Home > Software design >  GetComponent(Type customType) behaving differently than GetComponent<customType>
GetComponent(Type customType) behaving differently than GetComponent<customType>

Time:05-15

I have this method 'SetStats' that's part of a class.

public class HeroUnit: MonoBehaviour {
    public virtual void SetStats(Stats stats) => Stats = stats;
}

When I instantiate a gameObject by pointing to a prefab, then get the component of a known type 'HeroUnit' attached to it, I can call the SetStats method without any problem.

void SpawnUnit(Vector3 pos) {
    var spawnedGameObject = Instantiate(unitPrefab, pos, Quaternion.identity,transform) as GameObject; 
    var spawned = spawnedGameObject.GetComponent<HeroUnit>();

    spawned.SetStats(stats);
}

However, when I don't force a known component type, and that I rather give it dynamically to the GetComponent() method: the instantiation works, but I can't call the SetStats method anymore.

void SpawnUnit(String myUnit, Vector3 pos) {
    var spawnedGameObject = Instantiate(unitPrefab, pos, Quaternion.identity,transform) as GameObject; 
    Type unitType = Type.GetType(myUnit);
    var spawned = spawnedGameObject.GetComponent(unitType);

    spawned.SetStats(stats);
}

This returns the following compile error :

error CS1061: 'Component' does not contain a definition for 'SetStats' and no accessible extension method 'SetStats' accepting a first argument of type 'Component' could be found

Any idea how to make the compiler understand that 'spawned' is not a 'Component' when the code is ran? I checked 'spawned' type at runtime, and it is a 'HeroUnit', as it should.

CodePudding user response:

Take the var off and see if it'll compile. I don't think you're getting a HeroUnit, I think you're getting a Component.

Try casting the result of GetComponent, like

HeroUnit spawned = (HeroUnit) spawnedGameObject.GetComponent(unitType);

I'll say too that passing types around as strings is a bad idea. You got the string from somewhere, so just use the types instead of strings.

You're probably going to come back and complain about that your unitType isn't necessarily a HeroUnit, to which I would reply, "then how do you know it has a SetStats method?"

You might be better off casting to a base class or interface, but again this string business is not helping you.

  • Related