Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
13
Question by Jason B · Jul 22, 2011 at 08:16 PM · c#classoverridesubclass

Why is Start() from my base class ignored in my sub-class?

I fully understand that I'm probably making an error, but I'm not sure how to rectify it.

I'm only not posting code because it's easily described; make two scripts, make one be a standard script and the second one a sub-class of the first script. If you then attach the sub-class to a game object, Start() from the base class doesn't fire. The Start() only fires if you attach only the base class to the object, verifying that the Start() function itself does work.

How can I fix this?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
17
Best Answer

Answer by ClandestineMan · Jul 22, 2011 at 08:33 PM

Start in your base class is not public so when you extend the class start is hidden. You will have to implement a new Start method and call base.Start(). That is what we do on our project.

I am also assuming that your coding in C#.

EXAMPLE:
public class TourGuide : _Model { new void Start() { base.Start(); transform.Rotate(Vector3.down,95.5f); } }
public class _Model : MonoBehaviour { void Start() { // original code. } }
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jason B · Jul 22, 2011 at 08:38 PM 0
Share

Thanks. Understood. I assumed that splitting my classes into separate script files within Unity would somehow eli$$anonymous$$ate the need to do this, but I guess not.

avatar image Jason B · Jul 22, 2011 at 08:47 PM 0
Share

Sorry, I un-checked your answer for the moment. I just wanted to make sure that I check the most useful answer for whoever stumbles into this thread next, and want to see if jharger's alternative is more useful for me. :)

avatar image Bunny83 · Jul 22, 2011 at 11:29 PM 13
Share

Why does everyone $$anonymous$$ch shadowing / hiding / reimplementing a method. That's not the usual way when you create a subclass. If you want a method to be able to get overridden in a subclass you should make it "virtual". In the subclass you have to use the override keyword and that's how the inheritance work the way that is intended. The method doesn't need to be public but it can't be private. That's why we have protected. Protected members are visible only for the class it self and derived classes but not from outside.

The method you're overriding gets replaced by the new one so if you want to have the overridden method called as well you have to use base.methodname() in your new method.

This has been discussed several times here and it's fundamental oop stuff.

avatar image lavmax · Jul 06, 2016 at 12:53 PM 1
Share

This answer doesn't work anymore, at least in Unity 5.3.5. You'll get a warning and an error if you do this. See the komodor answer below (make it public and virtual). PS. Hiding methods (using new) in C# is also a bad idea until you desperately need it in a particular situation.

avatar image Bunny83 lavmax · Jul 06, 2016 at 01:04 PM 2
Share

This does work, however not as it's stated here. In this example the methods are "private". So you can't use base.Start() since Start in the base class is private. It has to be at least "protected".

Start, Update, Awake, ... shouldn't be public as they shouldn't be called manually from outside. Best practise for those if you want to use inheritance is to make them protected virtual.

avatar image
20

Answer by komodor · May 15, 2014 at 03:10 PM

declare the Start method public virtual in base class and public override in all classes derived from it, methods without access specified are considered private

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image tbriz · Mar 18, 2019 at 01:06 AM 4
Share

For those looking for code:

In the base class:

 public virtual void Start()
 {
     // base class code runs
 }

In the class that inherits from it:

 public override void Start()
 {
     base.Start(); // runs the code from the base
     // add your additional code here
 }
avatar image Bonfire-Boy tbriz · Mar 18, 2019 at 11:25 AM 1
Share

As Bunny has pointed out in comments on other answers, these functions should be protected, not public.

avatar image
1

Answer by jharger · Jul 22, 2011 at 08:36 PM

I believe that, basically, Unity only calls the lowest implementation of any message function (which Start() is), so the sub-class will always have its version called and not the parent class. Compare this to inheritance in a lot of OOP languages in general, and this is also the case (the overriding version is the one called). Note, that this is not overriding the Start() method, rather it is shadowing the name.

I'm not sure how to do this in Javascript, but with C# you can declare the base class's Start() like this:

 protected new void Start() { /* ... */ }

... and then call it from the sub-class by using base.Start(). I personally don't like this solution, because it's not really clear what's going on there, so you can do something more like this:

