How does Unity execute its methods? - c#

I only have a small experience in Unity3D, but I noticed that classes that derive from MonoBehaviour may contain functions with predefined signatures that will be called in a special way. For instance, if I write:
void Update()
{
//some code
}
this method will be called every frame.
I imagine that inside Unity there is some sort of an endless loop that calls the Update method every frame for each object on the scene. But how does it know that the object actually provides the Update method implementation? It would have been clear if Update was an override for a method in the MonoBehaviour class, but judging by the syntax (and the fact that you can implement such methods with any access modifier) it's not. Is there some reflection magic happening there?

http://blogs.unity3d.com/2015/12/23/1k-update-calls/
No, Unity doesn’t use System.Reflection to find a magic method every
time it needs to call one.
Instead, the first time a MonoBehaviour of a given type is accessed
the underlying script is inspected through scripting runtime (either
Mono or IL2CPP) whether it has any magic methods defined and this
information is cached. If a MonoBehaviour has a specific method it is
added to a proper list, for example if a script has Update method
defined it is added to a list of scripts which need to be updated
every frame.
During the game Unity just iterates through these lists and executes
methods from it — that simple. Also, this is why it doesn’t matter if
your Update method is public or private.

Related

Does UnityEvent creates a dependency on the scripts called

I know that we should avoid scripts to be dependent of each other. That's why I'm wondering if putting a script in a UnityEvent in the Inspector makes the script which owns this UnityEvent, dependent on the one called.
For instance, I have a script ScriptWithEvent.cs which has a UnityEvent. In the inspector I add an event to this UnityEvent which calls the method Open() inside an other script OtherScript.cs. Inside this script I have another method which changes a component active state linked to a GameObject containing ScriptWithEvent.cs or a public variable inside ScriptWithEvent.cs.
Does this make ScriptWithEvent.cs and OtherScript.cs dependent on each other ?
Does UnityEvent creates a dependency on the scripts we make it call ?
No it does not, UnityEvent takes a UnityAction which is a pointer to a method.
The script holding the UnityEvent does not know about the type of the method holder nor does it know about the content of the method. In the same way, a C# event would not know about the registered method, only that they need to match the delegate signature.
Your UnityEvent is a list of addresses where to find the methods to be run when invoke is called. But it is totally oblivious to what type it is stored in.
The only dependency for UnityEvent is that the method has to be stored in a MonoBehaviour and the method signature has some limitations.
UnityEvent has this advantage over normal C# event, in the latter the subscriber would need to find out how to register to the type or interface
UnityEvent via inspector removes that dependency as you can drag anything.

How does Unity wiki's Singleton work?

I have a "manager" GameObject in my scene with a Manager Script component attached to it.
I need this Manager script to be a singleton since it makes no sense for there to be several managers.
I used the singleton implementation from the Unity wiki.
I have two questions about it:
Why does it create a new GameObject and then use GameObject.AddComponent<T>() to instantiate the singleton? Why not just do new T()?
I have protected both of my Singleton and Manager class constructors. No one should be able to instantiate these classes except themselves. How does the Unity Editor do to instantiate them?
As the comments say:
MonoBehaviour classes cannot be instanciated with new T() because of the way GameObject components work: they must be attached to a GameObject! As such, the GameObject class provides a way of instantiating a new MonoBehaviour attached to that GameObject: AddComponent<T>() which presumably operates through reflection (other MonoBehaviour methods such as Start() and Update() aren't exactly invoked with reflection, not every frame during runtime, but it's easy to make the comparison that they are; it's about as opaque and magical and has significant overhead, so it may as well be reflection).
Preventing the constructor from being called at all would probably just break everything, so don't bother trying to protect it any more than you already are. Because of the way AddComponent works, calling the constructor through reflection, you can't actually prevent a new instance from being created, but you CAN detect that it happened and do something about. My preferred way is the script going "oh, an instance already exists and its not me" and destroys itself.
Additionally, as components can require other components (RigidBody requires a Collider, MonoBehaviours can specify their own requirements as well) which is specified through an attributes, when AddComponent<T>() is called to add the one component, it will search the class attributes to see if there are any [RequireComponents] specified and add them too, automatically. This would also be done through reflection.

How do the Unity private awake update and start methods work? [duplicate]

This question already has an answer here:
How does Unity execute its methods?
(1 answer)
Closed 2 years ago.
How does Unity call the Awake, Update, and Start methods behind the scene? That they have no access modifier to me indicates they are private methods, and they don't use anything like new or override, so how does the Unity framework find the methods to call them?
On a related question, is there any particular reason virtual methods were not used?
Edit: For those unfamiliar with Unity scripts, this is how they generally appear:
public class MyClass : MonoBehaviour{
void Start(){
}
void Awake(){
}
void Update(){
}
}
What I don't understand is how the framework finds and automatically calls those methods for each script when, by all appearances, they look to just be private methods
Here is a piece of information in a Unity blog post
HOW UPDATE IS CALLED
No, Unity doesn’t use System.Reflection to find a magic method every time it needs to call one.
Instead, the first time a MonoBehaviour of a given type is accessed the underlying script is inspected through scripting runtime (either Mono or IL2CPP) whether it has any magic methods defined and this information is cached. If a MonoBehaviour has a specific method it is added to a proper list, for example if a script has Update method defined it is added to a list of scripts which need to be updated every frame.
During the game Unity just iterates through these lists and executes methods from it — that simple. Also, this is why it doesn’t matter if your Update method is public or private.
The reason the methods are not virtual is for performance. If it were virtual then every single MonoBehaviour would need all of the relevant methods called (Start, Awake, Update, FixedUpdate, etc.) which is a Bad Thing.

Why are the MonoBehaviour methods not implemented for overriding?

In Unity3d you have the MonoBehaviour class, which is the normal base class for all scripts. When implementing a script, one has to implement the methods such as Awake() or Start() or Update().
However, These methods are not implemented as virtual or abstract in the MonoBehaviour class so that one could easily override them; in fact they are not implemented at all. The method one writes at the Moment is a new method that the class did not have beforehand.
Why are these methods not implemented as virtual or abstract in the base class (MonoBehaviour)?
If you check the documentation you will see that all those 'functions' are listed in the 'Messages' section; MonoBehaviour Doc.
So that means that 'functions' (like Start, OnEnable or Awake), they are not implemented as methods but as messages.
Now, MonoBehaviour inherits from Behaviour, which inherits from Component which has the SendMessage method. That method basically calls a message/method with the option to report an error if the message/method exists or not. The parameter of the name message/method is a string, /~~so they are using reflection there.~~/ Check Update!!
Seems like Unity behind the scenes determines if those messages were implemented to see if it has to call them or not. According to this UnityAnswer:
Unity is mainly written in c++ and therefore most magic happens in
native code. Unity uses reflection to determine, after your scripts
have been compiled, what of those "events" you've implemented and
remember that for this class. Unity only calls Update / LateUpdate /
OnGUI when it has been implemented.
So, the short answer is, they are not 'real' methods that you have to override, they are messages that are called only if they were implemented.
Update;
As #Raining noted, I was wrong in the way that Unity obtains the messages to call.
Unity doesn't use reflection to do this.
According this 1k-update-calls (also provided by #Rainin) scripts are inspected to check if they contain some of those 'magic methods'. If so, they are added to lists that will be executed accordingly.

C# Ways to access containing class without passing reference

Is there any way to access the containing/enclosing class during initialization (constructor logic) of the nested owned class without needing a reference passed as a constructor parameter?
The reason I don't want to pass a reference to the containing class as a constructor parameter to the nested owned class is because virtually every single object in my program would need it, and it just feels sloppy passing in an argument manually every time that would never change anyways. I want to simplify the programming as much as possible as other team members of mine will be using my engine.
I tried making a method for the container class to use when adding new objects that would take the new instance as a parameter and then set that instance's "container" variable to "this" (the container class), but the nested owned object's initialization code happens first which defeats the purpose (I want to be able to access the container during initialization, so the container variable needs to be set before, not after the constructor code is executed).
Any ways to make this happen? Or am I doomed to manually pass in a reference to the container class every time I make a new nested owned object?
EDIT:
Example:
Let's say I'm making a video game, and the player is going to cast a magic spell that spawns a HealerGoblin:
From Player class:
spawnMonster(new HealerGoblin(30)); //30 = Monster's Combat Level
In HealerGoblin class:
public HealerGoblin(int Level)
{
Owner.Health += Level; //Owner in this case, being the player.
}
As you could probably see, the player would cast the spawn monster spell, select a level 30 healer goblin, and the healer goblin has a special effect when he spawns that increases his owner's health by some amount (in this case equal to the goblin's level). (Keep in mind this is a hypothetical, I know there are other, probably better, ways to do something like this specifically, but this is just an example of what I'm trying to do).
So the problem is, any player or NPC in the game could cast that spell and be the "owner". How would the goblin's Owner property be set by the time that initialization code that references the owner is executed?
I know I could pass the owner by reference:
spawnMonster(new HealerGoblin(this, 30); //First argument being what Owner is set to.
But I want every single object in my program to automatically have a reference to their "owners", and manually putting (this) every time I initialize a new object, and having to set up a new owner parameter to be passed every time I make a new derived class, just seems sloppy and counter-intuitive considering you would never not pass the reference.
So my question is what other ways would there be to do get a reference to the container/owner object before initialization besides passing it by reference through the constructor? If any?
I understand your pain. I've been there too. But the answer is no in a standard way of programming. It maybe possible by using the call stack, reflection and some hack work, but since you are trying to simplify your code, you don't want to have that kind of stuff in your code.
As far as I know. In short there is no such feature.

Categories

Resources