Keyshon
Keyshon

Reputation: 143

Why is the class reference lost on MonoBehaviour Start()

I create an instance of a new GameObject in a static method, where I set all the GameObject fields. However, when I try to get the fields from Start(), reference attributes are nulls.

public class Hero : MovableStrategicObject
{
    public string heroName;
    public Player conrtollingPlayer;

    protected new void Start()
    {
        base.Start();
        Debug.Log("2 - Hero name: " + heroName);
        Debug.Log("2 - Controlling player exists: " + (conrtollingPlayer != null));
        Debug.Log("2 - Tile exists: " + (currentTile != null)); // Inherited attribute
    }

    public static GameObject Spawn(Tile tile, Player player, string name, string prefabPath = "Heroes/HeroPrefab")
    {
        GameObject o = MovableStrategicObject.Spawn(prefabPath, tile);
        var scripts = o.GetComponents(typeof(MonoBehaviour));
        Hero hero = null;

        foreach (MonoBehaviour s in scripts)
        {
            if (s is Hero)
                hero = s as Hero;
        }

        if (hero != null)
        {
            Instantiate(o, (Vector2)tile.gameObject.transform.position, Quaternion.identity);
            o.GetComponent<Hero>().conrtollingPlayer = player;
            o.GetComponent<Hero>().heroName = name;
            Debug.Log("1 - Hero name: " + o.GetComponent<Hero>().heroName);
            Debug.Log("1 - Controlling player exists: " + (o.GetComponent<Hero>().conrtollingPlayer != null));
            Debug.Log("1 - Tile exists: " + (o.GetComponent<Hero>().currentTile != null)); // Inherited attribute

            return o;
        }
        else
        {
            Debug.Log("Object (" + prefabPath + ") has no Hero script attached.");
            return null;
        }
    }
}

Result:

enter image description here

P.S. You can be sure that it is the right game object because the hero name and all the derived attributes are assigned properly.

Upvotes: 1

Views: 46

Answers (1)

Keyshon
Keyshon

Reputation: 143

The problem was in that line:

Instantiate(o, (Vector2)tile.gameObject.transform.position, Quaternion.identity);

Because this object is a new instance of GameObject, all assignments with the previous object didn't affect this instance. So the fix was:

GameObject h = Instantiate(o, (Vector2)tile.gameObject.transform.position, Quaternion.identity);
h.GetComponent<Hero>().conrtollingPlayer = player;
h.GetComponent<Hero>().heroName = name;

return h;

The new object already has this information.

Upvotes: 2

Related Questions