Search Unity

Question How do i correctly use overrides when deriving from MonoBehaviour

Discussion in 'Scripting' started by Temeos, Mar 2, 2023.

  1. Temeos

    Temeos

    Joined:
    Mar 29, 2019
    Posts:
    22
    Hello everyone,

    after quite a bit of reading, i unfortunately haven't found a good answer to my question. Its very simple.
    I have a script that looks like this.

    Code (CSharp):
    1. public class Sensors:Monobehavior{
    2.  
    3. private void Start() {
    4. testOverride()
    5. }
    6. protected virtual void testOverride(){
    7. Debug.Log("i am sensor");
    8. }
    9.  
    10. }
    Now i have another script:
    Code (CSharp):
    1. public class LDS:Senors{
    2.  
    3. protected override void testOverride()
    4. {
    5. Debug.Log("i am LDS");
    6. }
    7. }
    In theory the LDS class should override the testOverride() function, but it does not.
    Additionally for some reason i get two Logs in Unity with "i am sensor", but i digress.

    So, my question: Can i use overrides for my custom methods when deriving from monobeahviour or not?
    If not, what is the convention? Event Actions? Or do i just grab references to the other scripts i need?

    I would very much appreciate some help!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    Far better is to be explicit and make your MonoBehaviours implement interfaces, such as an
    ISensor
    interface in your designs above.

    Of course you can do any kind of C# trickery you want.

    The convention however is that overriding via MonoBehaviours, ESPECIALLY overriding the actual MonoBehaviour callbacks, is a rarely-done thing.

    Yes it is done. Yes it is perfectly legal.

    But if you start doing it in your codebase, you may reasonably expect future issues when other users of your codebase forget to call your
    base.Awake()
    for example.

    Use it all at your own peril. If you can be disciplined, more power to you, but I've seen SO many incredibly frustrating difficult-to-track-down bugs come from this, there's no chance I would ever reach for that solution. It just doesn't confer any benefit worth the risks, especially in a large team environment.

    Using Interfaces in Unity3D:

    https://forum.unity.com/threads/how...rereceiver-error-message.920801/#post-6028457

    https://forum.unity.com/threads/manager-classes.965609/#post-6286820

    Check Youtube for other tutorials about interfaces and working in Unity3D. It's a pretty powerful combination.
     
  3. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Yes.
    Exactly what you posted.

    Are you sure that on your GameObject you placed the LDS-component?
    Are there any other Sensors-components on gameobjects your scene?
     
  4. Temeos

    Temeos

    Joined:
    Mar 29, 2019
    Posts:
    22
    Thank you very much for the quick answer!

    I think i will heed you warning and implement interfaces.
    But just for curiosity sake, do you have a suggestion why the override does not work properly?
     
  5. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,647
    Well, don't mean to make it awkward, but it worked fine for me. You sure you saved your files?
     
    SF_FrankvHoof and Kurt-Dekker like this.
  6. Temeos

    Temeos

    Joined:
    Mar 29, 2019
    Posts:
    22
    I am sure i have saved my files. Funny enough, i tried making a empty scene and added new scripts that do the same as the one i posted originally, just with other names and that works...
    When i switch to my other scene though with the original scripts, the overrides are still not registered.

    My Sensors class uses fixedUpdate, does that maybe inpact something? Or maybe the fact that the parent class as well as the child class use the Start method?
     
  7. Temeos

    Temeos

    Joined:
    Mar 29, 2019
    Posts:
    22
    There is only one game object that has the Sensor class attached to it.
    The LDS class is attached to multiple GameObjects.
     
  8. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,990
    But.... When you attach a Sensor class to a gameobject, you will get the message from the sensor class. That's pretty much expected. When you create a derived class, it does not change or affect the base class in any way. It only overrides the method in the derived instances. I'm really confused what your actual problem is. You may want to add a context object to your Debug.Log statements. That makes it much easier to track down from which object this message came from:

    Code (CSharp):
    1. Debug.Log("i am sensor", gameObject);
    You can do the same in your overridded method. Now when you click on the log message in the console, Unity will highlight that context object. So you can see which exact object has produced this message.
     
    Kurt-Dekker likes this.
  9. Temeos

    Temeos

    Joined:
    Mar 29, 2019
    Posts:
    22
    The problem is not, that the sensor class responds. That is, as you said, expected.
    The problem is, that the overrided method does not get called in LDS even though it should.
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    Try rebuild the prefab (or test scene setup).

    If you originally defined the base class and dragged it in, then later changed the type to the derived class, but did not drag the new one (with the derived type) in, the thing dragged in is still a base but it is being deserialized as a derived, so most likely you think you have a derived reference but it's really created in memory as a base and that's what you have the reference to.

    Just a thought.

    Just know that this is just one of the murkinesses you may have to deal with if you insist on deriving stuff. Unity absolutely does NOT serialize data by type... it's this weird GUID-based serialization that is essentially typeless, or "duck typing," as it will happy attempt to populate fields it finds.
     
  11. dogmachris

    dogmachris

    Joined:
    Sep 15, 2014
    Posts:
    1,375
    Yes, you can use overrides for custom methods when deriving from MonoBehaviour. In your example code, the issue might be with the misspelling of Monobehavior instead of MonoBehaviour.

    Try changing the spelling to MonoBehaviour and see if the testOverride() method is overridden by the LDS class. Additionally, make sure that both Sensors and LDS are attached to GameObjects in the scene.

    Regarding the two logs of "i am sensor", it could be because the Start() method of the Sensors class is being called twice if both scripts are attached to different GameObjects. You can check this by adding a Debug.Log() statement at the beginning of the Start() method to see how many times it is being called.