实例化Zombie时,Null Reference Exception不一致

时间:2017-06-19 18:33:38

标签: c# unity3d nullreferenceexception

我正在使用Unity版本5.6.1f1,如果有帮助的话。

在我实例化Zombie的随机时刻,它导致NullReferenceException指向ThirdPersonController.cs。但是,这个GameObject和脚本是由Unity构建的标准字符包资产。我所做的只是通过脚本附加,Zombie.target附加到Player.transform有些僵尸按预期追逐Player,但有些则没有。

Unity论坛上出现此错误,找到的唯一解决方案是删除指向ThirdPersonCharacter.CheckGroundStatus()的FSM,或者未分配动画师。

在图片中,设置为“无”的目标始终以玩游戏为目标。 Zombie Prefab Zombie pic extended

错误:

 NullReferenceException: Object reference not set to an instance of an object
    UnityStandardAssets.Characters.ThirdPerson.ThirdPersonCharacter.CheckGroundStatus () (at Assets/Standard Assets/Characters/ThirdPersonCharacter/Scripts/ThirdPersonCharacter.cs:215)
    UnityStandardAssets.Characters.ThirdPerson.ThirdPersonCharacter.Move (Vector3 move, Boolean crouch, Boolean jump) (at Assets/Standard Assets/Characters/ThirdPersonCharacter/Scripts/ThirdPersonCharacter.cs:54)
    UnityStandardAssets.Characters.ThirdPerson.AICharacterControl.Update () (at Assets/Standard Assets/Characters/ThirdPersonCharacter/Scripts/AICharacterControl.cs:39)

ThirdPersonCharacter,相关部分:

if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
{
    m_GroundNormal = hitInfo.normal;
    m_IsGrounded = true;
    m_Animator.applyRootMotion = true; //ERROR HERE
}

完整脚本(Unity提供的资产):

using UnityEngine;

namespace UnityStandardAssets.Characters.ThirdPerson
{
    [RequireComponent(typeof(Rigidbody))]
    [RequireComponent(typeof(CapsuleCollider))]
    [RequireComponent(typeof(Animator))]
    public class ThirdPersonCharacter : MonoBehaviour
    {
        [SerializeField] float m_MovingTurnSpeed = 360;
        [SerializeField] float m_StationaryTurnSpeed = 180;
        [SerializeField] float m_JumpPower = 12f;
        [Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
        [SerializeField] float m_RunCycleLegOffset = 0.2f; //specific to the character in sample assets, will need to be modified to work with others
        [SerializeField] float m_MoveSpeedMultiplier = 1f;
        [SerializeField] float m_AnimSpeedMultiplier = 1f;
        [SerializeField] float m_GroundCheckDistance = 0.1f;

        Rigidbody m_Rigidbody;
        Animator m_Animator;
        bool m_IsGrounded;
        float m_OrigGroundCheckDistance;
        const float k_Half = 0.5f;
        float m_TurnAmount;
        float m_ForwardAmount;
        Vector3 m_GroundNormal;
        float m_CapsuleHeight;
        Vector3 m_CapsuleCenter;
        CapsuleCollider m_Capsule;
        bool m_Crouching;


        void Start()
        {
            m_Animator = GetComponent<Animator>();
            m_Rigidbody = GetComponent<Rigidbody>();
            m_Capsule = GetComponent<CapsuleCollider>();
            m_CapsuleHeight = m_Capsule.height;
            m_CapsuleCenter = m_Capsule.center;

            m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
            m_OrigGroundCheckDistance = m_GroundCheckDistance;


        void CheckGroundStatus()
        {
            RaycastHit hitInfo;
#if UNITY_EDITOR
            // helper to visualise the ground check ray in the scene view
            Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
#endif
            // 0.1f is a small offset to start the ray from inside the character
            // it is also good to note that the transform position in the sample assets is at the base of the character
            if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
            {
                m_GroundNormal = hitInfo.normal;
                m_IsGrounded = true;
                m_Animator.applyRootMotion = true; //ERROR HERE
            }
            else
            {
                m_IsGrounded = false;
                m_GroundNormal = Vector3.up;
                m_Animator.applyRootMotion = false;
            }
        }
    }
}

AICharacterControl:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace UnityStandardAssets.Characters.ThirdPerson
{
    [RequireComponent(typeof (UnityEngine.AI.NavMeshAgent))]
    [RequireComponent(typeof (ThirdPersonCharacter))]
    public class AICharacterControl : MonoBehaviour
    {
        public UnityEngine.AI.NavMeshAgent agent { get; private set; }             // the navmesh agent required for the path finding
        public ThirdPersonCharacter character { get; private set; } // the character we are controlling
        public Transform target;                                // target to aim for
        private GameObject player; 

        private void Start()
        {
            // get the components on the object we need ( should not be null due to require component so no need to check )
            agent = GetComponentInChildren<UnityEngine.AI.NavMeshAgent>();
            character = GetComponent<ThirdPersonCharacter>();

            player = GameObject.FindGameObjectWithTag("Player");
            target = player.transform;

            agent.updateRotation = false;
            agent.updatePosition = true;
        }


        private void Update()
        {
            if (target != null)
                agent.SetDestination(target.position);

            if (agent.remainingDistance > agent.stoppingDistance)
                character.Move(agent.desiredVelocity, false, false);
            else
                character.Move(Vector3.zero, false, false);
        }


        public void SetTarget(Transform target)
        {
            this.target = target;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

尝试在ThirdPersonCharacter.cs中将“void Start”替换为“void Awake”。

当将ThirdPersonCharacter.cs与另一个AI行为脚本一起使用时,我遇到了一个非常类似的问题:在编辑器中工作得很好,但是一旦我构建它,我就得到了null引用异常,无论是在构建还是在编辑。我无法在网上找到任何东西,空引用异常错误很常见,但大多数情况下你通过修复一个变量解决它们...我是c#的相对新手,但我认为这不是一般问题使用脚本,但调用/初始化变量的方式。无论如何,这对我有用。

https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html