例
在Unity5中,假设名称为“ SomeObject”的GameObject作为预制存储在Assets / Resources / SomeObject.prefab中,我知道可以按如下方式创建预制的实例:
GameObject prefab = Resources.Load<GameObject>("SomeObject");
GameObject instance = GameObject.Instantiate(prefab);
一旦执行,实例GameObject将是原始“ SomeObject”预制件的副本,并将被放置在当前活动场景中,名称为“ SomeObject(Clone)”.
据我了解,GameObject预制件代表实际的预制件资产,并且对其所做的任何更改(设置名称,添加组件等)都会写入原始的预制件资产,并且即使退出编辑器播放模式,这些更改也会保留.
问题
>由于所有GameObject通常都存储在一个场景中,并且上例中GameObject预制件上的scene属性似乎是Unloaded / Invalid / Unnamed,因此我应该把这个特殊的GameObject放在哪里呢?我似乎能够使用普通GameObjects进行所有操作,但是在层次结构/场景视图中却看不见.
在某种边缘状态还是特殊的伪场景中,它有效吗?它似乎一直通过LoadSceneMode保持不变.单个场景发生了变化,但与传递给GameObject.DontDestroyOnLoad(…)时将对象移动到的特殊DontDestroyOnLoad场景不同.
>在上述示例中,预制件与实例之间是否还有其他值得注意的区别,除了生命周期变化,无效场景和彼此不同的对象(具有不同的GetInstanceID()等)之外?
>由于在预制上调用GameObject.Instantiate(…)会产生有效场景中的GameObject,是否有任何方法可以手动创建处于类似“无场景”状态的GameObject?我知道Unity打算将所有GameObjects都放在场景中,因此这纯粹是一个学术问题.
我尝试浏览functions involved的documentation,但是没有一个技术细节可以详细了解在预制资源上调用Resources.Load时发生的情况.
解决方法:
1.Where exactly should I consider this special GameObject to be?
它在单独的文件中,而在场景中未引用.一旦Resources.Load< GameObject>(“ SomeObject”);被调用时,它被加载到内存中,等待GameObject.Instantiate被调用时使用.
如果声明为公共GameObject预制;并从编辑器中分配,而不是从GameObject预制资源中分配.Load< GameObject>(“ SomeObject”);,场景加载时它将自动加载到内存中.
2.Are there any other noteworthy differences between prefab and object?
是.
预制件无法使用Destroy或DestroyObject函数销毁.必须通过将True传递给第二个论点来使用DestroyImmediate函数销毁它:DestroyImmediate(prefab,true);
3.Is there any way to manually create GameObjects that are in a similar ‘no scene’ state?
不,没有办法手动创建处于类似“无场景”状态的GameObject.
虽然可以伪造.
与此最接近的是,通过修改GameObjects的hideFlags
变量,然后停用该GameObject,可以使GameObject在编辑器的“层次结构”和“检查器”选项卡中不可见.
GameObject obj = new GameObject("SomeObject");
obj.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
之后,停用GameObject:
obj.SetActive(false);
现在,GameObject在编辑器中不可见,并且在“场景”和“游戏视图”中也不可见.
预制件和典型的GameObject之间确实没有太大的区别.预制只是容纳GameObject的容器,因此可以在场景之间重复使用和共享它.修改一个预制件将更新它的任何实例.
想象一下,当场景中有数百个相同类型的游戏对象并且需要修改所有这些对象时.使用预制,您只需要修改其中之一,或者只需修改预制,然后单击“应用”即可更新其他实例.这是您应该想到的唯一预制件.