简体   繁体   English

C#OnTriggerEnter NullReferenceException

[英]C# OnTriggerEnter NullReferenceException

I'm using the ZDK from Zigfu for Game Project on my study. 我在学习中使用Zigfu的ZDK for Game Project。 I took the standard avatar and attached two colliders (sphere colliders with rigid body) to the hands. 我拿了标准化身并将两个碰撞器(球体碰撞器与刚体)连接到手上。 One for the left hand, and one for the right hand. 一个用于左手,一个用于右手。 I build some (24) box colliders around the avatar, to track if the hands are entering a new area. 我在头像周围建造了一些(24)盒子对撞机,以跟踪手是否正在进入一个新区域。 Every box has an "id" from 0 to 23 an the following script: 每个框都有一个“id”,从0到23以下脚本:

using UnityEngine;
using System.Collections;

public class handsTracking : MonoBehaviour 
{
    public int id;

    void OnTriggerEnter (Collider other) {
        if(other.tag == "handsLeftTracking"){
            print("leftHand entered: " + id);
            playerCommunication.activity += 0.1f;
            playerCommunication.handsLeft[id] = true; //here ist the exception
        }
        else if (other.tag == "handsRightTracking"){
            print("rightHand entered: " + id);
            playerCommunication.activity += 0.1f;
            playerCommunication.handsRight[id] = true; //here ist the exception
        }
    }
    void OnTriggerExit (Collider other) {
        if(other.tag == "handsLeftTracking"){
            print("leftHand exited: " + id);
            playerCommunication.activity += 0.01f;
            playerCommunication.handsLeft[id] = false; //here ist the exception
        }
        else if (other.tag == "handsRightTracking"){
            print("rightHand exited: " + id);
            playerCommunication.activity += 0.01f;
            playerCommunication.handsRight[id] = false; //here ist the exception
        }
    }
}

In another script on the player I want to use these collisions. 在玩家的另一个脚本中我想使用这些碰撞。 The handsTracking.cs should only edit the values in the playerCommunication.cs script: handsTracking.cs应该只编辑playerCommunication.cs脚本中的值:

using UnityEngine;
using System.Collections;

public class playerCommunication : MonoBehaviour {

    public static bool[] handsRight;
    public static bool[] handsLeft;
    public static float activity;
    public float fallback;

    // Use this for initialization
    void Awake () {
        activity = 0.0f;
    }

    // Update is called once per frame
    void Update () {
        if((activity - fallback * Time.deltaTime) >= 0.0f){
            activity -= fallback * Time.deltaTime;
        }
    }

    void OnGUI () {
        GUI.Box (new Rect (10,200,150,20), "Activity: " + activity);    
    }
}

This works fine, so far. 到目前为止,这工作正常。 But I'm getting the following exceptions: 但我得到以下例外情况:

NullReferenceException: Object reference not set to an instance of an object
handsTracking.OnTriggerEnter (UnityEngine.Collider other) (at Assets/SeriousGame/Scripts/handsTracking.cs:19)

If I commend out lines where I tried to edit the array, the errors are gone. 如果我推测出我试图编辑数组的行,错误就消失了。 I tried to call a function in the playerCommunication script, or to handle the arrays in the handsTracking.cs , but nothing works. 我试图在playerCommunication脚本中调用一个函数,或者在handsTracking.cs中处理数组,但没有任何效果。 I don't understand the link between the collision and the array?! 我不明白碰撞和阵列之间的联系?!

Your array haven't been never initialized. 您的数组尚未初始化。 You got a NullReferenceException because your array is a reference to null since it hasn't be allocated nowhere. 你得到一个NullReferenceException因为你的数组是null的引用,因为它没有被分配。

For example you can init them inside Awake : 例如,您可以在Awake初始化它们:

int[] array1 = new int[5];

public static bool[] handsLeft;

// Use this for initialization
void Awake () {
    activity = 0.0f;
    handsLeft = new bool[ARRAY_SIZE];
}

Maybe you have tried to initialized those array fields from inspector, but they are declared as static so Unity3D won't serialize them when you switch from editor to play mode. 也许您已尝试从检查器初始化这些数组字段,但它们被声明为静态,因此当您从编辑器切换到播放模式时, Unity3D 不会将它们序列化

Pay attention that a static field would be shared by all instances of playerCommunication class. 注意所有playerCommunication类的实例都会共享一个静态字段。 So, if you want to have several GameObject to use this script, with different values inside your arrays, you shouldn't declare them as static. 因此,如果您希望让几个GameObject使用此脚本,并且在数组中使用不同的值,则不应将它们声明为静态。

If you want effectively declare them as static, since you can't know the order of creation of your classes, it would be better initialize them in a class static construcor: 如果你想有效地将​​它们声明为静态,因为你无法知道类的创建顺序,最好在类static static中初始化它们:

static playerCommunication ()
{
     handsLeft = new bool[ARRAY_SIZE];
     handsRight = new bool[ARRAY_SIZE];
}

The reason you get a nullpointerexception, is because you try to add an object in the array which isn't initialised yet. 获得nullpointerexception的原因是因为您尝试在数组中添加尚未初始化的对象。

You have the following declaration: 您有以下声明:

public int id;

After that, you have the following line of code: 之后,您有以下代码行:

print("leftHand entered: " + id);

Change that to, for example: 将其更改为,例如:

Debug.Log("ID value is now: " + id);

You will probably see the following: 您可能会看到以下内容:

ID value is now: null

You haven't given id a value yet. 你尚未给id一个值。 When you call playerCommunication.handsLeft[id] = true; 当你调用playerCommunication.handsLeft[id] = true; , you are actually trying to set the null'est value of the array to true . ,您实际上是在尝试将数组的null'est值设置为true Make sure you set the id -value to something. 确保将id value设置为某个值。 You say every box has a id value from 0 to 23. Did you set that correctly in the Unity properties view? 你说每个盒子的id值都是0到23.你是否在Unity属性视图中正确设置了?

My guess as to the reason you're getting the exception is because you're not accessing the playerCommunication script that's on the player, instead it's trying to use the one in the script folder, which (I imagine) doesn't have anything set on the public handsRight etc. 我猜你得到异常的原因是因为你没有访问播放器上的playerCommunication脚本,而是试图使用脚本文件夹中的那个,我想这里没有任何设置在公众手上等

What you need to do is replace lines like this: 你需要做的是替换这样的行:

playerCommunication.handsLeft[id] = true;

with this: 有了这个:

GameObject.Find("Avatar").GetComponent<playerCommunication>().handsLeft[id] = true;

where "Avatar" will be the name of the avatar/player game object, and playerCommunication is the script within that object which has the handsLeft public bool. 其中“Avatar”将是头像/玩家游戏对象的名称,而playerCommunication是该对象中具有handsLeft公共bool的脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM