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

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.

Related

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

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

Infinite Road Update

I am working on Unity for a month. I am new on Unity and C#, before Unity I worked other game engines. Whatever I am working on infinite run game, I wrote random road generator. Road generator is working well but I have problem about updating road. I can update road manualy like this. How can I update it automaticly?
void Update()
{
if(Input.GetKeyDown(KeyCode.A)) UpdateRoad();
}
My UpdateRoad method adding road like this(I am using object pooling).
I want to update after Link Road, OnExitTrigger or something I dont know. How can I do it?
You would need to implement Object Pooling.
I would suggest making your Design of Objects first so you can test. Or if not use, the stock Blocks Primitive of Unity3D as your Prefabs. I hope you already know prefabs. It is a major key for making infinite runner. Actually a main core for making any kinds of game.
Prefabs is an Object File where you can Instantiate it in a location. So lets say you will generate a Flat walkable, then Generate a Pit. You would probably want to stack them together.
Now Generating them is easy. You would not like to go in an Update? Approach because most likely you're not going to update, but you're going to further stack what is going on ahead, based on your game logic.
To further Understand this, Unity3D already made a project or Fully Detailed tutorial. It maybe made in 2D but it is going to be the same, if you're going to change the Collider2D to Collider <- this is important in your case.
https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/infinite-runner
Update
You would need to create an Object, that is invisible. Meaning a Trigger.
Then on Trigger call your method UpdateRoad();
https://unity3d.com/learn/tutorials/modules/beginner/physics/colliders-as-triggers
Detailed Videos about Trigger.
If I understood your needs correctly, you could create Empty Object name it SpawnPoint, set position for Spawn Point as you need (out of the camera view) and then Instanciate random prefabs of road. Concerning On TriggerExit - it could be used to destroy "old piece of road". But to have it working properly, dont forget to set collider and rigitbody to your objects. Dont add collider2D or Rigitbody2d, add and use Box Collider and Rigitbody components

Categories