C# 销毁游戏对象,但也将其保存在变量中供以后使用
我正在创建一个程序生成的游戏,它将永远生成新的“地形”,为此,我的游戏开始延迟,因此我尝试卸载一些块,稍后我希望再次加载(如果玩家再次回到特定位置) 这是我的卸货代码:C# 销毁游戏对象,但也将其保存在变量中供以后使用,c#,unity3d,C#,Unity3d,我正在创建一个程序生成的游戏,它将永远生成新的“地形”,为此,我的游戏开始延迟,因此我尝试卸载一些块,稍后我希望再次加载(如果玩家再次回到特定位置) 这是我的卸货代码: GameObject _tmp = MapGeneration.Map[Mathf.Abs(y)][x]; DestroyImmediate(MapGeneration.Map[Mathf.Abs(y)][x].gameObject); MapGeneration.Map[Mathf.Abs(y)][x] = _tmp; 稍后
GameObject _tmp = MapGeneration.Map[Mathf.Abs(y)][x];
DestroyImmediate(MapGeneration.Map[Mathf.Abs(y)][x].gameObject);
MapGeneration.Map[Mathf.Abs(y)][x] = _tmp;
稍后,当我再次尝试实例化该块时:
Instantiate(MapGeneration.Map[Mathf.Abs(y)][x].gameObject, new Vector3(x, y, 0), Quaternion.identity);
我得到这个错误:
MissingReferenceException:类型为“GameObject”的对象已被销毁,但您仍在尝试访问它。
您的脚本应该检查它是否为null,或者不应该销毁对象。
UnityEngine.Object.Internal_实例化单(UnityEngine.Object数据,向量3位置,四元数)
UnityEngine.Object.Instantiate(UnityEngine.Object原始、矢量3位置、四元数旋转)
Update()(位于Assets/Scripts/MapGeneration.cs:53)
您不希望销毁对象,而是希望禁用它,这样它就不会占用处理资源。使用
Destroy()
请查看SetActive()
它本质上相当于inspector面板中对象/组件左上角的小勾选框的代码。处于非活动状态时,引擎将“跳过”它,但这也包括Find()
和GetComponent()
等功能,因此在将游戏对象设置为非活动状态之前,请确保已存储对其的引用,否则您将无法再次“发现”它。您不想破坏该对象,您希望禁用它,以便它不会占用处理资源。使用Destroy()
请查看SetActive()
它本质上相当于inspector面板中对象/组件左上角的小勾选框的代码。当游戏对象处于非活动状态时,引擎将“跳过”它,但这也包括Find()
和GetComponent()
等功能,因此在将其设置为非活动状态之前,请确保已存储对该游戏对象的引用,否则您将无法再次“发现”它。销毁任何游戏对象后,您将无法访问该游戏对象
要解决此问题,必须为对象创建预制件,以下步骤说明如何使用预制件创建和销毁一个对象:
1-为您的一个对象创建一个预置。(例如“terrain1”对象)
2-在脚本(类级别)中,定义以下变量,如下所示:
public GameObject terrain1Prefab;
GameObject terrain1Instance;
terrain1Instance = Instantiate(terrain1Prefab, new Vector3(x, y, 0), Quaternion.identity);
Destroy(terrain1Instance);
3-将公共变量“terrain1prefable”链接到您创建的预置
4-在您的函数中,创建“TerraIn1Prefact”的实例,并按如下方式存储其实例:
public GameObject terrain1Prefab;
GameObject terrain1Instance;
terrain1Instance = Instantiate(terrain1Prefab, new Vector3(x, y, 0), Quaternion.identity);
Destroy(terrain1Instance);
5-现在,您可以按如下方式销毁实例:
public GameObject terrain1Prefab;
GameObject terrain1Instance;
terrain1Instance = Instantiate(terrain1Prefab, new Vector3(x, y, 0), Quaternion.identity);
Destroy(terrain1Instance);
销毁任何游戏对象后,您无法访问它
要解决此问题,必须为对象创建预制件,以下步骤说明如何使用预制件创建和销毁一个对象:
1-为您的一个对象创建一个预置。(例如“terrain1”对象)
2-在脚本(类级别)中,定义以下变量,如下所示:
public GameObject terrain1Prefab;
GameObject terrain1Instance;
terrain1Instance = Instantiate(terrain1Prefab, new Vector3(x, y, 0), Quaternion.identity);
Destroy(terrain1Instance);
3-将公共变量“terrain1prefable”链接到您创建的预置
4-在您的函数中,创建“TerraIn1Prefact”的实例,并按如下方式存储其实例:
public GameObject terrain1Prefab;
GameObject terrain1Instance;
terrain1Instance = Instantiate(terrain1Prefab, new Vector3(x, y, 0), Quaternion.identity);
Destroy(terrain1Instance);
5-现在,您可以按如下方式销毁实例:
public GameObject terrain1Prefab;
GameObject terrain1Instance;
terrain1Instance = Instantiate(terrain1Prefab, new Vector3(x, y, 0), Quaternion.identity);
Destroy(terrain1Instance);
等待什么?你知道C#是通过引用传递的是吗?所以,如果你将一个对象的实例传递给一个变量,然后销毁该实例,那么这个变量也将指向空?这就是你们的错误是的,我知道,这就是为什么我来找你们寻求建议。等等。。什么?你知道C#是通过引用传递的是吗?所以,如果你将一个对象的实例传递给一个变量,然后销毁该实例,那么这个变量也将指向空?因此你的错误是的,我知道,这就是为什么我来找你们寻求建议。当加载的非活动块数量达到一个很高的数字时,你仍然会遇到延迟问题。。。如果您试图创建无限地形,则此方法将导致跟踪过程中出现问题。。。我会在需要的时候从文件中保存和加载我的块,我的地形可以永远保持下去:)@Savlon Cool,我必须尝试一下!当加载的非活动块的数量达到一个很高的数字时,您仍然会遇到延迟问题。。。如果您试图创建无限地形,则此方法将导致跟踪过程中出现问题。。。我会在需要的时候从文件中保存和加载我的块,我的地形可以永远保持下去:)@Savlon Cool,我必须尝试一下!