(Unity C#) NullReferenceException ТОЛЬКО вне функции Start ()

Я получаю сообщение об ошибке:

NullReferenceException: Object reference not set to an instance of an object

что подводит меня к строке:

if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, enemy.groundCheckDistance))

Я провел некоторое тестирование и обнаружил, что враг фактически был установлен для экземпляра этого объекта, потому что я печатал значение для Враг.groundCheckDistance при каждом обновлении, и он каждый раз успешно печатал правильное значение из объекта враг. Я даже изменил его в инспекторе, и он получил правильное значение. Позже я обнаружил, что все объекты, которые я установил в методе Начинать(), превращаются в нулевое значение только снаружи метода Начинать().(Под этим я подразумеваю, что Animator, Rigidbody, Capsule Collider и т. д. Становятся нулевыми) Я на 100% уверен, что к этому игровому объекту привязаны аниматор, коллайдер капсулы, твердое тело и враг. Однако я создаю их на Бодрствующий() в другом классе. Может быть, поэтому я получаю сообщение об ошибке? Если это так, как мне это исправить?

Это сценарий, в который я добавляю компоненты на Бодрствующий(). Когда я запускаю игру, я вижу, что они успешно добавлены.

using UnityEngine;
using UnityEngine.AI;

namespace MGCO.Characters.EnemyScripts
{
    //USED TO CONSTRUCT THE COMPONENTS ON AN ENEMY AT RUNTIME
    public class EnemyComponents : MonoBehaviour
    {
        //INITIALIZE ENEMY OBJECT
        Enemy enemy;

        void Awake()
        {
            enemy = GetComponent<Enemy>();

            //MAKE SURE ENEMY IS NOT HUMANOID
            if (!enemy.isHumanoid)
            {
                //CHECK TO SEE IF MESH FILTER ALREADY EXISTS
                if (!GetComponent<MeshFilter>())
                {
                    //INITIALIZE "MeshFilter"
                    MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();

                    //SET MESH OF MESHFILTER
                    meshFilter.mesh = enemy.enemyMesh;
                }

                //CHECK TO SEE IF MESH RENDERER ALREADY EXISTS
                if (!GetComponent<MeshRenderer>())
                {
                    //INITIALIZE "MeshRenderer"
                    MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();

                    //SET MESH MATERIAL
                    meshRenderer.material = enemy.meshMaterial;
                }
            }
            //MAKE SURE ENEMY IS NOT HUMANOID
            else
            {
                //CHECK TO SEE IF ANIMATOR ALREADY EXISTS
                if (!GetComponent<Animator>())
                {
                    //INITIALIZE "RuntimeAnimatorController"
                    Animator animator = gameObject.AddComponent<Animator>();

                    //SET RUNTIMEANIMATORCONTROLLER
                    animator.runtimeAnimatorController = enemy.runtimeAnimatorController;

                    //SET AVATAR
                    animator.avatar = enemy.avatar;

                    //SET ROOT ANIMATION BOOL
                    animator.applyRootMotion = enemy.applyRootMotion;
                }
            }

            //CHECK TO SEE IF RIGIDBODY ALREADY EXISTS
            if (!GetComponent<Rigidbody>())
            {
                //INITIALIZE "Rigidbody"
                Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();

                //SET MASS
                enemyRigidbody.mass = enemy.mass;

                //SET DRAG
                enemyRigidbody.drag = enemy.drag;

                //SET ANGULAR DRAG
                enemyRigidbody.angularDrag = enemy.angularDrag;

                //SET USE GRAVITY
                enemyRigidbody.useGravity = enemy.useGravity;
            }

            //CHECK TO SEE IF NAVMESHAGENT ALREADY EXISTS
            if (!GetComponent<NavMeshAgent>())
            {
                //INITIALIZE "NavMeshAgent"
                NavMeshAgent navMeshAgent = gameObject.AddComponent<NavMeshAgent>();

                //SET NAVMESH SPEED
                navMeshAgent.speed = enemy.speed;

                //SET BASE OFFSET
                navMeshAgent.baseOffset = enemy.baseOffset;

                //SET ANGULAR SPEED (HOW FAST ENEMY TURNS CORNERS)
                navMeshAgent.angularSpeed = enemy.angularSpeed;

                //SET ACCELERATION
                navMeshAgent.acceleration = enemy.acceleration;

                //SET STOPPING DISTANCE
                navMeshAgent.stoppingDistance = enemy.stoppingDistance;

                //SET OBSTACLE AVOIDANCE RADIUS
                navMeshAgent.radius = enemy.navmeshRadius;

                //SET OBSTACLE AVOIDANCE HEIGHT
                navMeshAgent.radius = enemy.navmeshHeight;
            }

            //CHECK TO SEE IF COLLIDER ALREADY EXISTS
            if (!GetComponent<CapsuleCollider>())
            {
                //INITIALIZE "CapsuleCollider"
                CapsuleCollider capsuleCollider = gameObject.AddComponent<CapsuleCollider>();

                //SET CENTER
                capsuleCollider.center = enemy.center;

                //SET COLLIDER RADIUS
                capsuleCollider.radius = enemy.colliderRadius;

                //SET COLLIDER HEIGHT
                capsuleCollider.height = enemy.colliderHeight;
            }
        }
    }
}

