3

例子

在 Unity5 中,假设一个名为“SomeObject”的游戏对象被存储为一个预制件Assets/Resources/SomeObject.prefab,我知道我可以创建一个预制件的实例,如下所示:

GameObject prefab   = Resources.Load<GameObject>("SomeObject");
GameObject instance = GameObject.Instantiate(prefab);

一旦执行,instanceGameObject 将是原始“SomeObject”预制件的副本,并将被放置在名为“SomeObject(Clone)”的当前活动场景中。


据我了解,GameObject prefab代表实际的预制资产,对其所做的任何更改(设置名称、添加组件等)都会写入原始预制资产,即使在退出编辑器播放模式后这些更改仍然存在。

问题

  1. 由于所有游戏对象通常都存储在一个场景中,并且上面示例中的scene属性GameObject prefab似乎是 Unloaded/Invalid/Unnamed,我究竟应该将这个特殊的 GameObject 放在哪里?我似乎可以用它做所有我可以用普通游戏对象做的事情,除了在层次/场景视图中可见。

    它是有效地处于某种不确定状态,还是特殊的 PseudoScene?它似乎通过LoadSceneMode.Single场景变化持续存在,但不像DontDestroyOnLoadObjects 在传递到时移动到的特殊场景GameObject.DontDestroyOnLoad(...)

  2. 除了生命周期变化、无效场景和彼此不同的对象(具有不同的对象等)之外,上述示例prefab之间是否还有其他值得注意的差异?instanceGetInstanceID()

  3. 由于调用GameObject.Instantiate(...)prefab产生一个处于有效场景的游戏对象,有没有办法手动创建处于类似“无场景”状态的游戏对象?我知道 Unity 打算让所有游戏对象都出现在场景中,所以这纯粹是一个学术问题。

我曾尝试查看所涉及函数的文档没有人深入了解调用预制资源时具体发生的情况的技术细节。 Resources.Load

4

1 回答 1

3

1.我到底应该把这个特殊的游戏对象放在哪里?

它在一个单独的文件中,并且没有在场景中引用。一旦Resources.Load<GameObject>("SomeObject");被调用,它就被加载到内存中等待GameObject.Instantiate被调用时使用。

如果它被声明为public GameObject prefab;并从编辑器分配而不是GameObject prefab Resources.Load<GameObject>("SomeObject");,它将在场景加载时自动加载到内存中。

2.预制件和对象之间还有其他值得注意的区别吗?

是的。

预制件不能用DestroyorDestroyObject函数销毁。它必须DestroyImmediate通过传递true给它的第二个参数来用函数销毁:DestroyImmediate(prefab, true);

3.有没有办法手动创建类似“无场景”状态的游戏对象?

不,无法手动创建处于类似“无场景”状态的游戏对象。

虽然你可以伪造它。

最接近的方法是通过修改 GameObjects 的变量,使 GameObject 在 Editor 的HierarchyInspectorhideFlags选项卡中不可见,然后停用该 GameObject。

GameObject obj = new GameObject("SomeObject");
obj.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;

之后,停用 GameObject:

obj.SetActive(false);

现在,游戏对象在编辑器中是不可见的,在场景和游戏视图中也是不可见的。


预制件和典型的游戏对象之间并没有太大的区别。Prefab 只是一个包含 GameObject 的容器,以便它可以在场景之间重复使用和共享。修改一个预制件将更新它的任何实例。

想象一下,当您在场景中有数百个相同类型的游戏对象并且需要修改所有这些对象时。使用预制件,您只需修改其中一个或只修改预制件,然后单击应用来更新其他实例。这是你唯一应该想到的预制件。

于 2017-06-15T07:36:20.117 回答