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