目录
- 1 prefab、prefab变体、prefab覆盖和prefab 嵌套
- 2 connect 与unpack
- 3 prefab到底是什么,它和gameobject又有什么区别?
- 4 为什么要用prefab?
- 5 代码动态加载prefab
- 6 为什么我unity PrefabUtility.InstantiatePrefab() 得到的是null
- 7 PrefabUtility.InstantiatePrefab()与Instantiate 区别
- 8 PrefabAssetType
- 9 prefab使用建议
- 10 总结
Prefab基础参见官方手册::
- Unity 手册-预制件
- Unity 手册-在运行时实例化预制件
本文主要针对手册中没有提到或没有解释清楚的概念进行探究。
转载请注明出处: https://blog.csdn.net/weixin_44013533/article/details/138233550
作者:CSDN@|Ringleader|
1 prefab、prefab变体、prefab覆盖和prefab 嵌套
覆盖就是对拖动到scene中的预制体进行的修改,分为更改属性和增减组件或gameobject,但无法修改gameobject层级关系。
你可以重置修改,也可以将修改变动应用到源prefab资产。可以批量操作也可以对单独项进行操作。
注意:变体的覆盖分覆盖到父prefab和自身prefab变体:
注意存在覆盖优先的情况:
- 预制件实例上覆盖的属性值始终优先于预制件资源的值。这意味着,如果更改预制件资源的属性,对覆盖该属性的实例没有任何影响。
- 如果对预制件资源进行更改,但未按预期更新所有实例,则应检查实例上是否覆盖了该属性。最好仅在确实必要时才使用实例覆盖,因为如果整个项目中有大量实例覆盖,则很难判断对预制件资源的更改是否对所有实例都有影响。
至于预制体变体和嵌套预制体,可以类比class概念理解成prefab的继承。
2 connect 与unpack
2018.2 and above updated method. Right click on the game object and select “unpack prefab”.
3 prefab到底是什么,它和gameobject又有什么区别?
比如scene场景一个普通gameobject层级结构:
则这个scene的yaml文件对应gameObject结构如下:
当将gameobject拖入project变成prefab后,scene文件结构变成:
这里sourcePrefab的guid就是这个prefab.mata里的guid
注意:prefab资源文件本体没有记录该资源的guid,而是由其对应的meta文件记录的。
而此时prefab结构如下:
可以看到prefab的gameobject结构和scene中gameobject结构并没有什么区别。而上面scene文件的区别就是将原先gameObject变成通过PrefabInstance根据guid进行引用罢了。
所以prefab的本质就是: prefab是独立于scene而存在的一组gameObject资源。
这个帖子里也提到了相似的看法:
Unity create prefab at runtime
4 为什么要用prefab?
- gameObject组可预设为模板:Unity 的prefab系统允许创建、配置和存储游戏对象及其所有组件、属性值和子游戏对象作为可重用资源。预制体资源充当模板,在此模板的基础之上可以在场景中创建新的预制体实例。
- 对象重用:如果要在场景中的多个位置或项目中的多个场景之间重用以特定方式配置的游戏对象,比如非玩家角色 (NPC)、道具或景物,则应将此游戏对象转换为预制体。
- 批量修改同一prefab实例:prefab比简单复制和粘贴游戏对象更好,因为预制件系统可以自动保持所有副本同步。对预制体资源所做的任何编辑都会自动反映在该预制件的实例中,因此可以轻松地对整个项目进行广泛的更改,而无需对资源的每个副本重复进行相同的编辑。
- 此外通过预制体嵌套(Nested Prefabs)可以将一个预制体嵌套到另一个预制体中,从而创建多个易于编辑的复杂游戏对象层级视图。可以通过覆盖各个预制体实例的设置来创建预制体变体(Prefabs Variant),从而可以将一系列覆盖组合在一起形成有意义预制体的变化。
5 代码动态加载prefab
聊聊Unity中如何使用预制体Prefab提高工作效率
这篇讲解得非常好,顺便了解了UI
6 为什么我unity PrefabUtility.InstantiatePrefab() 得到的是null
PrefabUtility.InstantiatePrefab()如果instantiate的是场景中已存在的gameobject会无效。object.Instantiate()更像是clone,而PrefabUtility.InstantiatePrefab()才是实实在在的实例化。
PrefabUtility.InstantiatePrefab()要求传递的是prefab资产,而不是scene中的对象,否则无法克隆
但为什么用Instantiate和PrefabUtility.InstantiatePrefab得到的图标不一样呢?
Creating GameObject at runtime from child prefab
7 PrefabUtility.InstantiatePrefab()与Instantiate 区别
这一篇详细介绍了两者的不同:Instantiate vs PrefabUtility.InstantiatePrefab
同时注意PrefabUtility只是用于Editor。需要添加注释
否则打包时会报错
Instantiate vs PrefabUtility.InstantiatePrefab
Instantiate original Prefab based on an already existing Prefab in game
Unity create prefab at runtime
8 PrefabAssetType
namespace UnityEditor
{
/// <summary>
/// <para>Enum indicating the type of Prefab Asset, such as Regular, Model and Variant.</para>
/// </summary>
public enum PrefabAssetType
{
/// <summary>
/// <para>The object being queried is not part of a Prefab at all.</para>
/// </summary>
NotAPrefab,
/// <summary>
/// <para>The object being queried is part of a regular Prefab.</para>
/// </summary>
Regular,
/// <summary>
/// <para>The object being queried is part of a Model Prefab.</para>
/// </summary>
Model,
/// <summary>
/// <para>The object being queried is part of a Prefab Variant.</para>
/// </summary>
Variant,
/// <summary>
/// <para>The object being queried is part of a Prefab instance, but because the asset is missing the actual type of Prefab can’t be determined.</para>
/// </summary>
MissingAsset,
}
9 prefab使用建议
《Unity性能优化》第玖节——编辑器创建资源优化(2)——预制体
10 总结
本文初步探究了关于prefab的一些疑惑,但并没有彻底弄清,不过至少比原先清晰了很多,后面可能还要研究AssetBundle和资源加载、序列化之类的才能更清楚些,等未来实战再遇到时再来研究吧。