0

Pretty much the title. I first set it in the first method and as soon as I wanna call it up it says it´s empty. Even in the Inspector it says that it´s set to the right thing but it can´t be called for some reason.

The two relevant code snippets:

public class WUZ_Unit : Leader
{
    public override void UpdatePosition()
    {
    vecPos = GameObject.Find("WUZ(Clone)").transform.position;
    Debug.Log(this + " the grid: " + grid);
    **position = grid.GetNode((int)vecPos.x, (int)vecPos.y);**
    }
}

and:

public abstract class Entity : MonoBehaviour {

   public void InitiateGrid(Gridmanager g)
   {
    anim = GetComponent<Animator>();
    if (anim.gameObject.activeSelf)
    {
        anim.SetBool("IsAlive", true);
    }
    grid = g;
    Debug.Log(this + " set " + grid);
    }
}

what the console spits out on the first Debug Log:

enter image description here

and what the console spits out on the second Debug Log:

and what the console spits out:

This is the Error Code in Text: NullReferenceException: Object reference not set to an instance of an object WUZ_Unit.UpdatePosition () (at Assets/Scripts/Unit/WUZ_Unit.cs:21) GameHandler.UpdateAllMoves () (at Assets/Scripts/GameHandler.cs:1805) GameHandler.Start () (at Assets/Scripts/GameHandler.cs:1697)

The asked for code regarding instantiation:

    public void GenerateCharacters(int x, int y, GameObject c, int i)
{
    GameObject go = Instantiate(c) as GameObject;
    //Entity e = go.GetComponent<Entity>();
    //StartCoroutine(e.SpawnAnim());


    if (i == 0)
    {
        Unit u = go.GetComponent<Unit>();
        go.GetComponent<Enemy>().enabled = false;
        u.enabled = true;
        u.InitializeUnits();
        u.healthBarEnemy = healthBarEnemy;
        u.healthBarAlly = healthBarAlly;
        u.healthMeter = healthbarMeter;
        u.highlightAttack = highlightAttack;
        u.highlightIndicator = highlightIndicator;
        u.highlightMove = highlightMove;
        u.InitiateGrid(grid);
        u.SetPos(x, y);
        GeneratePosition(u, x, y);
        u.PlayerChange(gamePhase);
        go.GetComponent<Enemy>().enabled = false;

    }

This is the asked for code regarding updateposition:

    public void UpdateAllMoves()
        {
            Debug.Log("updating all moves");
            //Updating the grid status
            grid.UpdatePosition();

            Unit[] ul = unitList.ToArray();

            for (int i = 0; i < ul.Length; i++)
            {
                ul[i].UpdatePosition();
            }

            Enemy[] el = enemyList.ToArray();
            for (int i = 0; i < el.Length; i++)
            {
                el[i].UpdatePosition();
            }

            CheckforCheckUnit(grid);
            CheckforCheckEnemy(grid);

            ConvertAllMoves();
            grid.ClearNodeMoves();

            grid.UpdatePosition();

            UpdateNodes();

            grid.UpdatePosition();

            for (int i = 0; i < ul.Length; i++)
            {
                **ul[i].UpdatePosition();**
            }

            for (int i = 0; i < el.Length; i++)
            {
                el[i].UpdatePosition();
            }

            CheckforCheckUnit(grid);
            CheckforCheckEnemy(grid);

            ConvertAllMoves();
            grid.ClearNodeMoves();

            grid.UpdatePosition();

            UpdateNodes();


        }

so I made sure that vecPos is not the problem:

    Debug.Log(this + " the grid: " + grid + " the vecPos " + vecPos.x + " " + vecPos.y);

What the console spits out:

WUZ (WUZ_Unit) the grid:  the vecPos 2 28
UnityEngine.Debug:Log(Object)
WUZ_Unit:UpdatePosition() (at Assets/Scripts/Unit/WUZ_Unit.cs:20)
GameHandler:UpdateAllMoves() (at Assets/Scripts/GameHandler.cs:1805)
GameHandler:Start() (at Assets/Scripts/GameHandler.cs:1697)

more clarification code:

    public void GettingCharacters()
{
    Debug.Log(StaticPara.player1Units.Length);
    for(int i = 0; StaticPara.player1Units.Length > i; i++)
    {
        unitList.Add(StaticPara.player1Units[i].GetComponent<Unit>());
        int x = startingTilesBlue[i].xPos;
        int y = startingTilesBlue[i].yPos;
        GenerateCharacters(x, y, StaticPara.player1Units[i], 0);
    }

    for (int i = 0; StaticPara.player2Units.Length > i; i++)
    {
        enemyList.Add(StaticPara.player2Units[i].GetComponent<Enemy>());
        int x = startingTilesRed[i].xPos;
        int y = startingTilesRed[i].yPos;
        GenerateCharacters(x, y, StaticPara.player2Units[i], 1);
    }
}



void Start()
{
    grid = gridGO.GetComponent<Gridmanager>();
    grid.CreateGrid();

    //setting up ui and the game
    gamePhase = 0;
    phaseStatusString = "Move Phase";
    endPhaseButton.GetComponent<Button>().interactable = false;
    ability_ALX = true;
    //spawning character Models
    GenerateStartingPositions();
    GettingCharacters();


    //Updating their stats
    Unit[] ul = unitList.ToArray();
    for (int i = 0; i < ul.Length; i++)
    {
        ul[i].healthMax = ul[i].healthBase;
        ul[i].healthCurrent = ul[i].healthMax;
        ul[i].damageCurrent = ul[i].damageBase;
    }

    Enemy[] el = enemyList.ToArray();
    for (int i = 0; i < el.Length; i++)
    {
        el[i].healthMax = el[i].healthBase;
        el[i].healthCurrent = el[i].healthMax;
        el[i].damageCurrent = el[i].damageBase;
    }

    SelectKing();
    **UpdateAllMoves();**
}

Here is the Update Nodes Function:

    public void UpdateNodes()
{
    for(int i = 0; i < unitList.Count; i++)
    {
        for(int j = 0; j < unitList[i].possibleMoves.Length; j++)
        {
            for(int k = 0; k < unitList[i].possibleMoves[j].Count; k++)
            {
                unitList[i].possibleMoves[j][k].moveableByUnit.Add(new CheckAssist(unitList[i], j));
            }
        }

        for (int j = 0; j < unitList[i].possibleAttacks.Length; j++)
        {
            for (int k = 0; k < unitList[i].possibleAttacks[j].Count; k++)
            {
                unitList[i].possibleAttacks[j][k].attackableByUnit.Add(new CheckAssist(unitList[i], j));
            }
        }

        for (int j = 0; j < unitList[i].possibleAttackIndicators.Length; j++)
        {
            for (int k = 0; k < unitList[i].possibleAttackIndicators[j].Count; k++)
            {
                unitList[i].possibleAttackIndicators[j][k].attackableByUnit.Add(new CheckAssist(unitList[i], j));
            }
        }

        for (int j = 0; j < unitList[i].possibleAttacksInactive.Length; j++)
        {
            for (int k = 0; k < unitList[i].possibleAttacksInactive[j].Count; k++)
            {
                unitList[i].possibleAttacksInactive[j][k].passiveAAByUnit.Add(new CheckAssist(unitList[i], j));
            }
        }
    }

    for (int i = 0; i < enemyList.Count; i++)
    {
        for (int j = 0; j < enemyList[i].possibleMoves.Length; j++)
        {
            for (int k = 0; k < enemyList[i].possibleMoves[j].Count; k++)
            {
                enemyList[i].possibleMoves[j][k].moveableByEnemy.Add(new CheckAssist(enemyList[i], j));
            }
        }

        for (int j = 0; j < enemyList[i].possibleAttacks.Length; j++)
        {
            for (int k = 0; k < enemyList[i].possibleAttacks[j].Count; k++)
            {
                enemyList[i].possibleAttacks[j][k].attackableByEnemy.Add(new CheckAssist(enemyList[i], j));
                //Debug.Log("added attack to" + enemyList[i].possibleAttackIndicators[j][k].xPos + " " + enemyList[i].possibleAttackIndicators[j][k].yPos);
            }
        }

        for (int j = 0; j < enemyList[i].possibleAttackIndicators.Length; j++)
        {
            for (int k = 0; k < enemyList[i].possibleAttackIndicators[j].Count; k++)
            {
                enemyList[i].possibleAttackIndicators[j][k].attackableByEnemy.Add(new CheckAssist(enemyList[i], j));
                //Debug.Log("added attack to" + enemyList[i].possibleAttackIndicators[j][k].xPos + " " + enemyList[i].possibleAttackIndicators[j][k].yPos);
            }
        }

        for (int j = 0; j < enemyList[i].possibleAttacksInactive.Length; j++)
        {
            for (int k = 0; k < enemyList[i].possibleAttacksInactive[j].Count; k++)
            {
                enemyList[i].possibleAttacksInactive[j][k].passiveAAByEnemy.Add(new CheckAssist(unitList[i], j));
            }
        }
    }
}
  • 1
    Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/181986/discussion-on-question-by-rafael-pietsch-nullreferenceexception-in-child-class-w). – Samuel Liew Oct 16 '18 at 23:01

