[検証バージョン] Unity 5.5.1p3
直接編集はファイルの破損などの危険があるため、各自で判断の上、バックアップをちゃんととってお試しください。
追記:
—
ヒエラルキービュー上でプレファブの子を削除するとプレファブとの関連付けが解かれたように見えますが、実はその状態でApplyをすることができます。
Twitterでご教示いただきました。ありがとうございます!
@mokusan 確かにヒエラルキービューでプレファブインスタンスの子オブジェクトを削除すると元のプレファブへの参照が解除されちゃうけど、そこでもう1回「Apply」押せば参照復活して、削除も元プレファブに反映されるみたいだから単純にそうしてるんですけどダメなのかな
— きっとポジション (@kitposition) February 27, 2017
—
階層構造を持つオブジェクト群をプレファブ化した場合、その子の一部を消すことってできませんよね?
プロジェクトビューからは子の一部を削除することはできないし、ヒエラルキービューで子を削除しようとするとプレファブとの関連が解けてしまいます。
子を追加してApplyはできるけど、削除はできないんです。
※ もしUnityの通常の操作でプレファブの一部の子だけを消すことができるのでしたら教えてください。
なんとかならないかと思い、まずはプレファブのインスタンスが置かれているシーンファイルをのぞいてみました。
(シーンファイルはデフォルト設定ではバイナリになっているので、Editor SettingsでAsset SerializationのModeをForce Textにしないと中身を見ることができません)
%YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!29 &1 ・ ・ ・ (ライティングなどのシーン設定に関する記述) ・ ・ ・ --- !u!1001 &1314774805 Prefab: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalPosition.x value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalPosition.y value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalPosition.z value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.x value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.y value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.z value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.w value: 1 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_RootOrder value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] m_ParentPrefab: {fileID: 100100000, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} m_IsPrefabParent: 0
どうやらプレファブとの関連付けが記述されているだけで、プレファブファイルの方を直接編集してやれば上手くいきそうです。
※ ただし、以下の場合は関連付け以外の情報がシーンファイルに含まれるので注意が必要です。
・プレファブ化した元のオブジェクトがそのままシーンに残っている場合
・プレファブをインスタンス化したものにコンポーネントや子オブジェクトを追加した場合。
それではプレファブのファイルを編集してみます。
%YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !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: 1006150272106676} m_IsPrefabParent: 1 --- !u!1 &1006150272106676 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} serializedVersion: 5 m_Component: - component: {fileID: 4721125990716184} m_Layer: 0 m_Name: GameObject m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!1 &1271471559630830 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} serializedVersion: 5 m_Component: - component: {fileID: 4955832607490314} - component: {fileID: 33287708229778766} - component: {fileID: 65699820418463966} - component: {fileID: 23228631480229132} m_Layer: 0 m_Name: Cube m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &4721125990716184 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1006150272106676} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 4955832607490314} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &4955832607490314 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1271471559630830} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 4721125990716184} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &23228631480229132 MeshRenderer: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1271471559630830} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_Materials: - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} m_StaticBatchInfo: firstSubMesh: 0 subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 m_PreserveUVs: 1 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 m_SortingOrder: 0 --- !u!33 &33287708229778766 MeshFilter: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1271471559630830} m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} --- !u!65 &65699820418463966 BoxCollider: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1271471559630830} 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」のような記述から始まるひとかたまりが一つのオブジェクトやコンポーネントを表しているのがわかります。
前半がオブジェクトに関する記述、後半がコンポーネント。親子関係はTransformコンポーネントの部分に記述されています。
「m_Name:」にオブジェクト名が書かれているので、今回消したい子オブジェクト’Cube’を探します。
--- !u!1 &1271471559630830 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} serializedVersion: 5 m_Component: - component: {fileID: 4955832607490314} - component: {fileID: 33287708229778766} - component: {fileID: 65699820418463966} - component: {fileID: 23228631480229132} m_Layer: 0 m_Name: Cube m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1
先頭に書かれている「— !u!1 &1271471559630830」の「1271471559630830」がこのオブジェクトの固有のIDです。
このIDでファイル内を検索すると4つのコンポーネントが付いていることがわかります。
そのうちの一つTransformコンポーネントに関する記述をみてみます。
--- !u!4 &4955832607490314 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1271471559630830} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 4721125990716184} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
今度はこのTransformコンポーネントのID「4955832607490314」で検索すると、親のTransformの記述が見つかります。
--- !u!4 &4721125990716184 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1006150272106676} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 4955832607490314} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
ここの「m_Children:」というところに子のTransformのIDが書かれているので、この行を削除してしまいます。
--- !u!4 &4721125990716184 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1006150272106676} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
あとは、先ほど見つけたオブジェクトに関する記述と4箇所のコンポーネントに関する記述を消すだけです。
%YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !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: 1006150272106676} m_IsPrefabParent: 1 --- !u!1 &1006150272106676 GameObject: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} serializedVersion: 5 m_Component: - component: {fileID: 4721125990716184} m_Layer: 0 m_Name: GameObject m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &4721125990716184 Transform: m_ObjectHideFlags: 1 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1006150272106676} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
これでプレファブファイルがUnityで読み込まれたタイミングでプレファブと全てのインスタンス化されたオブジェクトから子オブジェクト’Cube’が消えます。
インスタンス化してシーンに置かれたオブジェクトに個別に編集を行なっている場合にはシーンファイルにゴミが残る可能性があるので、くれぐれもご注意ください。
以前にUnityのYAMLを読んでみようみたいな記事を見かけたことがあったのですが、まさか本当に自分が読むことになるとは思ってもいませんでした^^;
しかし実際にのぞいてみるとかなりシンプルで分かりやすいですね。
ちなみにプレファブをインスタンス化したものに施した変更はシーンファイルの中の「Prefab:」のところに追記される形で記述されます。
警告はしましたが実際はコンポーネントのパラメータを変更したり、コンポーネントを削除してる場合は今回の編集では影響受けないみたいです。
ただし削除するオブジェクトにコンポーネントを追加していたり、配下にさらに子を追加したりしているとシーンファイルにゴミが残るみたいです。
以下は削除したCubeオブジェクトに適当なスクリプトを追加、また配下にSphereを追加していた場合のシーンファイルです。
--- !u!1001 &1314774805 Prefab: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalPosition.x value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalPosition.y value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalPosition.z value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.x value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.y value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.z value: 0 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_LocalRotation.w value: 1 objectReference: {fileID: 0} - target: {fileID: 4721125990716184, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} propertyPath: m_RootOrder value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] m_ParentPrefab: {fileID: 100100000, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} m_IsPrefabParent: 0 --- !u!1 &1314774806 stripped GameObject: m_PrefabParentObject: {fileID: 1271471559630830, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} m_PrefabInternal: {fileID: 1314774805} --- !u!114 &1314774807 MonoBehaviour: m_ObjectHideFlags: 0 m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 0} m_GameObject: {fileID: 1314774806} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: c75fe1ad4fe3e493ab421c02f41fed06, type: 3} m_Name: m_EditorClassIdentifier: --- !u!4 &1314774808 stripped Transform: m_PrefabParentObject: {fileID: 4955832607490314, guid: 6071afa7dc4674b5ebaa3a0fa0c5c884, type: 2} m_PrefabInternal: {fileID: 1314774805}
Unityのヒエラルキービュー上では問題なさそうに見えますが、シーンファイルにはしっかりゴミが残っているようです。