 // Base class
 void Start() {
     DoInitialization();
 }

 void DoInitialization() {
     // Base class's code goes here
 }

 // Subclass
 void Start() {
     base.DoInitialization();
     // Other init code
 }

One question you should ask yourself, though, is sub-classing what you really want to do? If you're just looking to force some shared functionality, why not just use add the base class as a component to the game object you're working with? You can even force it with a RequireComponent(). That way you can still get the functionality of what was the base class without the funkyness of using inheritence in MonoBehaviours.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jason B · Jul 22, 2011 at 08:43 PM 0
Share

What I have right now is a simplistic game to test a concept, and right now all enemies have a base class called "Enemy". This includes various shared attributes such as health, points, death instantiation, things all enemies have in common. Then for each individual enemy, I have classes that run their specific AI. Sub-classing does seem to be the best option to do this (to me). Because in each sub-class, I do often need to refer to the base class for certain things.

Just to clarify, do you mean I can add the base class and sub-class scripts separately as components rather than just adding the sub-class, and retain the functionality of both with no ill side effects? For instance, both their Start(), Update(), etc. would be independent and would run naturally? Or would this cause me to not be able to easily reference the base class from the sub-class anymore?

avatar image jharger · Jul 22, 2011 at 09:33 PM 0
Share

Yeah, basically. What I do is have a sort of character logic class that takes care of the common functionality that's likely to be in both the player and AI objects. So I might have a "Warrior" class, for example. Then I create a separate "EnemyAI" class when would then use RequireComponent() and GetComponent() to get a handle to the class, which I can then query to get hit points, select a weapon, etc.

As far as ill side effects... there may be a tiny bit of overhead to adding yet another component, but not much... I mean most objects are going to have several components anyway... what's one more?

avatar image Bunny83 · Jul 22, 2011 at 11:45 PM 3
Share

The problem is when you hide a method ins$$anonymous$$d of overriding it you can get in trouble.

When you have a derived class instance but you save the reference in a variable of the base type it won't call the new/overridden method. If it's overridden properly that's no problem.

 public class Animal
 {
     public string GetName()
     {
         return "Animal";
     }
     public virtual int GetLegCount()
     {
         return 0;
     }
 }

 public class Cow : Animal
 {
     public new string GetName()
     {
         return "Cow";
     }
     public override int GetLegCount()
     {
         return 4;
     }
 }

 public class Chicken : Animal
 {
     public new string GetName()
     {
         return "Chicken";
     }
     public override int GetLegCount()
     {
         return 2;
     }
 }
 

Execute the following code with the classes above :

 List<Animal> myAnimals = new List<Animal>();
 myAnimals.Add(new Cow());
 myAnimals.Add(new Chicken());
 
 foreach(Animal animal in myAnimals)
 {
     Debug.Log("Name:" + animal.GetName() + " Legs:" + animal.GetLegCount());
 }

The result will be:
"Name:Animal Legs:4"
"Name:Animal Legs:2"

avatar image
1

Answer by softrare · Oct 26, 2013 at 09:36 PM

I don't know if something in Unity changed in this regard since this was asked / discussed but I just did exactly what the OP wanted and it worked.

If you declare a base class abstract (inherited from MonoBehaviour) and put a child class on a gameobject (in the scene) and implement Awake() or Start() in the base, the child class doesn't need to do anything (except for inheriting of course). When the scene starts these callbacks get called on the base class automatically. I am using Unity v3.5.7.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vadithiyan · Apr 29, 2015 at 07:34 AM 0
Share

yea, this same thing happened to me. I just did not declare anything in the child class, it automaically called the base class's monobehaviour methods. I had to do none of the workarounds mentioned here.

avatar image SimonRigby · Mar 06, 2020 at 11:09 PM 0
Share

If the child class doesn't implement Start it will call the one in the base class. If you do implement Start in the child, this is where the issue occurs as it only calls the sub-classed Start method.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

Using the object.Equals() method for a custom class 1 Answer

Conversion of a static class to struct? 1 Answer

Calling functions from other namespaces and scripts. 0 Answers

C# Unity 3d Don't Destroy Class On Load 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges