Unity: NullReferenceException

本文关键字:NullReferenceException Unity | 更新日期: 2023-09-27 18:24:25

NullReferenceException:对象引用未设置为对象的实例Tower.OnGUI()(位于Assets/Tower.cs:100)

相关线路为:

if(Main.Gold >= Towers.u[stage])

Towers中的变量是这样定义的,我做错了吗?

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Towers : MonoBehaviour {
    public static float[] d;
    public static float[] r;
    public static float[] s;
    public static float[] u;
    // Use this for initialization
    void Start () { 
        d = new float[10];
        d[0] = 1f;
        d[1] = 3f;
        d[2] = 5f;
        d[3] = 7f;
        d[4] = 9f;
        d[5] = 11f;
        d[6] = 13f;
        d[7] = 15f;
        d[8] = 18f;
        d[9] = 21f;
        d[10] = 23f;        
        r = new float[10];
        r[0] = 5f;
        r[1] = 9f;
        r[2] = 13f;
        r[3] = 17f;
        r[4] = 21f;
        r[5] = 25f;
        r[6] = 29f;
        r[7] = 33f;
        r[8] = 37f;
        r[9] = 41f;
        r[10] = 45f;
        s = new float[10];
        s[0] = 3f;
        s[1] = 2.8f;
        s[2] = 2.6f;
        s[3] = 2.4f;
        s[4] = 2.2f;
        s[5] = 2f;
        s[6] = 1.8f;
        s[7] = 1.6f;
        s[8] = 1.4f;
        s[9] = 1.2f;
        s[10] = 1f;
        u = new float[10];
        u[0] = 50f;
        u[1] = 100f;
        u[2] = 150f;
        u[3] = 200f;
        u[4] = 250f;
        u[5] = 300f;
        u[6] = 350f;
        u[7] = 400f;
        u[8] = 450f;
        u[9] = 500f;
        u[10] = 0f;     
    }
}

谢谢!

Unity: NullReferenceException

似乎是Main为null,或者您没有在导致问题的行之前调用Towers.Start()

当初始化这样的静态字段时,有时最好在声明字段的地方使用静态初始化,方法是调用返回初始化数据的私有静态方法。

这样做意味着您不需要必须记住调用的单独的Start()方法。

例如:

public class Towers: MonoBehaviour
{
    public static float[] d = initD();
    public static float[] r = initR();
    public static float[] s = initS();
    public static float[] u = initU();
    private static float[] initD()
    {
        return new []
        {
             1f,
             3f,
             5f,
             7f,
             9f,
            11f,
            13f,
            15f,
            18f,
            21f,
            23f
        };
    }
    private static float[] initR()
    {
        return new []
        {
             5f,
             9f,
            13f,
            17f,
            21f,
            25f,
            29f,
            33f,
            37f,
            41f,
            45f
        };
    }
    private static float[] initS()
    {
        return new []
        {
            3.0f,
            2.8f,
            2.6f,
            2.4f,
            2.2f,
            2.0f,
            1.8f,
            1.6f,
            1.4f,
            1.2f,
            1.0f
        };
    }
    private static float[] initU()
    {
        return new[]
        {
             50f,
            100f,
            150f,
            200f,
            250f,
            300f,
            350f,
            400f,
            450f,
            500f,
              0f
        };
    }
}

您应该将任何单体行为的初始化放在Awake而不是Start中,Awake是您可以在单体行为生命周期中捕获的第一个事件。

编辑:请记住,如果你试图访问Awake中的其他MonoBehaviours,你不能确定它们是否已经初始化。

您应该将Start函数中的行移到创建时调用的Awake函数中。您尝试访问从0到10的数组,但数组大小为10,因此您必须访问最多9的数组。若要访问数组的第十个值,必须将其分配为11大小,这意味着实际的值计数。