- Home /
Does Unity support Inheritance and Subclassing?
If I have a few different characters/objects in my game that all share some common behavior, can I use inheritance to centralize the common behavior into a base class? Or do you recommend another approach?
To give a simple example, I might want to have a character controlled by the player, and other characters with similar behavior that are controlled by an AI routine.
If inheritance is possible, do the base class and subclasses go in separate files? Do I only have to attach the relevant subclass file to a particular game object, or the base class file as well?
Finally, is inheritance possible in both C# and UnityScript?
Important note (Thats the only reason why author asked this question, and no one provided the right answer):
Unity supports inheritance, BUT, with 1 condition: Unity "Allocates" only that class, which have the same "Name" as "FileName". So if you want to allocate specific object from script in Inpector, you must name script with specific object's name.
INVALID example:
//
// $$anonymous$$yBehaviour.cs
//
public class $$anonymous$$yBehaviour : $$anonymous$$onoBehaviour
{
public virtual voud Start()
{
Debug.Log("$$anonymous$$yBehaviour");
}
}
public class $$anonymous$$yDerivedBehaviour : $$anonymous$$yBehaviour
{
public override voud Start()
{
base.Start();
Debug.Log("$$anonymous$$yDerivedBehaviour");
}
}
// You will see only: "$$anonymous$$yBehaviour",
// because unity Allocated only class,
// with the same name as "$$anonymous$$yBehaviour.cs".
VALID example:
//
// $$anonymous$$yDerivedBehaviour.cs
//
public class $$anonymous$$yBehaviour : $$anonymous$$onoBehaviour
{
public virtual voud Start()
{
Debug.Log("$$anonymous$$yBehaviour");
}
}
public class $$anonymous$$yDerivedBehaviour : $$anonymous$$yBehaviour
{
public override voud Start()
{
base.Start();
Debug.Log("$$anonymous$$yDerivedBehaviour");
}
}
// Now Unity Allocated $$anonymous$$yDerivedBehaviour,
// we will see "$$anonymous$$yBehaviour" and "$$anonymous$$yDerivedBehaviour".
INVALID And VALID look exactly the same except comment lines. This is most confusing.
Different filenames. He's pointing out that $$anonymous$$onoBehaviour classes have to have the same name as their filename. It's not quite the whole answer though - see the further discussion on the accepted answer.
so if I'm understanding right, in order to be able to assign a particular class to an object you need to make a separate script for each one, there is no way to have more than one class which derives from monobehaviour in the same script?
Right, because $$anonymous$$onoBehaviour is a CLASS level inheritance object and you can only extend one class. You can, however, create Interfaces and implement as many of those as you'd like:
class $$anonymous$$yThing : $$anonymous$$ySuperThing,I$$anonymous$$oney,IInventoryItem {...}
Answer by flaminghairball · Oct 23, 2009 at 08:28 PM
Subclassing (inheritance) is available in the Unity flavor of JavaScript as well as in C#. See MSDN for how to use inheritance in C#. To have an inheritance chain in JavaScript:
Put in this code:
class MyCoolObject extends MonoBehaviour {
var myCoolInt : int;
var myCoolFloat : float
}
Now you have a new class that implements all the methods of MonoBehaviour(such as Update() and FixedUpdate()). If you want to create a subclass of MyCoolObject, just:
class MyCoolerObject extends MyCoolObject {
var myCoolerInt : int;
var myCoolerFloat : float;
}
Now if you reference MyCoolerObject in a script, both the cooler variables and the cool variables will show up in the inspector.
Fla$$anonymous$$gHairball answers the question quite well - since $$anonymous$$yCoolerObject descends from $$anonymous$$yCoolObject, it already contains all its members - you only need to attach the descendant and you will get the parent's properties and methods.
C# does support inheritance in the same way as well, yes.
about part .4 oh the above answer-
How do you reference $$anonymous$$yCoolerObject class in a script?
Seeing how these are derived from $$anonymous$$onobehavior, you'd use them just like every other component - add them to an object in your scene. You can then reference them from other components, on events (like a collision) or if another object uses a method to interface with this object.
The generic GetComponent.() function would be a good start if you want to get into using custom modules.
Answer by Peter Alexander · Dec 28, 2009 at 05:50 AM
Unity does support subclassing, but it does NOT support dynamic dispatch for "Unity" method calls.
For example:
public class MyBehaviour : MonoBehaviour { private void Start() { Debug.Log("MyBehaviour created"); } }
public class DerivedBehaviour : MyBehaviour {
}
If you attach a DerivedBehaviour
script to a GameObject, it will NOT call MyBehaviour.Start() on startup. If you want to do that then you have to do it manually:
public class MyBehaviour : MonoBehaviour { private virtual void Start() { Debug.Log("MyBehaviour created"); } }
public class DerivedBehaviour : MyBehaviour { private virtual void Start() { base.Start(); } }
Note that making the methods virtual in the first example would not fix the problem.
This applies to all "Unity" calls (e.g. Awake, Start, Update, LateUpdate, OnLevelLoaded etc.). "Normal" method calls work correctly like you would expect in any .NET app.
The reason why you're seeing this is that Awake, Start etc. are not actually methods on the $$anonymous$$onoBehaviour class, but rather messages sent to derivatives of it. You'll therefore see the same behaviour from Send$$anonymous$$essage use.
That's not true. You have it just a little bit wrong. You should get a CS0621 because virtual methods can't be private! It wouldn't make much sense either. Furthermore you have to override the method in the derived class, otherwise you reimplement it and you would hide the base method. I did what you did but use protected for both methods and override in the derived class and it works as expected.
I don't have the reputation to vote, but this answer is very confusing. (+1 for comments, if I could)
@Bunny83, your complaint is a bit confusing because it addresses only syntactic problems in the answer and not the core of the answer. C# will toss a compiler error for both of these points, so I think they're pretty self explanatory. -- Also, as a potentially interesting aside, there is a conceptually valid interpretation for a virtual private method (which you correctly state that C# doesn't allow). Consider a situation where your parent class has a private abstract virtual method (still not legal in C#, but legal in C++). This specification dictates to an inheriting class that a function must be implemented for use by the parent; that the parent does not itself supply a default implementation for this function; and that this function need not be exposed for use by inheritors of the inheriting class. Forbidding the virtual private member requires the inheriting class to expose its implementation of the function to further inheritors, which isn't strictly necessary in this case, because the only reference to the v.p. member that should functionally exist already knows that a function of that name is accessible (via its own abstraction version of the member). -- Admittedly obscure, but I thought it interesting when I found out about it.
Answer by Ricardo · Oct 24, 2009 at 04:10 AM
Every script that you add to an object is itself a subclass of MonoBehavior, and from then on it's .Net all the way down (or up, actually). Here are two examples:
As a really straightforward example, you could take a look at the code for Rock'n'Roll dice. As you can see, there's a DieController MonoBehavior, which contains most of the general code, and then there are some subclasses for the various types of die, which override a few relevant properties.
You could also take a look at the behaviors included in UnitySteer, some of which inherit from a very basic VehicleBehavior and also implement particular interfaces.
In short, any language feature that would apply to a regular .Net class applies to your Unity scripts as well, since they are simply .Net classes.
Just to be a pedant, they're not simply .Net classes (I challenge you to get this == null
to evaluate to True in stock .Net without some seriously sloppy coding)
I assume you're referring to Unity's custom == operator? Still .NET :)
Answer by Ralkarin · Jan 26, 2011 at 05:47 PM
I just wanted to add that when using Inheritance for MonoBehaviour objects, the GetComponent() function on the GameObject class will return derived objects as well. This wasn't immediately obvious to me, but is very useful for deriving MonoBehaviours to share functionality and write abstract code in Unity.
Using your scenario, here's a very simple example:
public class CharacterBehaviour : MonoBehaviour { void Start() { CharacterBehaviour behaviour = gameObject.GetComponent<CharacterBehaviour>();
print("Behaviour Type: " + behaviour.GetType().Name);
}
}
public class PlayerCharacterBehaviour : CharacterBehaviour {
}
public class AICharacterBehaviour : CharacterBehaviour {
}
With a GameObject that has a PlayerCharacterBehaviour attached, you will see:
Behaviour Type: PlayerCharacterBehaviour
With a GameObject that has an AICharacterBehaviour attached, you will see:
Behaviour Type: AICharacterBehaviour
This lets you write generic code against all objects with a CharacterBehaviour attached.
Answer by bill · Feb 06, 2010 at 07:50 AM
Inheriting from GameObject seems to crash unity. It would be nice to do to make it easier to interface with other code.
In Unity 3.0 GameObject is a sealed class, so you can no longer even attempt to derive from it. The same is true of other internal classes such as $$anonymous$$esh.