(Unity C#) NullReferenceException 仅在 Start() 函数之外
(Unity C#) NullReferenceException ONLY outside of the Start() function
我一直收到错误消息:
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))
我做了一些测试,发现 enemy 实际上设置为这个对象的实例,因为我打印了 [=46= 的值] 每次更新,它每次都成功地从 enemy 对象中打印出正确的值。我什至在检查器中更改了它,它检索到了正确的值。 后来我发现我在 Start() 方法中设置的所有对象都变为 null 仅在 Start() 方法。 (我的意思是 Animator、Rigidbody、Capsule Collider 等都变为 null) 我是100% 确定动画师、胶囊对撞机、刚体和敌人已附加到此游戏对象。但是,我在 Awake() 上以不同的 class 创建它们。这就是我收到错误的原因吗?如果是我该如何解决?
这是我在 Awake() 上添加组件的脚本。当我 运行 游戏时,我看到它们已成功添加。
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;
}
}
}
}
感谢您的帮助:)
//REFERENCE GAMEOBJECTS
Enemy enemy;
Animator animator;
Rigidbody enemyRigidbody;
CapsuleCollider capsuleCollider;
在这里你声明了你的引用,但你没有在任何地方分配它们。
Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();
在这里,您添加了刚体组件,它 returns 是对自身的引用。但是,您将引用分配给了一个名为 enemyRigidbody 的不同变量,而不是上面声明的变量。
即使变量名称相似,在较小的 scope/declaration space 中声明一个变量(一个在 class 中,另一个在一个方法中)会创建一个全新的变量名称相同,但只能在方法本身内使用。
你想要的是:
enemyRigidbody = gameObject.AddComponent<Rigidbody>();
这是对您在上面声明的 Rigidbody 的引用。
我一直收到错误消息:
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))
我做了一些测试,发现 enemy 实际上设置为这个对象的实例,因为我打印了 [=46= 的值] 每次更新,它每次都成功地从 enemy 对象中打印出正确的值。我什至在检查器中更改了它,它检索到了正确的值。 后来我发现我在 Start() 方法中设置的所有对象都变为 null 仅在 Start() 方法。 (我的意思是 Animator、Rigidbody、Capsule Collider 等都变为 null) 我是100% 确定动画师、胶囊对撞机、刚体和敌人已附加到此游戏对象。但是,我在 Awake() 上以不同的 class 创建它们。这就是我收到错误的原因吗?如果是我该如何解决?
这是我在 Awake() 上添加组件的脚本。当我 运行 游戏时,我看到它们已成功添加。
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;
}
}
}
}
感谢您的帮助:)
//REFERENCE GAMEOBJECTS
Enemy enemy;
Animator animator;
Rigidbody enemyRigidbody;
CapsuleCollider capsuleCollider;
在这里你声明了你的引用,但你没有在任何地方分配它们。
Rigidbody enemyRigidbody = gameObject.AddComponent<Rigidbody>();
在这里,您添加了刚体组件,它 returns 是对自身的引用。但是,您将引用分配给了一个名为 enemyRigidbody 的不同变量,而不是上面声明的变量。
即使变量名称相似,在较小的 scope/declaration space 中声明一个变量(一个在 class 中,另一个在一个方法中)会创建一个全新的变量名称相同,但只能在方法本身内使用。
你想要的是:
enemyRigidbody = gameObject.AddComponent<Rigidbody>();
这是对您在上面声明的 Rigidbody 的引用。