gpt4 book ai didi

c# - 游戏重启后游戏对象不会加载

转载 作者:太空宇宙 更新时间:2023-11-03 19:40:50 26 4
gpt4 key购买 nike

我正在制作一个迷宫游戏,如果游戏重新启动,需要收集完成它的 key 不会再次出现,我收到以下错误;

MissingReferenceException: The object of type 'MazeDirectives' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.

我只是禁用 MazeKey 对象,而不是破坏它,有人可以帮忙吗?下面是我的代码;

迷宫 key .cs

using UnityEngine;
using System.Collections;

public class MazeKey : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{

transform.parent.SendMessage("OnKeyFound", SendMessageOptions.DontRequireReceiver);
gameObject.SetActive(false);
}
}

迷宫指令.cs

MazeGoal mazeGoal;
MazeKey mazeKey;

void StartDirectives()
{
mazeGoal = Instantiate(mazeGoalPrefab, MazeGenerator.instance.mazeGoalPosition, Quaternion.identity) as MazeGoal;
mazeGoal.transform.SetParent(transform);

mazeKeyPositions = MazeGenerator.instance.GetRandomFloorPositions(keysToFind);

for (int i = 0; i < mazeKeyPositions.Count; i++)
{
MazeKey mazeKey = Instantiate(mazeKeyPrefab, mazeKeyPositions[i], Quaternion.identity) as MazeKey;
mazeKey.transform.SetParent(transform);

}
}

要重新启动游戏,我使用下面的代码;

void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
gameObject.SetActive(true);
}
}

迷宫目标.cs

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

public class MazeGoal : MonoBehaviour
{

public Sprite closedGoalSprite;
public Sprite openedGoalSprite;

void Start()
{

GetComponentInChildren<SpriteRenderer>().sprite = closedGoalSprite;



}

public void OpenGoal()
{
GetComponentInChildren<SpriteRenderer>().sprite = openedGoalSprite;
}

void OnTriggerEnter2D()
{
transform.parent.SendMessage("OnGoalReached", SendMessageOptions.DontRequireReceiver);
}

最佳答案

解释

您得到的异常不是关于 MazeKey 对象,而是关于 MazeDirectives 组件。

很遗憾,您在评论中看到了最重要的信息:

private void Awake() 
{
MazeGenerator.OnMazeReady += StartDirectives;
}

所以 OnMazeReady 似乎是 static 并且没有实例化,因此在加载新场景时它不会被销毁,而是在新场景中保持完整膨胀!

当你打电话时

MazeGenerator.OnMazeReady += StartDirectives;

您将对 MazeDirectives 实例的 StartDirectives 方法的调用添加为该 static 事件的监听器。

现在,当您重新加载场景时,所有 GameObject 及其组件实例都会被销毁

=> MazeGenerator 的实例也是如此……但是 static 事件OnMazeReady没有被摧毁!

所以在下一个 Awake 调用之后,您现在有两个监听器

  • 来自“第二个”/新加载场景的那个
  • 仍然是您第一次添加的“旧”

但是由于您添加的第一个监听器的 MazeDirectives 实例在重新加载场景并生成新实例时被销毁,因此您会遇到该异常

MissingReferenceException: The object of type 'MazeDirectives' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

当该方法尝试访问被销毁实例的 transform 值时。


解决方案 1a

所以你应该在销毁实例时移除监听器

private void OnDestroy()
{
MazeGenerator.OnMazeReady -= StartDirectives;
}

解决方案 1b

或者一次只用一个监听器覆盖它

private void Awake() 
{
MazeGenerator.OnMazeReady = StartDirectives;
}

这第二种方法显然只有在没有其他实例或类监听该事件时才有用。问题是使用事件有多大意义?如果不需要,我无论如何都会删除它,只是为了确定

private void OnDestroy()
{
MazeGenerator.OnMazeReady = null;
}

解决方案2

我更喜欢这个解决方案。

不要将 MazeGenerator.OnMazeReady 设为静态。因为无论如何我看到你正在使用单例模式,例如在

 MazeGenerator.instance.mazeGoalPosition

您可以改为仅使 OnMazeReady 成为非静态的,然后以相同的方式使用它:

private void Awake()
{
MazeGenerator.instance.OnMazeReady += startDirectives;
}

因此它将与 MazeGenerator 实例一起销毁。


一般说明

我会总是尽快删除我添加的所有监听器,以避免您遇到的问题。

您可以另外删除它,例如已经在 StartDirectives 中,以确保即使同一场景“意外”调用 OnMazeReady 两次,该方法也只执行一次。

提示:我说 另外 因为它总是保存/可能删除一个监听器,即使它之前没有添加,你应该总是把它留在 OnDestroy以防在对象被销毁之前从未调用 StartDirectives

关于c# - 游戏重启后游戏对象不会加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53712922/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com