Unity Update() performance - c#

I have two functionality that need to achieve:
movement
rotation
both must be in Update(), i can combine it but i prefer both of them in separate script in each Movement.cs and Rotation.cs.
So i have two method:
Combine both into one script in and using one Update().
Separate into two script and each of them have Update().
My question : does it cost performance if separate them into each individual Update() instead of combine in one script with one Update().
Both script will be attach on one object, so if i have hundreds of object.
Method 1 - 100 objects and 100 script with Update().
Method 2 - 100 objects and 200 script with Update().
Another question : is it really bad to do Method 2 ?.

This is a case of micro-optimisation. You should use any of the methods that makes more sense in your particular case and after you're done you should to some profiling.
Based on the results of profiling you'll end up knowing where and what to optimise.
Getting back to the problem at hand having 2 Updates will cost you one more function call per frame and some time when your MonoBehaviour is first loaded, but that is negligible, you'll eat a lot more CPU cycles in other parts of your code.

If you can combine, do it. The Unity MonoBehaviours are usefull but eat quickly your resources, especially if you have many scripts running at the same time.
Check this blog ticket : https://blogs.unity3d.com/2015/12/23/1k-update-calls/
WHAT SHOULD YOU DO?
Of course it all depends on your project, but in the field it’s not rare to see a game using a large number of GameObjects in the scene each executing some logic every frame. Usually it’s a little bit of code which doesn’t seem to affect anything, but when the number grows very large the overhead of calling thousands of Update methods starts to be noticeable.

Perhaps a third option would be better for you, it elaborates on the first option but still splits your logic into two separate areas, thus achieving the loose coupling you were going for originally.
public static class Manipulators
{
public static void Rotate(MonoBehaviour behaviour, float amount)
{
Transform t = behaviour.GetComponent<Transform>();
// Do stuff with t
}
public static void Move(MonoBehaviour behaviour, float amount)
{
Transform t = behaviour.GetComponent<Transform>();
// Do stuff with t
}
}
Then in your monobehaviour...
public void Update()
{
Manipulators.Rotate(this, 15f);
Manipulators.Move(this, 15f);
}

Here are some tests I did on how Update() compares to some common Unity3d functions.
In the scene there are 10000 empty GameObjects with UpdateTest script on them.
The Average FPS value is smoothed heavily and I use the Mono backend.
So it seems the cost of Update() function is somewhat less than moving an empty GameObject with transform.localposition.
I've used Unity3d 2020.1.5

Related

Efficient For Loops Unity C#

I'm running a robot simulation in unity where each of the 300 robots runs the same script and I'm using RayCast for communication between robots. Each robot cast 36 Rays in 10 degree increments to cover all 360 degree every 0.02s. This is done using the RaycastCommand so its done in parallel and isn't causing any performance issues. The issue comes when trying to process the RayCast Data.
I need to loop over every result and compare the tags and ID in each robot script as such:
for(int k =0; k< results.Length; k++) // For every result
{
if(results[k].collider !=null) // Check if RayCast collision happened
{
if(results[k].collider.tag == "Robot") // Check that collision is with robot
{
var ID = results[k].collider.GetComponent<RobotControl>().ID; // Get The robot ID
if(!listID.Contains(ID)) // Check that it hasnt comunicated with that robot yet
{
listID.Add(ID);
Debug.DrawRay(origin + (0.55f* Directions[k]), Directions[k] * results[k].distance , new Color(Directions[k].x, Directions[k].y, Directions[k].z, 1));
// Grab important info here
}
}
}
}
The main problem being I cant use IJobParallelFor since I'm accessing the collider and trying to read the tag, and this is the part of the code tanking my performance since everything else is done using Parallel Jobs. The real issue is accessing the components is expensive.
Any Ideas on how to make it more efficient or somehow parallelize it?
Is there a way to access GameObject specific data, like ID, without accessing their components?
In general instead of 36 casts per robot can't you just use a Physics.OverlapSphere would probably already reduce it a lot since an overlap sphere is pretty easy to compute for the physics engine (if(distance < sphereRadius))
Then one thing costing a lot performance in your case is probably that Contains on a List. There you should rather use a HashSet. See Performance List vs HashSet for your 300 objects that would probably be worth it.
Or further to me it sounds like you would want to know which other robots are close to that one ... you could give each robot a SphereCollider on a certain layer so they only collide with each other, make it Triggers and store them in OnTriggerEnter andremove them in OnTriggerExit.
Is there a way to access GameObject specific data, like ID, without accessing their components?
Well, yes, you can access GameObject specific data like e.g. .name. But that ID is clearly not something GameObject specific but in your RobotControl class so, no, there is not really a way around GetComponent.
However, in newer Unity versions the GetComponent isn't that expensive anymore since the references are hashed and serialized on edit time.
Question is do you really need that ID list or would it be enough to simply save the collider/GameObject references and access the specific component only when really needed?
In your specific case here also the Debug.DrawRay is something extremely expensive and you should not do it too often and for possible 300 * 299 times ;)

