【Unity学习笔记】第十四 Prefab 概念解惑

目录

      • [1 prefab、prefab变体、prefab覆盖和prefab 嵌套](#1 prefab、prefab变体、prefab覆盖和prefab 嵌套)
      • [2 connect 与unpack](#2 connect 与unpack)
      • [3 prefab到底是什么,它和gameobject又有什么区别?](#3 prefab到底是什么,它和gameobject又有什么区别?)
      • [4 为什么要用prefab?](#4 为什么要用prefab?)
      • [5 代码动态加载prefab](#5 代码动态加载prefab)
      • [6 为什么我unity PrefabUtility.InstantiatePrefab() 得到的是null](#6 为什么我unity PrefabUtility.InstantiatePrefab() 得到的是null)
      • [7 PrefabUtility.InstantiatePrefab()与Instantiate 区别](#7 PrefabUtility.InstantiatePrefab()与Instantiate 区别)
      • [8 PrefabAssetType](#8 PrefabAssetType)
      • [9 prefab使用建议](#9 prefab使用建议)
      • [10 总结](#10 总结)

Prefab基础参见官方手册::

本文主要针对手册中没有提到或没有解释清楚的概念进行探究。

转载请注明出处: 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?

  1. gameObject组可预设为模板:Unity 的prefab系统允许创建、配置和存储游戏对象及其所有组件、属性值和子游戏对象作为可重用资源。预制体资源充当模板,在此模板的基础之上可以在场景中创建新的预制体实例。
  2. 对象重用:如果要在场景中的多个位置或项目中的多个场景之间重用以特定方式配置的游戏对象,比如非玩家角色 (NPC)、道具或景物,则应将此游戏对象转换为预制体。
  3. 批量修改同一prefab实例:prefab比简单复制和粘贴游戏对象更好,因为预制件系统可以自动保持所有副本同步。对预制体资源所做的任何编辑都会自动反映在该预制件的实例中,因此可以轻松地对整个项目进行广泛的更改,而无需对资源的每个副本重复进行相同的编辑。
  4. 此外通过预制体嵌套(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

csharp 复制代码
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和资源加载、序列化之类的才能更清楚些,等未来实战再遇到时再来研究吧。

相关推荐
小春熙子6 小时前
Unity图形学之Shader结构
unity·游戏引擎·技术美术
Sitarrrr8 小时前
【Unity】ScriptableObject的应用和3D物体跟随鼠标移动:鼠标放置物体在场景中
3d·unity
极梦网络无忧9 小时前
Unity中IK动画与布偶死亡动画切换的实现
unity·游戏引擎·lucene
逐·風16 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
_oP_i18 小时前
Unity Addressables 系统处理 WebGL 打包本地资源的一种高效方式
unity·游戏引擎·webgl
Leoysq1 天前
【UGUI】实现点击注册按钮跳转游戏场景
游戏·unity·游戏引擎·ugui
_oP_i1 天前
unity中 骨骼、纹理和材质关系
unity·游戏引擎·材质
Padid2 天前
Unity SRP学习笔记(二)
笔记·学习·unity·游戏引擎·图形渲染·着色器
Tp_jh2 天前
推荐一款非常好用的C/C++在线编译器
linux·c语言·c++·ide·单片机·unity·云原生
dangoxiba2 天前
[Unity Demo]从零开始制作空洞骑士Hollow Knight第十八集补充:制作空洞骑士独有的EventSystem和InputModule
游戏·unity·c#·游戏引擎·playmaker