prefab內容分析


寫在前面:

  • 當前使用的unity版本:5.3.7p4。
  • 如果打開prefab文件是亂碼:

    把editer的asset Srialization改為Force Text即可。

一、什么是Prefab

Prefab是unity3d中的一種資源類型,用於存儲可重復使用的游戲對象,來方便快捷的創建實例。
通過prefab在場景中創建的所有實例,都會鏈接到原始的prefab,所以當修改原始的prefab時,所有場景中的所有prefab實例都會被修改。

二、Prefab文件的內容

Prefab文件的內容是通過YAML語言序列化的一個GameObject的對象,包含了這個GameObject的所有描述信息(GameObject信息、Compent實例和屬性等)。

三、從一個Cube的Prefab說起

prefab文件的內容

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &101978
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  serializedVersion: 4
  m_Component:
  - 4: {fileID: 481870}
  - 33: {fileID: 3343092}
  - 65: {fileID: 6596578}
  - 23: {fileID: 2346436}
  m_Layer: 0
  m_Name: aCube
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &481870
Transform:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 101978}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 384.3385, y: 224.03131, z: 116.32626}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
  m_Children: []
  m_Father: {fileID: 0}
  m_RootOrder: 0
--- !u!23 &2346436
MeshRenderer:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 101978}
  m_Enabled: 1
  m_CastShadows: 1
  m_ReceiveShadows: 1
  m_Materials:
  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
  m_SubsetIndices: 
  m_StaticBatchRoot: {fileID: 0}
  m_UseLightProbes: 1
  m_ReflectionProbeUsage: 1
  m_ProbeAnchor: {fileID: 0}
  m_ScaleInLightmap: 1
  m_PreserveUVs: 1
  m_IgnoreNormalsForChartDetection: 0
  m_ImportantGI: 0
  m_MinimumChartSize: 4
  m_AutoUVMaxDistance: 0.5
  m_AutoUVMaxAngle: 89
  m_LightmapParameters: {fileID: 0}
  m_SortingLayerID: 0
  m_SortingOrder: 0
--- !u!33 &3343092
MeshFilter:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 101978}
  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!65 &6596578
BoxCollider:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 101978}
  m_Material: {fileID: 0}
  m_IsTrigger: 0
  m_Enabled: 1
  serializedVersion: 2
  m_Size: {x: 1, y: 1, z: 1}
  m_Center: {x: 0, y: 0, z: 0}
--- !u!1001 &100100000
Prefab:
  m_ObjectHideFlags: 1
  serializedVersion: 2
  m_Modification:
    m_TransformParent: {fileID: 0}
    m_Modifications: []
    m_RemovedComponents: []
  m_ParentPrefab: {fileID: 0}
  m_RootGameObject: {fileID: 101978}
  m_IsPrefabParent: 1

分析其中內容

1.前兩行內容是yaml語言的注釋

2.接下來是prefab中所有對象的描述信息

每個元素的描述內容以--- !u!n1 & n2開頭,其中n1代表元素的類型ID(每個ID的具體含義參考YAML Class ID Reference),n2代表這個元素的本地ID(fileID,在prefab文件中唯一)。
可以看到這個prefab中有GameObject,Transform,MeshRenderer,MeshFilter,BoxCollider,Prefab共6個對象。
除了Prefab對象代表prefab本身的信息,其他5個對象正是一個Cube的構成。

3.第一個GameObject對象的詳細說明

<1>--- !u!1 &101978
1代表這是一個GameObject類型的對象,101978是這個GameObject對象在Prefab資源中的fileID。
<2>m_ObjectHideFlags:0
這個元素在Project視圖中是否被隱藏,因為prefab中只有這一個GameObject作為根GameObject,所以沒被隱藏,值為0。
<3>m_PrefabParentObject: {fileID: 0}
代表場景中的prefab實例與原始prefab資源的鏈接,當一個prefab實例鏈接被破壞(刪除prefab實例的一個子節點,或修改一個子節點父子關系),或其中的compent被剝離到場景文件中(stripped,比如prefab實例在場景中不是根節點,而是一個GameObject的子節點,那么prefab實例的transtrom就會被剝離到場景文件中,賦予一個fileID,用來描述prefab實例的父子關系)時,生成的對象的m_PrefabParentObject會對應到原始prefab資源中的對象。

在原始prefab資源中,所有對象的m_PrefabParentObject都是0,代表空。
<4>m_PrefabInternal: {fileID: 100100000}
該屬性表示這個對象屬於哪個prefab對象。
在場景中當一個compent被剝離時,會指向場景中的prefab實例。
在原始prefab資源中,因為prefab中只有一個prefab對象,fileID就是1000100000。
所以在原始prefab資源中,所有對象的m_PrefabInternal值都是{fileID: 100100000}。
Stripped舉例:
新建一個叫testStripped的prefab,用一個空的GameObject給它賦值,然后將這個prefab拖到Main Camera下,保存場景文件后查看場景文件內容。