Why not finish all the functions within Update() function in unity

void Update() can perform the functions per 1 frame . So in script , e.x like
void OnTriggerEnter(){} . why don't put it in update() function .I know there's some misunderstanding here but I just can't explain it to myself .Besides , is that only void Update() , void Start(){} that functio in unity .Including some functions like void OnTriggerEnter can function as well in unity since it is built-in functions .How about those functions that written by us like public void SwitchAvatar() .Can it function if it is not referred inside void Update(){} .I know the questions above may sound stupid , but dunno why I can't tell the answers .All of your help is greatly appreciated . Thanks !
Alright, let's open pandoras box about magic methods in Unity.
First, there are two types of classes that you can inherit from, to access magic methods: MonoBehaviour and ScriptableObject. Both of them offer different things and the latter is mainly used to serialize data outside of scenes. Also, ScriptableObject has way less magic methods, compared to MonoBehaviour.
Second: A MonoBehaviour has a lifecycle. Where you are in this lifecycle determines what methods are called by the engine.
The following graphic shows you the whole lifecycle of a MonoBehaviour:
(Source: Unity - Manual: Order of Executions for Event Functions)
As you can see, the object gets instantiated and Awake is called. Before the first time Update is called, the engine calls the Start method. There is a difference between Awake and Start: Awake is comparable to a constructor. It is called without anything external being guaranteed to exist (like other components on your GameObject). When Start is called, all the other components on the object are initialized and can be accessed by a GetComponent call.
Now to Update, FixedUpdate and all the other events:
Unity has two separate cycles it iterates over. One for physics and one for everything else. Because calculating physics is expensive and needs precision, it is called in fixed, distinct time steps. You can actually set them in the project settings in the "Time" tab.
Now if you want to modify anything related to physics (like the velocity of a rigidbody), you should do that in FixedUpdate, because it runs in the same time step as the physics engine (PhysX or Box2D, depending on your usage of colliders).
Update on the other hand runs as often as possible. The current time distance between two Update calls can be observed by calling Time.deltaTime, which is the time that is passed between two Update calls. Note that Time.fixedDeltaTime is always the same, as it is the time between two physics calls.
The other event methods are called as responses to either the editor internal update loop, the rendering loop or the physics loop. Whenever an object collides in the physics calculation, OnCollisionEnter is called. Note that this can't happen out of Update, because, as we know, Update is not used to calculate physics.
Okay, a tl;dr:
Start and Update are not the only methods that exist in the MonoBehaviour lifecycle, there are plenty and each has its purpose. Physics are calculated in a different timescale as the Update method is called and thus cannot be part of Update.
And one thing to take away: You should really read the manual of the game engine you are using. There is plenty of stuff that you should know when you are writing code for a real time application and if you build onto an existing game engine, you should check the docs of that regularly. Especially the documentation of Unity is a very good read for both code and editor usage.

Creating scripts for each objects behaviours instead of writing everything in the object script body

I have two game objects in my example scene. Both needs to rotate constantly with a specific speed on their local space. They are just simple coins which purpose is to be collected by the player. Instead of writing the rotation script inside each Update() method, I created a script called Rotator that makes the object which it's attached to actually rotate.
I have attached the component Rotator to each object and it works just fine.
Now I have two game objects which have a component called Rotator that will make them rotate.
This is the Rotator class:
using UnityEngine;
public class Rotator : MonoBehaviour
{
[SerializeField][Range(5, 10)]
private int _rotationSpeed = 5;
[SerializeField]
private float _xAxes = 0;
[SerializeField]
private float _yAxes = 0;
[SerializeField]
private float _zAxes = 0;
void Update()
{
transform.Rotate(new Vector3(_xAxes, _yAxes, _zAxes) * _rotationSpeed * Time.deltaTime);
}
}
I think that in this way the creation flow for my game objects is much easier and modular than writing the same code above inside each element that should rotate.
My question is: will this have an impact on performance? Is it a bad idea to split behaviors into small pieces or components and then adding them to each game object that require them? Or is better, in the case of just a simple rotation, to write that line of code directly inside one game object script?
For example, I have now another game object called Player that needs to rotate on himself as well. This game object as attached already another script called PlayerController that handle the player movements by keyboard inputs. I can write this part...
transform.Rotate(new Vector3(_xAxes, _yAxes, _zAxes) * _rotationSpeed * Time.deltaTime);
...inside the PlayerController's update() method, or, like I think is better, attach the Rotator script to it.
In the last case, I will have a game object with two components:
PlayerController
Rotator
Of course, this is just an example, I don't want my player to keep spinning on himself for real, is just to explain my point of view.
So, in the end, I need to understand if this is a good practice, even if is a small line of code like the rotation is worth to create a component? And I'm referring to behaviors that are needed by more than one object, of course, I know that if it's a one-only case, it makes more sense to write it directly in the script which is already attached to the game object in question.
Long post, hope I was clear enough. Thank you all!
The way you do it is the way it should be done. The idea of unity is to use small modular components which can be reused. However having a lot of update functions can have a performance impact, especially if you use Mono and not IL2CPP.
But there are multiple solutions to this.
Use IL2CPP to remove the "virtual" call layer between C# (your code) and c++ side (engine code).
Write a behaviour manager which updates all of your scripts from the c# side.
Look at the Entity Component System and iterate over everything which needs to be rotated in one "Update function".
We actually released a game where rotating crystals had a CPU performance impact. In the end we calculated the LocalRotation value only once per frame and distributed it to all crystals.
It really depends on the size of the games and number of scripts attached. If it is a big game with dozens of long scripts you have to balance between the organization of your game and performance, since both are important. For example, it is better to call a method 1000 times inside one Update method than 1000 separate scripts with one Update method
In your case since it is simple and the rotation is the same for both objects it is better to create a common separate script as you have. If you need any change in their rotation you can change it just once plus there's no significant cost on performance.

