在统一中,为什么获取错误NullReferenceException:对象引用未设置为CameraScript上对象的实

本文关键字:设置 CameraScript 对象 对象引用 为什么 NullReferenceException 取错误 获取 | 更新日期: 2023-09-27 17:58:16

当我从层次结构中删除AIHirdPersonController时,错误就开始了。现在我有了主摄像头和ThirdPersonController。

我在Inspector中有主摄像头,我添加了一个摄像头脚本.cs

using UnityEngine;
using System.Collections;
public class CameraScript : MonoBehaviour {

    public Transform TargetLookAt;
    public float Distance = 5.0f;
    public float DistanceMin = 3.0f;
    public float DistanceMax = 10.0f;
    private float mouseX = 0.0f;
    private float mouseY = 0.0f;
    private float startingDistance = 0.0f;    
    private float desiredDistance = 0.0f;
    public float X_MouseSensitivity = 5.0f;
    public float Y_MouseSensitivity = 5.0f;
    public float MouseWheelSensitivity = 5.0f;
    public float Y_MinLimit = -40.0f;
    public float Y_MaxLimit = 80.0f;
    public float DistanceSmooth = 0.05f;    
    private float velocityDistance = 0.0f;    
    private Vector3 desiredPosition = Vector3.zero;
    public float X_Smooth = 0.05f;
    public float Y_Smooth = 0.1f;
    private float velX = 0.0f;
    private float velY = 0.0f;
    private float velZ = 0.0f;
    private Vector3 position = Vector3.zero;
    CursorLockMode wantedMode;    

    void  Start (){
        Distance = Mathf.Clamp(Distance, DistanceMin, DistanceMax);
        startingDistance = Distance;
        Reset();
        SetCursorState();
        OnGUI();
    }
    void Update(){
    }
    void  FixedUpdate (){
        if (TargetLookAt == null)
            return;
        HandlePlayerInput();
        CalculateDesiredPosition();
        UpdatePosition();
    }
    void  HandlePlayerInput (){
        float deadZone= 0.01f; // mousewheel deadZone
        //if (Input.GetMouseButton(1))
        //{
        mouseX += Input.GetAxis("Mouse X") * X_MouseSensitivity;
        mouseY -= Input.GetAxis("Mouse Y") * Y_MouseSensitivity;
        //}
        // this is where the mouseY is limited - Helper script
        mouseY = ClampAngle(mouseY, Y_MinLimit, Y_MaxLimit);
        // get Mouse Wheel Input
        if (Input.GetAxis("Mouse ScrollWheel") < -deadZone || Input.GetAxis("Mouse ScrollWheel") > deadZone)
        {
            desiredDistance = Mathf.Clamp(Distance - (Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity), 
                DistanceMin, DistanceMax);
        }
    }
    void  CalculateDesiredPosition (){
        // Evaluate distance
        Distance = Mathf.SmoothDamp(Distance, desiredDistance, ref velocityDistance, DistanceSmooth);
        // Calculate desired position -> Note : mouse inputs reversed to align to WorldSpace Axis
        desiredPosition = CalculatePosition(mouseY, mouseX, Distance);
    }
    Vector3  CalculatePosition ( float rotationX ,   float rotationY ,   float distance  ){
        Vector3 direction = new Vector3(0, 0, -distance);
        Quaternion rotation = Quaternion.Euler(rotationX, rotationY, 0);
        return TargetLookAt.position + (rotation * direction);
    }
    void  UpdatePosition (){
        float posX= Mathf.SmoothDamp(position.x, desiredPosition.x, ref velX, X_Smooth);
        float posY= Mathf.SmoothDamp(position.y, desiredPosition.y, ref velY, Y_Smooth);
        float posZ= Mathf.SmoothDamp(position.z, desiredPosition.z, ref velZ, X_Smooth);
        position = new Vector3(posX, posY, posZ);
        transform.position = position;
        transform.LookAt(TargetLookAt);
    }
    void  Reset (){
        mouseX = 0;
        mouseY = 10;
        Distance = startingDistance;
        desiredDistance = Distance;
    }
    float ClampAngle ( float angle ,   float min ,   float max  ){
        while (angle < -360 || angle > 360)
        {
            if (angle < -360)
                angle += 360;
            if (angle > 360)
                angle -= 360;
        }
        return Mathf.Clamp(angle, min, max);
    }
    // Apply requested cursor state
    void SetCursorState ()
    {
        Cursor.lockState = wantedMode;
        // Hide cursor when locking
        Cursor.visible = (CursorLockMode.Locked != wantedMode);
    }
    void OnGUI ()
    {
        GUILayout.BeginVertical ();
        // Release cursor on escape keypress
        if (Input.GetKeyDown (KeyCode.Escape))
            Cursor.lockState = wantedMode = CursorLockMode.None;
        switch (Cursor.lockState) {
        case CursorLockMode.None:
            GUILayout.Label ("Cursor is normal");
            if (GUILayout.Button ("Lock cursor"))
                wantedMode = CursorLockMode.Locked;
            if (GUILayout.Button ("Confine cursor"))
                wantedMode = CursorLockMode.Confined;
            break;
        case CursorLockMode.Confined:
            GUILayout.Label ("Cursor is confined");
            if (GUILayout.Button ("Lock cursor"))
                wantedMode = CursorLockMode.Locked;
            if (GUILayout.Button ("Release cursor"))
                wantedMode = CursorLockMode.None;
            break;
        case CursorLockMode.Locked:
            GUILayout.Label ("Cursor is locked");
            if (GUILayout.Button ("Unlock cursor"))
                wantedMode = CursorLockMode.None;
            if (GUILayout.Button ("Confine cursor"))
                wantedMode = CursorLockMode.Confined;
            break;
        }
        GUILayout.EndVertical ();
        SetCursorState ();
    }
}

错误出现在线路上:

GUILayout.BeginVertical ();

我得到的错误是:

NullReferenceException: Object reference not set to an instance of an object
UnityEngine.GUILayoutUtility.BeginLayoutGroup (UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options, System.Type layoutType) (at C:/buildslave/unity/build/Runtime/IMGUI/Managed/GUILayoutUtility.cs:252)
UnityEngine.GUILayout.BeginVertical (UnityEngine.GUIContent content, UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Runtime/IMGUI/Managed/GUILayout.cs:308)
UnityEngine.GUILayout.BeginVertical (UnityEngine.GUILayoutOption[] options) (at C:/buildslave/unity/build/Runtime/IMGUI/Managed/GUILayout.cs:296)
CameraScript.OnGUI () (at Assets/My Scripts/CameraScript.cs:135)
CameraScript.Start () (at Assets/My Scripts/CameraScript.cs:43)

在"Camera Script"区域的"Main Camera Inspector"中,"Target look At"设置为ThirdPersonController。

在统一中,为什么获取错误NullReferenceException:对象引用未设置为CameraScript上对象的实

您收到此错误是因为您正在从Start()函数调用OnGUI()函数。不要那样做。

void Start()
{
    Distance = Mathf.Clamp(Distance, DistanceMin, DistanceMax);
    startingDistance = Distance;
    Reset();
    SetCursorState();
    OnGUI();///--------------------->DON'T DO THIS!
}

OnGUI()函数是Unity GUI回调函数,由Unity自动调用以创建GUI。从Start()函数中删除这行代码,问题就应该解决了。如果您要从Start()函数启动任何内容,请创建一个新函数来执行此操作。

该新函数应而不是命名为OnGUI(),并且不得包含任何GUI函数,如GUILayout.BeginVertical();GUILayout.EndVertical();GUILayout.Button("Confine cursor")

注意

OnGUI()功能不应在您的游戏中使用。您应该将其用作测试工具来测试游戏中的功能,仅在编辑器。当在实际游戏中使用时,它是非常昂贵和缓慢的。你可以在这里了解你应该使用的新Unity UI

当堆栈跟踪显示您拥有源代码时,请在调试器中逐步检查它,以找出什么是null。很可能您没有正确配置GUILLayout。

显然,不管怎样,OnGUI和GUILLayout都是"遗留"代码,因此无论更新的替代方案是什么,都可能值得研究