Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# method override in Unity3d

Tags:

c#

unity3d

In the latest weeks I played with Unity3d using c# as scripting language. I never used before c# nor Unity3d, and I'm trying to understand how methods overriding works in Unity framework. What wonders me is that I can extend the base class MonoBehavior and override methods such Start (), Update () and so on without to have to use the override keyword and the compiler does not complain about it! Instead in a "normal" C# program I must use the override keyword or I get a compiler warning. For example:

public class BaseClass {
    public virtual void MyMethod () {
        Console.WriteLine("BaseClass.MyMethod()");
    }
}

public class SubClass : BaseClass {
    public override void MyMethod () {
        Console.WriteLine("SubClass.MyMethod()");
    }
}

class Program {
    static void Main ()  {
        SubClass obj = new SubClass ();
        obj.MyMethod ();
    }
}

instead in Unity I can simply do:

class PlayerController : MonoBehaviour {
    void Update () {
        // code...
    }
}

What happens behind the scenes? Does unity make use of "dynamic tricks" or what?

like image 659
daveoncode Avatar asked Jun 27 '16 07:06

daveoncode


3 Answers

Because MonoBehavior doesn't have a definition for Update. The runtime checks if a method called Update exists (using reflection), and then calls it if it does, but you are not overriding a base implementation

Update

Since you asked for an example on how this was possible, I've made a sample here: https://dotnetfiddle.net/UrpYkf

like image 159
Jcl Avatar answered Oct 22 '22 09:10

Jcl


Source by bunny83 at http://answers.unity3d.com/answers/177292/view.html

Unity works a bit different. All those so called "events" are NOT methods of the MonoBehaviour class. If you have a C# reflector you can just view the class implementation by opening the UnityEngine.dll

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.

Another point where you can notice that is when you create a MonoBehaviour class and don't implement any of those methods/events Unity will remove the enabled checkbox from your script instance because it doesn't contain any events that are affected by enabled.

Some events are dispatched with their SendMessage function (like OnCollisionEnter and such events).

The documentation calls all events "Overridable Functions" but that's not really true. If they were implemented as virtual function you would have to use the override keyword or it wouldn't work.

Here's the whole implementation of MonoBehaviour:

public class MonoBehaviour : Behaviour
 {
     public extern bool useGUILayout
     {
         get;
         set;
     }
     public extern MonoBehaviour();
     private extern void Internal_CancelInvokeAll();
     private extern bool Internal_IsInvokingAll();
     public extern void Invoke(string methodName, float time);
     public extern void InvokeRepeating(string methodName, float time, float repeatRate);
     public void CancelInvoke();
     public extern void CancelInvoke(string methodName);
     public extern bool IsInvoking(string methodName);
     public bool IsInvoking();
     public Coroutine StartCoroutine(IEnumerator routine);
     public extern Coroutine StartCoroutine_Auto(IEnumerator routine);
     public extern Coroutine StartCoroutine(string methodName, object value);
     public Coroutine StartCoroutine(string methodName);
     public extern void StopCoroutine(string methodName);
     public extern void StopAllCoroutines();
     public static void print(object message);
 }

I removed all the external attributes since nearly every method/property is mapped to a native function.

btw. the mentioned C# events are delegates which are just some kind of function pointers but a bit more complex ;)

like image 32
Orel Eraki Avatar answered Oct 22 '22 10:10

Orel Eraki


There are no Start, Update, Awake, etc declared in MonoBehaviour base class. That's why you don't write any Override keyword when you declare them. They will be called by Unity3D if they are implemented in your class, which can lead to performance improvements.

like image 1
Faroq Tavakoli Avatar answered Oct 22 '22 10:10

Faroq Tavakoli