Это сценарий, который получает ошибку:

using UnityEngine;

namespace MGCO.Characters.EnemyScripts
{
    public class EnemyAnimation : MonoBehaviour
    {
        //REFERENCE GAMEOBJECTS
        Enemy enemy;
        Animator animator;
        Rigidbody enemyRigidbody;
        CapsuleCollider capsuleCollider;


        //INITIALIZE VARS
        Vector3 groundNormal;
        Vector3 capsuleCenter;

        private bool isCrouching;
        private bool isGrounded;

        private float originalGroundCheckDistance;
        private float turnAmount;
        private float forwardAmount;
        private float capsuleHeight;

        //VALUE FOR HALF (NEVER CHANGES)
        const float half = 0.5f;

        //RUNS ON START
        void Start()
        {
            enemy = GetComponent<Enemy>();

            animator = GetComponent<Animator>();
            enemyRigidbody = GetComponent<Rigidbody>();
            capsuleCollider = GetComponent<CapsuleCollider>();
            capsuleHeight = capsuleCollider.height;
            capsuleCenter = capsuleCollider.center;

            //FREEZE RIGIDBODY ROTATION
            enemyRigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
            //SET LOCAL VARIABLE
            originalGroundCheckDistance = enemy.groundCheckDistance;
        }

        ...

        //CHECKS POSITION OF GROUND BENEATH PLAYER
        void CheckGroundStatus()
        {
            //INITIALIZE RAYCASTHIT
            RaycastHit hitInfo;

            //IF RAYCASTS DOWN TO "GroundCheckDistance" VARIABLE
            if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, enemy.groundCheckDistance))
            {
                //SET GROUNDNORMAL TO THE SURFACE OF THE RAYCASTHIT
                groundNormal = hitInfo.normal;
                //SET JUMPING FALSE
                isGrounded = true;
                //ANIMATOR APPLY ROOT MOTION
                animator.applyRootMotion = true;
            }
            else
            {
                //SET JUMPING TO TRUE
                isGrounded = false;
                //SET GROUNDNORMAL TO GO UP
                groundNormal = Vector3.up;
                //ANIMATOR DO NOT APPLY ROOT MOTION
                animator.applyRootMotion = false;
            }
        }
    }
}

И спасибо за помощь :)

Возможный дубликат Что такое исключение NullReferenceException и как его исправить?

BugFinder 01.05.2018 15:55

Ошибка очевидна - почему аниматор должен существовать вне этой функции запуска? вы никогда не устанавливаете его ни на что, что остается вне его

BugFinder 01.05.2018 15:59

Используйте отладчик

Ben 01.05.2018 16:01

@BugFinder Где еще я мог бы его установить?

Michael Gallo 01.05.2018 16:05

Это не его настройка, проблема в ее объеме .. вы объявили и установили переменную в start, так что это единственное место, где она существовала, когда вы покидаете start, ее больше нет

BugFinder 01.05.2018 16:06

Не могли бы вы добавить снимок экрана врага во время выполнения после создания врага? (Я имею в виду инспектора.)

Gunnar B. 01.05.2018 17:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
602
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
//REFERENCE GAMEOBJECTS  
Enemy enemy;  
Animator animator;  
Rigidbody enemyRigidbody;  
CapsuleCollider capsuleCollider;

Здесь вы объявляете свои ссылки, но никуда их не ПРИЗНАВАЕТЕ.

Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();

Здесь вы добавляете компонент твердого тела, и он возвращает ссылку на себя. Однако вы назначили ссылку на РАЗНУЮ переменную с именем ownRigidbody вместо той, которую вы объявили выше.

Несмотря на то, что имена переменных схожи, объявление переменной в пределах меньшей области действия / объявления (одна в классе, другая в методе) создает СОВЕРШЕННО НОВУЮ переменную с тем же именем, но ИСПОЛЬЗУЕТСЯ ТОЛЬКО В САМОМ МЕТОДЕ.

Вы хотите:

enemyRigidbody = gameObject.AddComponent<Rigidbody>();

который является ссылкой на Rigidbody, который вы указали выше.

Другие вопросы по теме

Похожие вопросы

WPF Microsoft DataGrid имеет странное поведение «IsReadOnly». Почему?
Как вернуть объекты, обновив несколько свойств в запросе linq, который использует JOIN
Страница входа в систему параметризованного запроса SQL
Создание документа Word (docx) с использованием данных из файла XML / Преобразование XML в документ Word на основе шаблона
Mvc Razor Список и редактирование в одном представлении с кнопкой отправки для каждого элемента списка
Странное воспроизводимое поведение при удалении - символы удаляются некорректно
Реализация интерфейса C# .NET на нескольких уровнях
Возможно ли (невозможно) использовать настраиваемый элемент управления WPF так же, как его базовый класс (в данном случае StackPanel) в XAML?
Регулярное выражение для соответствия сложному предложению Where для таблицы Certian
Прекращает ли установка IsAccessible значение false при нажатии кнопки или пропускает кодирование?