If I have over 100000 “if” functions on void update, and for sake of argument, they never satisfy the argument and thus always return false, meaning it will be skipped, does that still cost a slot in terms of processing?
Thanks In advance
If I have over 100000 “if” functions on void update, and for sake of argument, they never satisfy the argument and thus always return false, meaning it will be skipped, does that still cost a slot in terms of processing?
Thanks In advance
How could the processor know that they should be skipped without evaluating them?
What are you thinking about doing that makes you think need 100000 ifs that might not ever return true? ![]()
When you have a situation where you need to evaluate 100000 ifs every update tick, you probably have something wrong in your design/implementation. Split stuff to chunks, test only things which might need testing.
If you’ve got 100000 if-statements you’ve got some way more important problems than performance. It probably won’t take too long to check 100000 boolean, but damn.
are comparing floats with == ?
if yes ![]()
@Boz0r , @Olmi , @Madgvox , its a strategy game, which allows you to build 1000 units per player (maybe more), and each Unit has many scripts, many of them need to be on Void update, such as detecting distance between enemy units etc etc, the point is, I will end up with a lot of “if” function. I was told before to not worry about performance until the end of my game. but earlier I ran into a problem, all those units had by “accident” a Debug.log on Void Update, and it reduced my fps from 70 to 30. and I was afraid “if” statements may cost me the same if I leave them on void update. The thing is, most of these “if” statements will not be satisfied 99% of the time, and I was thinking if that would cost less in processing compared to Debug.Log, and that I might be able to get away with it.
Debug.Log is a very expensive operation, so I wouldn’t jump to any conclusions based on that. You should use the Profiler to get a better understanding what is consuming most of your frame times, and where you should focus your optimization efforts.
That being said, simply having Update methods, even if they are completely empty, does come with some overhead. With so many Units, that could start adding up.
You might want to create a custom class that handles calling custom OnUpdate methods on your units with direct calls, to make it faster. Also, if it’s possible, have your units unsubscribe from this OnUpdate callback when they don’t need it, so that your update handler doesn’t even need to call the OnUpdate method at all for them.
Or go the whole nine yards and switch to DOTS ![]()
As per previous post, here is a relevant blog article. Slightly old now but i think it still applies.
The transition between managed / unmanaged code as used by the monobehaviour OnUpdate is supposedly expensive. You can pool a bespoke update call to avoid this. Of course, you should use the profiler to find out if this is really an issue in your case. Good luck!
@SisusCo , Thx for info bro, would it be possible if you can give me an example on this:
Something like this:
using System.Collections.Generic;
using UnityEngine;
// add one of these to your scene
public class Updater : MonoBehaviour
{
private static Updater instance;
private List<IUpdateable> subscribers = new List<IUpdateable>(1000);
private static Updater Instance
{
get
{
if(instance == null)
{
// find an cache an instance of Updater from the scene
instance = FindObjectOfType<Updater>();
}
return instance;
}
}
// Add a new subscriber to receive OnUpdate callbacks
public static void Subscribe(IUpdateable updateable)
{
Instance.subscribers.Add(updateable);
}
// Remove a subscriber from receiving OnUpdate callbacks
public static void Unsubscribe(IUpdateable updateable)
{
Instance.subscribers.Remove(updateable);
}
private void Update()
{
// Call OnUpdate for all subscribers
for(int n = subscribers.Count - 1; n >= 0; n--)
{
subscribers[n].OnUpdate();
}
}
}
// Interface that should be implemented by classes that want to receive OnUpdate callbacks from Updater
public interface IUpdateable
{
void OnUpdate();
}
// Example class that receives the OnUpdate callbacks
public class Unit : MonoBehaviour, IUpdateable
{
private bool updating;
private Vector3? moveDestination;
public void OnUpdate()
{
// implement your Update logic here
}
// Usage example
public void Move(Vector3 position)
{
// set move destination so that ShouldUpdate will return true
moveDestination = position;
// Subscribe for OnUpdate events, so that can handle actual moving in OnUpdate
UpdateSubscriptionToUpdater();
}
// Another usage example
public void Stop()
{
// remove move destination so that ShouldUpdate will return false
moveDestination = null;
// Update subscription, so that OnUpdate does not get called unnecessarily
UpdateSubscriptionToUpdater();
}
private void OnEnable()
{
// check if should subscribe for OnUpdate when unit is spawned
UpdateSubscriptionToUpdater();
}
// Subscribe or unsubscribe to receive OnUpdate callbacks based on whether they are needed.
// This should be called whenver the Unit's need for receiving OnUpdate callback might have changed.
private void UpdateSubscriptionToUpdater()
{
if(ShouldUpdate())
{
if(!updating)
{
Updater.Subscribe(this);
updating = true;
}
}
else if(updating)
{
Updater.Unsubscribe(this);
updating = false;
}
}
private void OnDisable()
{
if(updating)
{
Updater.Unsubscribe(this);
updating = false;
}
}
private bool ShouldUpdate()
{
// replace this with your logic for determining whether the unit needs OnUpdate callbacks at this time
return moveDestination.HasValue;
}
}