Unity教程(Space Shooter),C#NullReferenceException

时间:2015-09-05 23:40:22

标签: c# unity3d

我正在通过统一网站(here)上的'太空射击'教程,我遇到以下代码的问题。我试图对船只Rigidbody施加限制,使其无法离开可见的游戏区域。但是,我收到以下错误,我不明白为什么(这是我第一次使用C#,所以很抱歉,如果它真的很明显是什么问题):

错误:

NullReferenceException: Object reference not set to an instance of an object
PlayerController.FixedUpdate () (at Assets/Scripts/PlayerController.cs:28)

我在下面标记了第28行(在错误中提到)

脚本:

using UnityEngine;
using System.Collections;

public class Boundary 
{
    public float xMin, xMax, zMin, zMax;
}

public class PlayerController : MonoBehaviour 
{

    public float speed;
    public Boundary b;
    public Rigidbody rb;

    void Start ()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate () {
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
        rb.velocity = movement * speed;

        rb.position = new Vector3(  \\ *** line 28 ***
            Mathf.Clamp (rb.position.x, b.xMin, b.xMax),
            0.0f,
            Mathf.Clamp (rb.position.z, b.zMin, b.zMax)
        );

    }
}

非常感谢任何有关解决此错误的帮助,教程中的脚本本身与unity5不兼容,但我只是看不出这个错误是对的。

2 个答案:

答案 0 :(得分:1)

在您的代码中,Boundary是一种引用类型,这意味着如果您没有为其提供值,则为空。在您的代码中,我无法看到您曾为b分配了一个值。这就是NullReferenceException出现的原因 - b为空!也许你可以在start方法中做到这一点:

b = new Boundary ();
b.xMin = 1;
b.xMax = 2;
b.zMin = 3;
b.zMax = 4;
//The numbers are just examples. Change it however you want

这应该使b不为空。或者,您可以在Boundary类中添加构造函数:

public Boundary (int xMin, int xMax, int zMin, int zMax) {
    this.xMin = xMin;
    this.xMax = xMax;
    this.zMin = zMin;
    this.zMax = zMax;
}

答案 1 :(得分:1)

正如您在评论中提到的那样,您并未在任何地方初始化b,因此默认情况下为null。阅读默认值和内容here,还可以查看值类型和引用类型之间的区别,例如,有一种方法可以使Boundary成为值类型。

您可能还想在Boundary中添加构造函数,以便更容易创建构造函数。

public class Boundary 
{
    public float xMin, xMax, zMin, zMax;

    public Boundary(float xMin, float xMax, ...)
    {
          // Set your fields.
    }
}

更好的是,使用Unity的Vector2类型来存储您的边界信息。

public class Boundary 
{
    public Vector2 MinPoint;
    public Vector2 MaxPoint;

    public Boundary(Vector2 minPoint, Vector2 maxPoint)
    {
          MinPoint = minPoint;
          MaxPoint = maxPoint;
    }
}

写这个片段比写第一个片段痛苦得多。如果您真的不需要存储这4个坐标的其他方法,请查看Rect here,因为它已经满足您的需求。