引用父级成员时子类中的NullReferenceException

时间:2018-10-16 16:25:03

标签: c# unity3d

几乎是标题。我首先用第一种方法进行设置,一旦我想调用它,它就说它是空的。即使在检查器中,它也表示已将其设置为正确的东西,但由于某种原因而无法调用。

两个相关的代码段:

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);**
    }
}

和:

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);
    }
}

控制台在第一个调试日志中显示的内容:

enter image description here

以及控制台在第二个调试日志中显示的内容:

and what the console spits out:

这是文本中的错误代码:     NullReferenceException:对象引用未设置为对象的实例     WUZ_Unit.UpdatePosition()(位于Assets / Scripts / Unit / WUZ_Unit.cs:21)     GameHandler.UpdateAllMoves()(在Assets / Scripts / GameHandler.cs:1805)     GameHandler.Start()(位于Assets / Scripts / GameHandler.cs:1697)

询问有关实例化的代码:

    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;

    }

这是有关更新位置的要求代码:

    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();


        }

所以我确定vecPos不是问题:

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

控制台吐出的内容:

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)

更多说明代码:

    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();**
}

这是更新节点功能:

    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));
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

问题似乎出在其中:

CheckforCheckUnit(grid);
CheckforCheckEnemy(grid);

ConvertAllMoves();
grid.ClearNodeMoves();

grid.UpdatePosition();

UpdateNodes();

grid.UpdatePosition();

正在以某种方式修改Unit中的unitList,将Unit.grid的值设置为空。

您可能会考虑将GridManager作为参数添加到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);
}

,然后在UpdateAllMoves中将其包括在呼叫中。例如:

...
    el[i].UpdatePosition(grid);
...
    ul[i].UpdatePosition(grid);
...

答案 1 :(得分:0)

我修复了自己的代码,方法如下:

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

我从传递的GameObject中添加了Unit脚本,而不是从实例化的Gameobject中添加了Unit脚本,这意味着我更改了甚至不在List中的变量

感谢@ruzihm的所有帮助

编辑:是的,我确实将unitList.Add从GettingCharacters()移到了GenerateCharacters()