Unity3D - GameObject.Find() vs Inspector Assignment performance - c#

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.)

Related

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.

Reading from file more efficient than GameObject.Find?

Hey I'm new to Unity and I started creating a Tower defense game. Currently I can create one level and have monsters spawn and walk along a path I made with empty GameObjects ( Waypoints ). I can also drag and drop Heroes onto certain places called ( PlacePoints ); these are empty GameObjects, too. Here is a picture of my Level_1 prefab:
Level_1
This all works well so far but I read about GameObject.Find and Transform.Find being slow. And since I want to write fast and clean code right from the start, how would I make this faster and more efficient? Here is an example from my LevelManager script:
public Transform findPlacePoints()
{
return GameObject.Find("Level_1(Clone)").transform.Find("PlacePoints");
}
The question is, would it be faster to store all the information in a .txt file and load it in my LevelManager and then have each Script find the LevelManager which is a Singleton and ask for specific information? Basicly have the LevelManager act as a distributer? Informtion would be:
Spawn Times
Positions of ( SpawnPoints, Waypoints, PlacePoints, etc.)
Enemy Types
Don't fall into the trap of Premature Optimization. GameObject.Find is only slow if you make it slow (searching lots of objects in your scene). Check out the Improving Performance of Our Code section of Unity's Optimizing Scripts in Unity Games if you want to learn what writing good patterns looks like in Unity. It should provide you with some tips and not have to worry about deep-diving into GameObject.Find and disk operation optimizations.
As stated, It really depends on how many items you are searching and how you write the code. From my understanding direct references, such as setting a variable in the inspector, is the most efficient way to "find" something in scene.
Unless you are doing it a lot and in updates, it really shouldn't hurt performance that much. I would focus my optimization time on not destroying/instantiating, keeping UI updates out of the game loop, and keeping light scripts on frequently used objects.
Hope this helps!
What I would do (not saying it is the best) is have a static class just to store some informations (not a monobehaviour) let say Utilities. Have a public GameObject[] waypoints in it. On each of your level, add a script that will overwrite Utilities.waypoints with it's own GameObject[] variable. In the inspector, just drag/drop your waypoints on this script. You can then call Destroy(this) which will delete only the script after completion.

Unity Update() performance

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

DontDestroyOnLoad is not Working on Scene?

I Need to apply DontDestroyOnLoad on Scene.is it possible?
I Need to Do not disturb the scene when going in to another scenes also.here i'm sending mail,when ever clicking send button its going to authentication in mail server in this time my scene idle means not responding anything until come back to the response from mail server,so on that time i show one loading bar in my scene.this is not do process.the entire scene is hang until came response from mail server,so how to solve this?
void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
After reading so many non-answers I finally found the answer in a Unity forum. DontDestroyOnLoad ONLY works if the game object in question is at a "root level" meaning right under the scene, not nested under any other object. This is not mentioned anywhere in the documentation.
When loading a new level, scene, all Game Objects of the previous scene are destroyed by Unity.
If you want to protect a Game Object you can use the function.
DontDestroyOnLoad(gameObject);
It is important to note that when you say: this.gameObject you are pointing to pretty much the same thing, it just happens that this points directly to the script attached to that gameObject. So you don't need the this part, just gameObject will do.
Ideally you could protect that gameObject inside void Awake()
void Awake()
{
DontDestroyOnLoad(gameObject);
}
The above code will prevent Unity from destroying that gameObject unless your game closes completely or at a later point you call Destroy() on it. That means you can change from scene to scene and the gameObject will survive. However, if you make it back to the scene that creates that gameObject you are protecting you may run into problems if you do not have the logic implemented that prevents you from protecting a second, third, or many of that gameObject.
Your second question, if I understand it correctly:
You want to send mail when you change scenes, but your progress bar wont progress while changing scenes, it just stays there, static.
If that is the case then your problem is in Application.LoadLevel(sceneName); If you have the free version of Unity, then you need to come up with your own creative way of showing that progress bar, because Application.LoadLevel() will halt everything until it takes you to the new scene.
I don't completely understand what you are saying.
But because in your context, this in represents most probably a Monobehaviour, try the following:
void Awake() {
DontDestroyOnLoad(this.gameObject);
}
or
void Awake() {
DontDestroyOnLoad(gameObject);
}
See http://docs.unity3d.com/Documentation/ScriptReference/Object.DontDestroyOnLoad.html
I recommend you use a coroutine, with the 'yield' statement
check out this documentation of the WWW class, which likewise involves writing code to cope with waiting for a response from the web, without hanging your Unity3d program
coroutines are pretty powerful if you're working with tasks that take more than a frame or two. Richard Fine (AltDevBlog) has posted a really detailed description of what they are and how to use them, which I thoroughly recommend.

Categories