- Home /
Using GetComponent with base classes
I have a weird problem where I'm trying to access a component inside a gameobject by referencing its base class which is only returning a null. Here's how I'm trying to access my component.
m_attachment = m_heldObject.GetComponent< BaseAttachment<BaseMusicObject> >();
In this situation, the actual component is of type InstrumentAttachment which extends BaseAttachment. The class is set up like this.
public class BaseAttachment<T> : MonoBehaviour where T : BaseMusicObject
{
protected T m_musicRef;
public virtual T musicRef{ get { return m_musicRef;}
public virtual void Init(T managedReference){
m_musicRef = managedReference;
}
}
InstrumentAttachment is initialized as a InstrumentAttachment
object so that musicRef can be returned with the same type the generic class is initialized as. BaseInstrument extends BaseMusicObject. InstrumentAttachment is set up in this way.
public class InstrumentAttachment : BaseAttachment<BaseInstrument>{
}
Using GetComponent( typeOf(BaseAttachment < BaseMusicObject > ) ) as BaseAttachment < BaseMusicNote > ;
will also fail, but accessing the component with its derived type using GetComponent()
will work.
Am I doing something horribly wrong?
To show properly in text, you need to put spaces around them so the text formatter doesn't think they're html or whatever.
GetComponent( typeof( baseat ) ) as basat
If you're able to AddComponent your components with the proper types, you might need to cache the result of that function in another separate holder component to be able to consistently get the component :S.
Ah, thank you. This is my first question here so I'm not used to the formatting yet.
I definitely considered the caching idea, but the attachment class will either be created at runtime or added to a prefab, so I didn't have a consistent way of referencing it without using GetComponent. I've managed to work around the issue now regardless.
Answer by Azrapse · Oct 25, 2013 at 04:30 PM
I'm not 100% sure that you are being affected by this, but I suspect that you are making use of covariance and contravariance in generic types and those features were incorporated first into C# 4.0.
As far as I know, Unity uses C# 3.0.
Have a look at this: Covariance and Contravariance
Answer by Mystfit · Oct 26, 2013 at 06:36 AM
I managed to work around this problem by having a non-typed abstract class as the base class.
GetComponent< BaseAttachment>()
now works since derived classes all have a common ancestor to work from.
Base Classes:
public abstract class BaseAttachment : MonoBehaviour
{
public virtual void foo()
{
}
}
public class BaseAttachment<T> : BaseAttachment
{
protected T m_musicRef;
public void Init(T managedReference){
m_musicRef = managedReference;
}
public T musicRef{ get { return m_musicRef; }}
}
Derived class:
public class InstrumentAttachment : BaseAttachment<BaseInstrument>{
public override void foo()
{
}
}
This lets me run my overridden functions from any class derived from BaseAttachment, but offers me the ability to return the correctly typed musicRef object if working with the derived class.
Eg:
GameObject instrument = new GameObject();
instrument.AddComponent<InstrumentAttachment>().Init( new BaseInstrument() );
//Runs overridden foo
instrument.GetComponent<BaseAttachment>().foo();
//Runs overridden foo
instrument.GetComponent<InstrumentAttachment>().foo();
//Returns BaseInstrument
instrument.GetComponent<InstrumentAttachment>().musicRef;
Your answer
Follow this Question
Related Questions
How to GetComponent from Class that uses Generics 1 Answer
How do I reference a generic BaseClass using GetComponentInParent<>() 2 Answers
Why is this generic "Get component if null" code not working 5 Answers
Implicit type GetComponent call 0 Answers
Why use generics GetComponent() and what are generics 1 Answer