In my test, I define a class (SubGO, Sub Game Object) that is both a MonoBehaviour and interface (IInputSrc4ACT). Then, in my testing scene, I let another class (BaseGO, Base Game Object) contain a reference to an instance of SubGO. In the Start() of BaseGO, I cast that SubGO reference to an interface reference, then, I try to access that interface reference. What I find is that interface reference can be correctly converted from MonoBehaviour or Behaviour, while casting from Component or Unity Object results null references. Why?
Here below is the code of BaseGO.cs.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IInputSrc4ACT //input interface for ACT game
{
bool Jump();
}
public class BaseGO : MonoBehaviour
{
public int val;
public MonoBehaviour inputSrcRef;
//public Behaviour inputSrcRef; also works.
//public Component inputSrcRef; Component or Object not work!
public IInputSrc4ACT inputSrc; //interface we plan to use
public SubGO inputSrcRefConcrete; //not important in this test
void Awake()
{
inputSrc = inputSrcRef as IInputSrc4ACT;
//inputSrc = (IInputSrc4ACT) inputSrcRef; //as is better
}
void Start()
{
inputSrc.Jump();
//If inputSrc is casted from MonoBehaviour or Behaviour, this works correctly.
//If inputSrc is casted from Component or Object, this cause null-reference error.
RestoreSubGo(inputSrc);
inputSrcRefConcrete.Jump(); //not important in this test
}
//when casting back, see if any data is lost
void RestoreSubGo(IInputSrc4ACT interf)
{
SubGO subGo = interf as SubGO;
Debug.Log("subGO-" + subGo.nameStr + "-" + subGo.id);
}
}
Here below is the code of SubGO.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SubGO : MonoBehaviour, IInputSrc4ACT
{
public int id;
public string nameStr;
public bool Jump()
{
Debug.Log(id + ": Jump implemented");
return true;
}
}
This picture below shows BaseGO instance in my testing scene.
Its InputSrcRef contains a reference to SubGO instance in the scene.
This right here. The only time you should use âasâ to cast is if you know that the cast might fail, and youâve got code handling the null case. In your example, you should be getting a cast exception in Awake thatâd tell you what youâre casting wrong, but youâre getting a nullref in Start instead.
Yes, when I use âpublic Component inputSrcRefâ, and drag a SubGO instance in Unity editor onto inputSrcRef slot of BaseGO, that slot shows âTransformâ. Now, I understand how the underlying mechanism works: it is trying to find the first type that can cast to the field type. I did some tests to verify this mechanism.
It works with âpublic Component inputSrcRefâ. @lordofduct@Kiwasi@Baste
Now I have another question for this:
I thought GetComponent can only get and return a Unity Component? Why it works on my own defined interface, IInputSrc4ACT?
Also worth mentioning that for a long time, this exact case didnât work. IIRC there used to be a constraint on GetComponent so you couldnât pass non-Component types to it. Thank god thatâs changed.