Я получаю сообщение об ошибке:
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;
}
}
}
}
И спасибо за помощь :)
Ошибка очевидна - почему аниматор должен существовать вне этой функции запуска? вы никогда не устанавливаете его ни на что, что остается вне его
Используйте отладчик
@BugFinder Где еще я мог бы его установить?
Это не его настройка, проблема в ее объеме .. вы объявили и установили переменную в start, так что это единственное место, где она существовала, когда вы покидаете start, ее больше нет
Не могли бы вы добавить снимок экрана врага во время выполнения после создания врага? (Я имею в виду инспектора.)
//REFERENCE GAMEOBJECTS
Enemy enemy;
Animator animator;
Rigidbody enemyRigidbody;
CapsuleCollider capsuleCollider;
Здесь вы объявляете свои ссылки, но никуда их не ПРИЗНАВАЕТЕ.
Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();
Здесь вы добавляете компонент твердого тела, и он возвращает ссылку на себя. Однако вы назначили ссылку на РАЗНУЮ переменную с именем ownRigidbody вместо той, которую вы объявили выше.
Несмотря на то, что имена переменных схожи, объявление переменной в пределах меньшей области действия / объявления (одна в классе, другая в методе) создает СОВЕРШЕННО НОВУЮ переменную с тем же именем, но ИСПОЛЬЗУЕТСЯ ТОЛЬКО В САМОМ МЕТОДЕ.
Вы хотите:
enemyRigidbody = gameObject.AddComponent<Rigidbody>();
который является ссылкой на Rigidbody, который вы указали выше.
Возможный дубликат Что такое исключение NullReferenceException и как его исправить?