PrefabUtility.UnpackPrefabInstance

This commit is contained in:
ousttrue 2023-11-27 20:23:16 +09:00
parent 4ec5d54588
commit b890201581
3 changed files with 87 additions and 40 deletions

View File

@ -155,15 +155,6 @@ namespace UniGLTF.MeshUtility
// m_excludes.AddRange(excludes);
// }
/// <summary>
/// Scene と Prefab で挙動をスイッチする。
///
/// - Scene: ヒエラルキーを操作する。Asset の 書き出しはしない。UNDO はする。TODO: 明示的な Asset の書き出し。
/// - Prefab: 対象をコピーして処理する。Undo は実装しない。結果を Asset として書き出し、処理後にコピーは削除する。
///
/// </summary>
bool TargetIsPrefab => _exportTarget != null && _exportTarget.scene.name == null;
protected virtual void DialogMessage()
{
EditorGUILayout.HelpBox(MeshUtilityMessages.MESH_UTILITY.Msg(), MessageType.Info);
@ -172,7 +163,6 @@ namespace UniGLTF.MeshUtility
private void OnGUI()
{
var modified = false;
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
EditorGUIUtility.labelWidth = 200;
LanguageGetter.OnGuiSelectLang();
@ -187,11 +177,23 @@ namespace UniGLTF.MeshUtility
MeshIntegration.UpdateMeshIntegrationList(_exportTarget);
modified = true;
}
if (_exportTarget == null)
{
return;
}
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
// GameObject or Prefab ?
if (TargetIsPrefab)
switch (_exportTarget.GetPrefabType())
{
EditorGUILayout.HelpBox(MeshUtilityMessages.PREFAB_TARGET.Msg(), MessageType.Warning);
case UnityExtensions.PrefabType.PrefabAsset:
EditorGUILayout.HelpBox(MeshUtilityMessages.PREFAB_ASSET.Msg(), MessageType.Warning);
break;
case UnityExtensions.PrefabType.PrefabInstance:
EditorGUILayout.HelpBox(MeshUtilityMessages.PREFAB_INSTANCE.Msg(), MessageType.Warning);
break;
}
// tab bar
@ -255,7 +257,7 @@ namespace UniGLTF.MeshUtility
GUI.enabled = true;
if (pressed)
{
if (TargetIsPrefab)
if (_exportTarget.GetPrefabType() == UnityExtensions.PrefabType.PrefabAsset)
{
/// [prefab]
///
@ -283,6 +285,7 @@ namespace UniGLTF.MeshUtility
assetFolder = unityPath.Value;
var copy = GameObject.Instantiate(_exportTarget);
PrefabUtility.UnpackPrefabInstance(copy, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
var (results, created) = MeshUtility.Process(copy);
@ -294,6 +297,11 @@ namespace UniGLTF.MeshUtility
else
{
Undo.RegisterFullObjectHierarchyUndo(_exportTarget, "MeshUtility");
if (_exportTarget.GetPrefabType() == UnityExtensions.PrefabType.PrefabInstance)
{
PrefabUtility.UnpackPrefabInstance(_exportTarget, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
}
var (results, created) = MeshUtility.Process(_exportTarget);
foreach (var go in created)
{

View File

@ -44,36 +44,36 @@ Separate the mesh attached to the SkinnedMeshRenderer under the target object wi
[LangMsg(Languages.en, "Divide by the presence or absence of `blendshape`")]
MESH_SEPARATOR_BY_BLENDSHAPE,
// [LangMsg(Languages.ja, @"ターゲットオブジェクト下の SkinnedMeshRenderer または MeshFilter にアタッチされたメッシュを統合します。
// [LangMsg(Languages.ja, @"ターゲットオブジェクト下の SkinnedMeshRenderer または MeshFilter にアタッチされたメッシュを統合します。
// * Asset: Assets/MeshIntegrated.mesh が作成されます(上書きされるので注意してください)。
// * Scene: コピーされたヒエラルキーでは、統合された Mesh は除去されます。新しく MeshIntegrator ノードが追加されます。
// * VRMではBlendShapeClipの統合など追加の処理が必要です。`VRM0-MeshIntegratorWizard` を使ってください。
// ")]
// [LangMsg(Languages.en, @"Integrates the attached mesh into the SkinnedMeshRenderer or MeshFilter under the target object.
// * Asset: Assets/MeshIntegrated.mesh が作成されます(上書きされるので注意してください)。
// * Scene: コピーされたヒエラルキーでは、統合された Mesh は除去されます。新しく MeshIntegrator ノードが追加されます。
// * VRMではBlendShapeClipの統合など追加の処理が必要です。`VRM0-MeshIntegratorWizard` を使ってください。
// ")]
// [LangMsg(Languages.en, @"Integrates the attached mesh into the SkinnedMeshRenderer or MeshFilter under the target object.
// * Asset: Assets/MeshIntegrated.mesh is created (note that it will be overwritten).
// * Scene: In the copied hierarchy, the integrated mesh is removed. A new MeshIntegrator node is added.
// * VRM requires additional processing such as BlendShapeClip integration. Use the `VRM0-MeshIntegratorWizard` integration feature.
// ")]
// MESH_INTEGRATOR,
// * Asset: Assets/MeshIntegrated.mesh is created (note that it will be overwritten).
// * Scene: In the copied hierarchy, the integrated mesh is removed. A new MeshIntegrator node is added.
// * VRM requires additional processing such as BlendShapeClip integration. Use the `VRM0-MeshIntegratorWizard` integration feature.
// ")]
// MESH_INTEGRATOR,
// // [LangMsg(Languages.ja, "静的メッシュを一つに統合します")]
// // [LangMsg(Languages.en, "Integrate static meshes into one")]
// // STATIC_MESH_INTEGRATOR,
// // [LangMsg(Languages.ja, "静的メッシュを一つに統合します")]
// // [LangMsg(Languages.en, "Integrate static meshes into one")]
// // STATIC_MESH_INTEGRATOR,
// [LangMsg(Languages.ja, @"指定された SkinnedMeshRenderer から、指定されたボーンに対する Weight を保持する三角形を除去します。
// [LangMsg(Languages.ja, @"指定された SkinnedMeshRenderer から、指定されたボーンに対する Weight を保持する三角形を除去します。
// * Asset: 元の Mesh と同じフォルダに、三角形を除去した Mesh を保存します。
// * Scene: コピーされたヒエラルキーでは、三角形が除去された Mesh に差し替えられます。
// ")]
// [LangMsg(Languages.en, @"Removes the triangle that holds the weight for the specified bone from the specified SkinnedMeshRenderer.
// * Asset: 元の Mesh と同じフォルダに、三角形を除去した Mesh を保存します。
// * Scene: コピーされたヒエラルキーでは、三角形が除去された Mesh に差し替えられます。
// ")]
// [LangMsg(Languages.en, @"Removes the triangle that holds the weight for the specified bone from the specified SkinnedMeshRenderer.
// * Assets: Save the mesh with the triangles removed in the same folder as the original mesh.
// * Scene: In the copied hierarchy, it will be replaced with a Mesh with the triangles removed.
// ")]
// * Assets: Save the mesh with the triangles removed in the same folder as the original mesh.
// * Scene: In the copied hierarchy, it will be replaced with a Mesh with the triangles removed.
// ")]
// BONE_MESH_ERASER,
// BONE_MESH_ERASER,
[LangMsg(Languages.ja, "Skinned Meshを選んでください")]
[LangMsg(Languages.en, "Select a skinned mesh")]
@ -103,8 +103,12 @@ Separate the mesh attached to the SkinnedMeshRenderer under the target object wi
[LangMsg(Languages.en, "Because BlendShapeClip causes inconsistency , use `VRM0 -> MeshIntegrator` instead")]
VRM_DETECTED,
[LangMsg(Languages.ja, "対象は, Prefab です。実行時に書き出しファイルの指定があります。")]
[LangMsg(Languages.en, "The target is prefab. A temporary file is specified during execution.")]
PREFAB_TARGET,
[LangMsg(Languages.ja, "対象は, Prefab Asset です。実行時に書き出しファイルの指定があります。")]
[LangMsg(Languages.en, "The target is prefab asset. A temporary file is specified during execution.")]
PREFAB_ASSET,
[LangMsg(Languages.ja, "対象は, Prefab Instance です。Unpack されます。")]
[LangMsg(Languages.en, "The target is prefab asset. A temporary file is specified during execution.")]
PREFAB_INSTANCE,
}
}

View File

@ -449,5 +449,40 @@ namespace UniGLTF
}
return true;
}
public enum PrefabType
{
PrefabAsset,
PrefabInstance,
NotPrefab,
}
/// <summary>
/// Scene と Prefab で挙動をスイッチする。
///
/// - Scene: ヒエラルキーを操作する。Asset の 書き出しはしない。UNDO はする。TODO: 明示的な Asset の書き出し。
/// - Prefab: 対象をコピーして処理する。Undo は実装しない。結果を Asset として書き出し、処理後にコピーは削除する。
///
/// </summary>
public static PrefabType GetPrefabType(this GameObject go)
{
if (go == null)
{
throw new ArgumentNullException();
}
if (!go.scene.IsValid())
{
return PrefabType.PrefabAsset;
}
#if UNITY_EDITOR
if (PrefabUtility.GetOutermostPrefabInstanceRoot(go) != null)
{
return PrefabType.PrefabInstance;
}
#endif
return PrefabType.NotPrefab;
}
}
}
}