Why is my transform.position setter called via OnMouseDown() so slow?

I have the following method in my code:
private void OnMouseDown()
{
cube.transform.position = new Vector3(0, 1, 0);
}
When clicked on the gameObject, this method is called. It takes long to change the position of the cube (not more than a second, but still long, at least half a second). It does affect the user playing experience.
If I don't change the position of the cube, but for example its material, it is still slow. So I do know that this doesn't have to do with the line in my OnMouseDown() event.
Note however that I do have around 35 imported 3D meshes in my Scene, as well as over 50 primitive game objects. Does this have anything to do with the method being slow? Because when I make an empty Unity project with just 2 gameObjects, the method is fast.
Is it because of my full scene? Any ideas? Thanks!
If someone knows how to speed it up as well, I'd love to know!
EDIT: If I remove all my 3D meshes, the method is fast...
Unless your transfom tree is hundereds of children deep, this should be pretty much instant, its one of the things Unity has been designed to do quickly, so I think this has to do with the meshes you import. The should not have too many verticies, too many materials, and too many objects.
You can try to go through you objects with a 3D editor package (blender?) and combine the chunks into single objects.
If unity lags when you move an object, it may mean it has too many individual transforms to process. If your scene is intense you can gain a lot of performance by 'baknig' it, combining individual objects into larger meshes (those live on the gpu and cost gpu time not cpu time).
It is also possible that one or more of the meshes you imported has too many verts/triangles. If you currently have 10fps you may want to target having lighter meshes, and as few seperate GameObjects as possible (ideally you want the environment to be just a few combined meshes (to enable culling), not thousands of objects)
solution
Try to check if there are heavy materials are used that can slow the procedure. The game becomes slow when the objects are being added in the project and it destroy the overall efficiency of the game . It happens with me when i used too heavy models in the project the overall speed of the game is decreased . I replaced them with lightweight models of truck and issue was resolved .

Unity3D - GameObject.Find() vs Inspector Assignment performance

I'm making a mobile clone of pacman for android. Everything is working fine, but I am trying to optimize my game as much as possible.
Currently in some scripts I am finding GameObject's by doing GameObject.Find() in the Start() function of my scripts, like this:
void Start()
{
ghosts = GameObject.FindGameObjectsWithTag("Ghost");
pacman = GameObject.Find("Pacman");
gameManager = GameObject.Find("Game Manager").GetComponent<GameManager>();
}
My question is, would performance increase if I made some of these GameObject's inspector assigned variables instead of doing .Find()?
Would that increase the performance speed or would it make no difference seen as though I do a .Find() in the Start() function?
Obviously performance would decrease if it was called in the Update() as the script would try and find a GameObject every frame, but a Start() function would only search for it once?
Performance at startup for this kind of things is totally negligible, Inspector assignment requires deserialization, while Find requires message dispatch, both are slow operations, if you think that matters, profile that.
I would anyway use
FindObjectOfType<GameManager>() as GameManager
wich is at least more typesafe, I would not use editor inspection if possible, because manual wiring is source of many little errors. So I give a human-time performance reason:
Do not use editor inspection because if you miss to wire something you will have to debug a nullpointer wich on the long run will eat hours of your time.
You have anyway to use Editor Insection in cases where you do not have just to find 1 component, no workaround for that (unless you use Svelto or Svelto-ECS wich are rather advanced topics.)

Categories