Transform:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 280358070}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 1, z: -10}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
  m_Children:
  - {fileID: 619871928}
  m_Father: {fileID: 0}
  m_RootOrder: 0
--- !u!1001 &619871927
Prefab:
  m_ObjectHideFlags: 0
  serializedVersion: 2
  m_Modification:
    m_TransformParent: {fileID: 280358075}
    m_Modifications:
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalPosition.x
      value: 384.3385
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalPosition.y
      value: 223.03131
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalPosition.z
      value: 126.32626
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalRotation.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalRotation.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalRotation.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_LocalRotation.w
      value: 1
      objectReference: {fileID: 0}
    - target: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
      propertyPath: m_RootOrder
      value: 0
      objectReference: {fileID: 0}
    m_RemovedComponents: []
  m_ParentPrefab: {fileID: 100100000, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
  m_IsPrefabParent: 0
--- !u!4 &619871928 stripped
Transform:
  m_PrefabParentObject: {fileID: 488654, guid: 617cd7fcc638efd44b4beab357086bc0, type: 2}
  m_PrefabInternal: {fileID: 619871927}

查看其中Main Camera的transform,prefab實例和stripped的transform的信息。
發現Main Camera的transform的m_Children屬性指向了sttripped的transform,代表Prefab實例是Main Camera的子節點。
sttripped的transform的m_ParentPrefab指向了Prefab資源中對應的transform屬性,m_IsPrefabParent指向了場景文件中的Prefab實例。

通過對Preafab的transform剝離到場景文件中,實現了場景中對Prefab實例父子關系的記錄。
<5>serializedVersion: 4
序列化的版本,跟unity版本有關,不太確定。
<6>m_Component:
該GameObject包含哪些component,包含的對象用fileID表示。這個GameObject包含了4個Component,分別是Transform,MeshRenderer,MeshFilter,BoxCollider。
<7>m_Layer: 0
GameObject所在的層級。
<8>m_Name: aCube
GameObject的名稱。
<9>m_TagString: Untagged
Tag。
<10>m_Icon: {fileID: 0}
圖標,fileID為0代表沒有圖標。
圖標會顯示在場景中,比如選擇這個紅色的icon,在場景中就可以看到prefab上出現了一個紅色的標簽。0代表沒有標簽。


<11>m_NavMeshLayer: 0

GameObject的NavigationArea屬性,與自動尋路有關。
<12>m_StaticEditorFlags: 0
GameObject的Static屬性。
<13>m_IsActive: 1
GameObject是否是active狀態。

4.接下來四個對象描述了這個GameObject上的4個Component,選擇比較有代表性的Transform和MeshFilter進行分析。

Transform:

<1>前三行跟GameObject的含義一樣
<2>m_GameObject: {fileID: 101978}
Transoform所屬GameObject的fileID。
<3>m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
記錄的Transform的LocalRotation信息,這個是通過四元數表示的,可在debug模式下查看。

<4>m_LocalPosition: {x: 88.257, y: 90.200806, z: 90.15849}
Transform的LocalPosition屬性。
<5>m_LocalScale: {x: 1, y: 1, z: 1}
Transform的LocalScale屬性。
<6>m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
Transform的LocalEulerAnglesHint屬性,在Normal模式下可見。

MeshFilter:

<1>前4行的含義上面已經講過了
<2>m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
這代表這個Mesh屬性的值是一個外部資源,通過唯一的外部資源guid(每個外部資源的guid保存在同名的.meta文件下)和資源的本地fileID確定了具體的資源對象。
通過對項目中各個引用的外部資源的查看,猜測type的含義為:
0代表unity的內置資源。
2代表Yaml描述的復合類型的外部資源(prefab,animControoller等)。
3代表基礎類型的外部資源(image,script等)。

5.prefab對象

<1>前兩個說過了
<2>m_Modification:
當一個prefab實例化到場景中的時候,代表場景prefab實例被修改的值,這些值不隨原始prefab資源的修改而修改。
在原始prefab資源中是空的。
<3>m_ParentPrefab: {fileID: 0}
在場景中的一個prefab實例中代表這個prefab對應的原始perfab資源中的prefab對象。
在prefab實例中是0。
<4>m_RootGameObject: {fileID: 152762}
prefab資源對應的GameObject。
<5>m_IsPrefabParent: 1
可能是Prefab是資源還是實例的標記,不太確定。

簡單總結一下一個prefab的內容

prefab文件並不存儲具體資源,而是使用了yaml語言描述了一個被序列化的GameObject對象中包含的所有GameObject,Component的信息。包括相互之間的關系、存儲的數據和引用信息。

四、prefab在場景中的使用

1.簡單介紹場景文件的內容

一個場景文件也是通過yaml語言序列化的場景內容,一個場景文件不僅包含顯示在hierarchy中的GameObject、prefab信息,還包含了場景的設置信息。比prefab稍微復雜一些。

2.prefab文件在場景中的內容

新建一個test場景,將test拖入場景中,然后保存,查看場景中的Prefab實例信息。

--- !u!1001 &131130024
Prefab:
  m_ObjectHideFlags: 0
  serializedVersion: 2
  m_Modification:
    m_TransformParent: {fileID: 0}
    m_Modifications:
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalPosition.x
      value: 384.3385
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalPosition.y
      value: 224.03131
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalPosition.z
      value: 116.32626
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalRotation.x
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalRotation.y
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalRotation.z
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_LocalRotation.w
      value: 1
      objectReference: {fileID: 0}
    - target: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
      propertyPath: m_RootOrder
      value: 2
      objectReference: {fileID: 0}
    m_RemovedComponents: []
  m_ParentPrefab: {fileID: 100100000, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
  m_IsPrefabParent: 0

可以看到一個prefab被實例化到場景中時,沒有將prefab資源中內容直接復制到場景中,而是生成了一個prefab對象。
m_ParentPrefab代表這個prefab對應的prefab資源。
m_Modification代表這個prefab實例中屬性的修改信息,場景在讀取一個prefab實例時,會查看prefab資源中的屬性是否在m_Modification中存在,如果存在,則使用m_Modification中保存的值。這樣就保證了修改了場景中的prefab實例的屬性,不會被prefab資源的修改而覆蓋。
正是這兩個屬性讓prefab實例具有了與prefab資源同步修改,但會保存自己特性的功能。

3.Break Prefab Instance

如果我們希望一個prefab實例完全不隨prefab的修改而修改,那么我們可以通過Break Prefab Instance選項實現。

將一個prefab實例Break之后,這個prefab就會像一個普通的GameObject存在場景中

--- !u!1 &765230757
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 101978, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
  m_PrefabInternal: {fileID: 0}
  serializedVersion: 4
  m_Component:
  - 4: {fileID: 765230761}
  - 33: {fileID: 765230760}
  - 65: {fileID: 765230759}
  - 23: {fileID: 765230758}
  m_Layer: 0
  m_Name: aCube
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!23 &765230758
MeshRenderer:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 2346436, guid: fda6bd048b136f44286b537a5526a83c,
    type: 2}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 765230757}
  m_Enabled: 1
  m_CastShadows: 1
  m_ReceiveShadows: 1
  m_Materials:
  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
  m_SubsetIndices: 
  m_StaticBatchRoot: {fileID: 0}
  m_UseLightProbes: 1
  m_ReflectionProbeUsage: 1
  m_ProbeAnchor: {fileID: 0}
  m_ScaleInLightmap: 1
  m_PreserveUVs: 1
  m_IgnoreNormalsForChartDetection: 0
  m_ImportantGI: 0
  m_MinimumChartSize: 4
  m_AutoUVMaxDistance: 0.5
  m_AutoUVMaxAngle: 89
  m_LightmapParameters: {fileID: 0}
  m_SortingLayerID: 0
  m_SortingOrder: 0
--- !u!65 &765230759
BoxCollider:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 6596578, guid: fda6bd048b136f44286b537a5526a83c,
    type: 2}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 765230757}
  m_Material: {fileID: 0}
  m_IsTrigger: 0
  m_Enabled: 1
  serializedVersion: 2
  m_Size: {x: 1, y: 1, z: 1}
  m_Center: {x: 0, y: 0, z: 0}
--- !u!33 &765230760
MeshFilter:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 3343092, guid: fda6bd048b136f44286b537a5526a83c,
    type: 2}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 765230757}
  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &765230761
Transform:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 481870, guid: fda6bd048b136f44286b537a5526a83c, type: 2}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 765230757}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 384.3385, y: 224.03131, z: 116.32626}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
  m_Children: []
  m_Father: {fileID: 0}
  m_RootOrder: 2

每個元素的m_PrefabParentObject都指向了原始prefab資源中對應的對象。

右邊的prefab表示也會變為黃色,這代表這個prefab雖然被break了,但是還可以通過與原始prefab資源的鏈接去select,revert或apply,來變回或修改原來的prefab實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM