- Home /
Polymorphism issue
Here is a quick code for my issue (not correct syntactically, just for an idea)
class Bird : GameObject { virtual string name() { return "ABird"; } }
class Crow : Bird { override string name() { return "ACrow"; } }
now, if i hold a public 'Bird' variable and 'new' it with 'Crow', when i run the game, the variable just acts like a 'Bird' and not 'Crow'. I can not get 'ACrow' if i call 'name()' through that object but just 'ABird'.
i do this all in a class derived from 'MonoBehaviour'.
Am i ignoring any factors that affect polymorphism in unity?
it seems am making it more confusing.. so i created a smallest possible example to explain my issue
//file name: DrawingObjects.cs
using UnityEngine; using System;
public class DrawingObject : GameObject
{
public virtual void Print()
{
Debug.Log("DrawingObject");
}
}
public class Line : DrawingObject
{
public override void Print()
{
Debug.Log("Line");
}
}
//file name: Polymorph.cs
using UnityEngine; using System;
public class Polymorph : MonoBehaviour
{
public DrawingObject m_drawingObject = null;
public void Init()
{
m_drawingObject = new Line();
}
public void Start()
{
m_drawingObject.Print();
}
}
public class PolymorphClass : GameObject { public PolymorphClass() { m_component = AddComponent<Polymorph>(); m_component.Init(); } public Polymorph m_component = null; }
//when i create an instance of 'PolymorphClass' in editor and run it, its script 'Polymorph' executes a 'Start' method, which ideally call overriden 'Print' of 'Line', but what i see printed is 'DrawingObject' :( kindly see if am making any mistakes here. (not deriving from game object just opens a new issue of its own (how should i place an objects in the editor then?).. but for now i want to know what else is wrong with it)
As far as I know, you can't (or shouldn't) make new instances of $$anonymous$$onoBehaviour and its children. If I try this, I get this warning: "You are trying to create a $$anonymous$$onoBehaviour using the 'new' keyword. This is not allowed. $$anonymous$$onoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all"
Despite the warning, I still get a correct printout of the name when I try to duplicate the issue. $$anonymous$$y guess is that there is some detail missing in your explanation above, maybe you can post the exact code that leads to the issue.
i am not instanciating $$anonymous$$onoBehaviour but GameObjects. These are public members of my class which is a $$anonymous$$onoBehaviour.
Answer by qJake · Aug 13, 2010 at 09:06 AM
You cannot and should not derive from GameObject. This functionality has been removed in Unity 3 (GameObject is a sealed class), and this behavior is highly discouraged. You need to think up another way to solve whatever problem you're facing.
I am using unity 2.6 and i do not get any compile time errors for inheriting GameObject (if it is sealed). Even according to unity user reference, this is not clear if we must not derive from GameObject.
could you please elaborate on this..
Not really... it's just kind of common knowledge around here that you shouldn't do that. Why do you think they sealed it in 3.0? Because they don't want people doing it :P Just because you don't get compile errors doesn't mean you aren't doing something wrong.
Though this is not the exact answer i was expecting, but it the root cause of my issue. i figured out the exact answer later, that is based on SpikeX advice.
The polymorphism doesnt simply work on GameObjects, though the inheritance works (this applies to the unity version 2.6). At run time unity most probably create a mem copy of the world setup because of which polymorphism data on GameObjects is lost. (i need your opinion on this for its correctness). I solved it by keeping the Gameobject common and applying polymorphism on classes that are '$$anonymous$$onoBehaviour'.
Answer by Wolfram · Aug 13, 2010 at 11:33 AM
(You cannot use both virtual and override. Make your Crow.name "override string name".) [no longer valid; question was edited]
EDIT: moved answer from comment:
The type of an object is always seen as the class used in the variable declaration, not the actual derived class. You can use myBird.GetType() for that, it will return Bird if it's a Bird, and Crow if it's a Crow. msdn.microsoft.com/en-us/library/ You can also use dynamic casting, so "myBird as Crow" should return null for non-Crows, and Crow for Crows.
my mistake, i edited it, (though i already stated this is just for example)
well, my issue is not that my code is not compiling, but i cant use polymorphism.
Ah, I remember having had a problem like that. The type of an object is always seen as the class used in the variable declaration, not the actual derived class. You can use myBird.GetType() for that, it will return Bird if it's a Bird, and Crow if it's a Crow. http://msdn.microsoft.com/en-us/library/system.object.gettype.aspx You can also use dynamic casting, so "myBird as Crow" should return null for non-Crows, and Crow for Crows.
Answer by Magnus Wolffelt · Aug 13, 2010 at 08:41 PM
That is odd. Looking at your code, it should be working with polymorphism. It could be weird things happening due to the GameObject inhertiance, like Spike says.
Have you double checked everything? Have you tried something exactly the same, without inheriting GameObject?
if i make 'DrawingObject' inherit 'System.Object' then at run time i get null reference exception for 'm_drawingObject'
and if i inherit 'UnityEngine.Object' Unity itself crashes :|(why there is no smiley?.. i want to show my frustration)