Unity - 我的 GameOverManager 中的 NullReferenceException
Unity - NullReferenceException in my GameOverManager
我正在尝试将我的 "PlayerHealth" 脚本加载到我的 "GameOverManager" 以从 PlayerHealth-Script 检查我的当前健康状况。
如果当前生命值是“0”——我想触发一个动画。
问题是,Unity 给我一个错误消息:
"NullReferenceException: 对象引用未设置到对象的实例
GameOverManager.Update ()(位于 Assets/GameOverManager.cs:32)"
这是我的 GameOverManager 的一段代码:
public class GameOverManager : MonoBehaviour {
public PlayerHealth playerHealthScript;
public float restartDelay = 5f;
Animator anim;
float restartTimer;
private void Awake()
{
anim = GetComponent<Animator>();
}
private void Update()
{
playerHealthScript = GetComponent<PlayerHealth>();
if (playerHealthScript.currentHealth <= 0) {
anim.SetTrigger("GamerOver");
restartTimer += Time.deltaTime;
if (restartTimer >= restartDelay) {
SceneManager.LoadScene(2);
}
}
}
}
以下行触发错误:
if (playerHealthScript.currentHealth <= 0)
这是层次结构 - FPSController 持有 "PlayerHealth" - HUDCanvas 持有“GameOverManager:
以下是检查员:
这里是"PlayerHealth"的代码:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;
public class PlayerHealth : MonoBehaviour
{
public int startingHealth = 100; // The amount of health the player starts the game with.
public int currentHealth; // The current health the player has.
public Slider healthSlider; // Reference to the UI's health bar.
public Image damageImage; // Reference to an image to flash on the screen on being hurt.
public AudioClip deathClip; // The audio clip to play when the player dies.
public float flashSpeed = 5f; // The speed the damageImage will fade at.
public Color flashColour = new Color(1f, 0f, 0f, 0.1f); // The colour the damageImage is set to, to flash.
public float restartDelay = 5f;
//Animator anim; // Reference to the Animator component.
public AudioSource playerAudio; // Reference to the AudioSource component.
// PlayerMovement playerMovement; // Reference to the player's movement.
// PlayerShooting playerShooting; // Reference to the PlayerShooting script.
bool isDead; // Whether the player is dead.
bool damaged; // True when the player gets damaged.
void Awake()
{
// Setting up the references.
// anim = GetComponent<Animator>();
// playerAudio = GetComponent<AudioSource>();
// playerMovement = GetComponent<PlayerMovement>();
// playerShooting = GetComponentInChildren<PlayerShooting>();
// Set the initial health of the player.
currentHealth = startingHealth;
}
void Update()
{
// If the player has just been damaged...
if (damaged)
{
// ... set the colour of the damageImage to the flash colour.
damageImage.color = flashColour;
}
// Otherwise...
else
{
// ... transition the colour back to clear.
damageImage.color = Color.Lerp(damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
}
// Reset the damaged flag.
damaged = false;
}
public void TakeDamage(int amount)
{
// Set the damaged flag so the screen will flash.
damaged = true;
// Reduce the current health by the damage amount.
currentHealth -= amount;
playerAudio.Play();
Debug.Log("PLayer Health: " + currentHealth);
// Set the health bar's value to the current health.
healthSlider.value = currentHealth;
// Play the hurt sound
playerAudio.Play();
// If the player has lost all it's health and the death flag hasn't been set yet...
if (currentHealth <= 0 && !isDead)
{
// ... it should die.
Death();
}
}
void Death()
{
// Set the death flag so this function won't be called again.
isDead = true;
Debug.Log("In der Death Funktion");
首先,你不需要,或者更好的是,你不应该,在 Update
中使用 GetComponent
,这是一个非常慢的方法,它会影响很多性能。
因此,将您的代码更改为:
public class GameOverManager : MonoBehaviour {
public PlayerHealth playerHealthScript;
public float restartDelay = 5f;
private Animator anim;
private float restartTimer;
private void Awake() {
anim = GetComponent<Animator>();
//No need for GetComponent<PlayerHealth>() if you assign it in the Inspector
//playerHealthScript = GetComponent<PlayerHealth>();
}
private void Update() {
if (playerHealthScript.currentHealth <= 0) {
anim.SetTrigger("GamerOver");
restartTimer += Time.deltaTime;
if (restartTimer >= restartDelay) {
SceneManager.LoadScene(2);
}
}
}
}
此外,您的错误发生很可能是因为在 Inspector 中您将包含 PlayerHealth
脚本的游戏对象分配给了 playerHealthScript
变量。但是,由于您尝试在 Update
中再次获取脚本组件,但这次是从具有 GameOverManager
脚本的游戏对象(我假设它没有 PlayerHealth
脚本) ,您将获得 NullReference,因为在此游戏对象上找不到该脚本。
因此,正如您在我的代码中注释掉的两行中看到的那样,您实际上不需要从脚本中获取该组件,只需通过 Inspector 分配它就可以了。
我正在尝试将我的 "PlayerHealth" 脚本加载到我的 "GameOverManager" 以从 PlayerHealth-Script 检查我的当前健康状况。
如果当前生命值是“0”——我想触发一个动画。
问题是,Unity 给我一个错误消息:
"NullReferenceException: 对象引用未设置到对象的实例 GameOverManager.Update ()(位于 Assets/GameOverManager.cs:32)"
这是我的 GameOverManager 的一段代码:
public class GameOverManager : MonoBehaviour {
public PlayerHealth playerHealthScript;
public float restartDelay = 5f;
Animator anim;
float restartTimer;
private void Awake()
{
anim = GetComponent<Animator>();
}
private void Update()
{
playerHealthScript = GetComponent<PlayerHealth>();
if (playerHealthScript.currentHealth <= 0) {
anim.SetTrigger("GamerOver");
restartTimer += Time.deltaTime;
if (restartTimer >= restartDelay) {
SceneManager.LoadScene(2);
}
}
}
}
以下行触发错误:
if (playerHealthScript.currentHealth <= 0)
这是层次结构 - FPSController 持有 "PlayerHealth" - HUDCanvas 持有“GameOverManager:
以下是检查员:
这里是"PlayerHealth"的代码:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;
public class PlayerHealth : MonoBehaviour
{
public int startingHealth = 100; // The amount of health the player starts the game with.
public int currentHealth; // The current health the player has.
public Slider healthSlider; // Reference to the UI's health bar.
public Image damageImage; // Reference to an image to flash on the screen on being hurt.
public AudioClip deathClip; // The audio clip to play when the player dies.
public float flashSpeed = 5f; // The speed the damageImage will fade at.
public Color flashColour = new Color(1f, 0f, 0f, 0.1f); // The colour the damageImage is set to, to flash.
public float restartDelay = 5f;
//Animator anim; // Reference to the Animator component.
public AudioSource playerAudio; // Reference to the AudioSource component.
// PlayerMovement playerMovement; // Reference to the player's movement.
// PlayerShooting playerShooting; // Reference to the PlayerShooting script.
bool isDead; // Whether the player is dead.
bool damaged; // True when the player gets damaged.
void Awake()
{
// Setting up the references.
// anim = GetComponent<Animator>();
// playerAudio = GetComponent<AudioSource>();
// playerMovement = GetComponent<PlayerMovement>();
// playerShooting = GetComponentInChildren<PlayerShooting>();
// Set the initial health of the player.
currentHealth = startingHealth;
}
void Update()
{
// If the player has just been damaged...
if (damaged)
{
// ... set the colour of the damageImage to the flash colour.
damageImage.color = flashColour;
}
// Otherwise...
else
{
// ... transition the colour back to clear.
damageImage.color = Color.Lerp(damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
}
// Reset the damaged flag.
damaged = false;
}
public void TakeDamage(int amount)
{
// Set the damaged flag so the screen will flash.
damaged = true;
// Reduce the current health by the damage amount.
currentHealth -= amount;
playerAudio.Play();
Debug.Log("PLayer Health: " + currentHealth);
// Set the health bar's value to the current health.
healthSlider.value = currentHealth;
// Play the hurt sound
playerAudio.Play();
// If the player has lost all it's health and the death flag hasn't been set yet...
if (currentHealth <= 0 && !isDead)
{
// ... it should die.
Death();
}
}
void Death()
{
// Set the death flag so this function won't be called again.
isDead = true;
Debug.Log("In der Death Funktion");
首先,你不需要,或者更好的是,你不应该,在 Update
中使用 GetComponent
,这是一个非常慢的方法,它会影响很多性能。
因此,将您的代码更改为:
public class GameOverManager : MonoBehaviour {
public PlayerHealth playerHealthScript;
public float restartDelay = 5f;
private Animator anim;
private float restartTimer;
private void Awake() {
anim = GetComponent<Animator>();
//No need for GetComponent<PlayerHealth>() if you assign it in the Inspector
//playerHealthScript = GetComponent<PlayerHealth>();
}
private void Update() {
if (playerHealthScript.currentHealth <= 0) {
anim.SetTrigger("GamerOver");
restartTimer += Time.deltaTime;
if (restartTimer >= restartDelay) {
SceneManager.LoadScene(2);
}
}
}
}
此外,您的错误发生很可能是因为在 Inspector 中您将包含 PlayerHealth
脚本的游戏对象分配给了 playerHealthScript
变量。但是,由于您尝试在 Update
中再次获取脚本组件,但这次是从具有 GameOverManager
脚本的游戏对象(我假设它没有 PlayerHealth
脚本) ,您将获得 NullReference,因为在此游戏对象上找不到该脚本。
因此,正如您在我的代码中注释掉的两行中看到的那样,您实际上不需要从脚本中获取该组件,只需通过 Inspector 分配它就可以了。