2 Answers2

2

The problem seems to be that some line among these:

CheckforCheckUnit(grid);
CheckforCheckEnemy(grid);

ConvertAllMoves();
grid.ClearNodeMoves();

grid.UpdatePosition();

UpdateNodes();

grid.UpdatePosition();

is modifying the Units in unitList in some way that sets the Unit.grid value to null.

Something else you might consider is adding GridManager as a parameter to UpdatePosition():

public override void UpdatePosition(GridManager gameGrid) {
    vecPos = GameObject.Find("WUZ(Clone)").transform.position;
    Debug.Log(this + " the grid: " + gameGrid);
    position = gameGrid.GetNode((int)vecPos.x, (int)vecPos.y);
}

and then in UpdateAllMoves, include it in the calls. e.g.:

...
    el[i].UpdatePosition(grid);
...
    ul[i].UpdatePosition(grid);
...
Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • I guess I could do that. I will use the static variable instead though. or is that dumb? – Rafael Pietsch Oct 16 '18 at 20:25
  • 2
    As long as it works it's probably not "dumb" but as you just saw it could take some time to find the issue. With this direct parameter call you could exactly track back at which point a value was not set/passed correctly. – derHugo Oct 16 '18 at 20:31
  • 1
    There's nothing wrong with doing it technically, since `GridManager` is something you only ever want one of. But it might lead to unpredictable results that are hard to pinpoint if you ever accidentally create an extra `GridManager` instance that also modifies that static variable. – Ruzihm Oct 16 '18 at 20:32
  • Thank you guys for the Help – Rafael Pietsch Oct 16 '18 at 20:35
  • @RafaelPietsch If you're still interested in fixing the underlying problem, I edited my answer to have a better suggestion of where to look. – Ruzihm Oct 16 '18 at 20:45
  • @Ruzihm I would be interested. Because now the same Problem appears at a different stage with a diffrent variable. It seems all variables in the Object are empty... – Rafael Pietsch Oct 16 '18 at 20:57
  • 1
    NullReferenceException: Object reference not set to an instance of an object GameHandler.UpdateNodes () (at Assets/Scripts/GameHandler.cs:1061) GameHandler.UpdateAllMoves () (at Assets/Scripts/GameHandler.cs:1823) GameHandler.Start () (at Assets/Scripts/GameHandler.cs:1698) here is the error... sighhhh – Rafael Pietsch Oct 16 '18 at 21:01
0

I fixed my own Code and here is how:

    unitList.Add(StaticPara.player1Units[i].GetComponent<Unit>());
    int x = startingTilesBlue[i].xPos;
    int y = startingTilesBlue[i].yPos;
    GenerateCharacters(x, y, StaticPara.player1Units[i], 0);

I added the Unit script from the passed the GameObject rather than the Unit script from the instantiated Gameobject meaning I changed variables that were not even in the List

Thanks for all the help @ruzihm

EDIT: Yes I did I moved unitList.Add from GettingCharacters() to GenerateCharacters()