mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-18 16:21:50 -05:00
prefab only
This commit is contained in:
parent
81422e22be
commit
7eb564feea
|
|
@ -4,6 +4,7 @@ using UnityEditorInternal;
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
|
|
@ -107,6 +108,21 @@ namespace VRM
|
|||
var prefabPath = parent.Parent.Child(parent.FileNameWithoutExtension + ".prefab");
|
||||
prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath.Value);
|
||||
}
|
||||
// once more, with string-based method. search same folder *.prefab
|
||||
if (prefab == null)
|
||||
{
|
||||
var parent = UniGLTF.UnityPath.FromUnityPath(assetPath).Parent;
|
||||
foreach (var file in Directory.EnumerateFiles(parent.FullPath))
|
||||
{
|
||||
var ext = Path.GetExtension(file).ToLower();
|
||||
if (ext == ".prefab")
|
||||
{
|
||||
var prefabPath = UniGLTF.UnityPath.FromFullpath(file);
|
||||
prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return prefab;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,38 +134,41 @@ namespace VRM
|
|||
// v0.45 Added. Binary flag
|
||||
EditorGUILayout.PropertyField(m_isBinaryProp, true);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
//m_mode = EditorGUILayout.Popup("SourceType", m_mode, MODES);
|
||||
m_mode = GUILayout.Toolbar(m_mode, MODES);
|
||||
switch (m_mode)
|
||||
if (m_targetObject.m_prefab != null)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ClipGUI();
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
if (GUILayout.Button("Clear"))
|
||||
EditorGUILayout.Space();
|
||||
//m_mode = EditorGUILayout.Popup("SourceType", m_mode, MODES);
|
||||
m_mode = GUILayout.Toolbar(m_mode, MODES);
|
||||
switch (m_mode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_changed = true;
|
||||
m_valuesProp.arraySize = 0;
|
||||
ClipGUI();
|
||||
}
|
||||
m_ValuesList.DoLayoutList();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (GUILayout.Button("Clear"))
|
||||
case 1:
|
||||
{
|
||||
m_changed = true;
|
||||
m_materialsProp.arraySize = 0;
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
m_changed = true;
|
||||
m_valuesProp.arraySize = 0;
|
||||
}
|
||||
m_ValuesList.DoLayoutList();
|
||||
}
|
||||
m_MaterialValuesList.DoLayoutList();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
m_changed = true;
|
||||
m_materialsProp.arraySize = 0;
|
||||
}
|
||||
m_MaterialValuesList.DoLayoutList();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_serializedObject.ApplyModifiedProperties();
|
||||
|
|
@ -231,6 +234,10 @@ namespace VRM
|
|||
// すべてのSkinnedMeshRendererを列挙する
|
||||
foreach (var renderer in m_items.Select(x => x.SkinnedMeshRenderer))
|
||||
{
|
||||
if(renderer==null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var mesh = renderer.sharedMesh;
|
||||
if (mesh != null && mesh.blendShapeCount > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,17 +13,18 @@ namespace VRM
|
|||
/// </summary>
|
||||
public static class VRMMeshIntegratorUtility
|
||||
{
|
||||
public static void FollowBlendshapeRendererChange(List<MeshIntegrationResult> results, GameObject root, string assetFolder)
|
||||
public static List<BlendShapeClip> FollowBlendshapeRendererChange(List<MeshIntegrationResult> results, GameObject root, string assetFolder)
|
||||
{
|
||||
var clips = new List<BlendShapeClip>();
|
||||
var proxy = root.GetComponent<VRMBlendShapeProxy>();
|
||||
if (proxy == null || proxy.BlendShapeAvatar == null)
|
||||
{
|
||||
return;
|
||||
return clips;
|
||||
}
|
||||
var result = results.FirstOrDefault(x => x.IntegratedRenderer.sharedMesh.blendShapeCount > 0);
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
return clips;
|
||||
}
|
||||
|
||||
var rendererDict = new Dictionary<string, SkinnedMeshRenderer>();
|
||||
|
|
@ -36,19 +37,19 @@ namespace VRM
|
|||
// copy modify and write
|
||||
var clipAssetPathList = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
var clips = new List<BlendShapeClip>();
|
||||
foreach (var src in proxy.BlendShapeAvatar.Clips)
|
||||
{
|
||||
if (src == null) continue;
|
||||
|
||||
// copy
|
||||
var clip = BlendShapeClip.Instantiate(src);
|
||||
clip.Prefab = null;
|
||||
var copy = ScriptableObject.CreateInstance<BlendShapeClip>();
|
||||
copy.CopyFrom(src);
|
||||
copy.Prefab = null;
|
||||
|
||||
// modify
|
||||
for (var i = 0; i < clip.Values.Length; ++i)
|
||||
for (var i = 0; i < copy.Values.Length; ++i)
|
||||
{
|
||||
var val = clip.Values[i];
|
||||
var val = copy.Values[i];
|
||||
if (rendererDict.ContainsKey(val.RelativePath))
|
||||
{
|
||||
var srcRenderer = rendererDict[val.RelativePath];
|
||||
|
|
@ -62,16 +63,16 @@ namespace VRM
|
|||
val.RelativePath = dstPath;
|
||||
val.Index = newIndex;
|
||||
}
|
||||
clip.Values[i] = val;
|
||||
copy.Values[i] = val;
|
||||
}
|
||||
|
||||
// write
|
||||
var assetPath = $"{assetFolder}/{clip.name}.asset";
|
||||
var assetPath = $"{assetFolder}/{copy.name}.asset";
|
||||
sb.AppendLine($"write: {assetPath}");
|
||||
AssetDatabase.CreateAsset(clip, assetPath);
|
||||
AssetDatabase.CreateAsset(copy, assetPath);
|
||||
|
||||
clipAssetPathList.Add(assetPath);
|
||||
clips.Add(clip);
|
||||
clips.Add(copy);
|
||||
}
|
||||
Debug.Log(sb.ToString());
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ namespace VRM
|
|||
|
||||
{
|
||||
// create blendshape avatar & replace
|
||||
var copy = BlendShapeAvatar.CreateInstance<BlendShapeAvatar>();
|
||||
var copy = ScriptableObject.CreateInstance<BlendShapeAvatar>();
|
||||
copy.Clips.AddRange(clips);
|
||||
var assetPath = $"{assetFolder}/blendshape.asset";
|
||||
AssetDatabase.CreateAsset(copy, assetPath);
|
||||
|
|
@ -93,6 +94,8 @@ namespace VRM
|
|||
// assign
|
||||
proxy.BlendShapeAvatar = copy;
|
||||
}
|
||||
|
||||
return clips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ namespace VRM
|
|||
None,
|
||||
NoTarget,
|
||||
HasParent,
|
||||
NotPrefab,
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
|
|
@ -100,7 +101,6 @@ namespace VRM
|
|||
private void OnEnable()
|
||||
{
|
||||
Clear(HelpMessage.Ready, ValidationError.None);
|
||||
m_root = Selection.activeGameObject;
|
||||
OnValidate();
|
||||
}
|
||||
|
||||
|
|
@ -165,12 +165,19 @@ namespace VRM
|
|||
|
||||
void OnValidate()
|
||||
{
|
||||
isValid = false;
|
||||
if (m_root == null)
|
||||
{
|
||||
Clear(HelpMessage.SetTarget, ValidationError.NoTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_root.GetGameObjectType() != GameObjectType.AssetPrefab)
|
||||
{
|
||||
Clear(HelpMessage.SetTarget, ValidationError.NotPrefab);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_root.transform.parent != null)
|
||||
{
|
||||
Clear(HelpMessage.InvalidTarget, ValidationError.HasParent);
|
||||
|
|
@ -225,7 +232,7 @@ namespace VRM
|
|||
|
||||
/// 2022.05 仕様変更
|
||||
///
|
||||
/// * scene or prefab どっちでも動作する
|
||||
/// * prefab 専用
|
||||
/// * backup するのではなく 変更した copy を作成する。元は変えない
|
||||
/// * copy 先の統合前の renderer を disable で残さず destroy する
|
||||
/// * 実行すると mesh, blendshape, blendShape を新規に作成する
|
||||
|
|
@ -234,6 +241,11 @@ namespace VRM
|
|||
///
|
||||
void Integrate()
|
||||
{
|
||||
if (m_root.GetGameObjectType() != GameObjectType.AssetPrefab)
|
||||
{
|
||||
throw new Exception("for prefab only");
|
||||
}
|
||||
|
||||
String folder = "Assets";
|
||||
var prefab = m_root.GetPrefab();
|
||||
if (prefab != null)
|
||||
|
|
@ -276,7 +288,7 @@ namespace VRM
|
|||
}
|
||||
|
||||
// 統合した結果を反映した BlendShapeClip を作成して置き換える
|
||||
VRMMeshIntegratorUtility.FollowBlendshapeRendererChange(results, copy, assetFolder);
|
||||
var clips = VRMMeshIntegratorUtility.FollowBlendshapeRendererChange(results, copy, assetFolder);
|
||||
|
||||
// 用が済んだ 統合前 の renderer を削除する
|
||||
foreach (var result in results)
|
||||
|
|
@ -298,23 +310,27 @@ namespace VRM
|
|||
firstperson.Reset();
|
||||
}
|
||||
|
||||
if (prefab != null)
|
||||
// prefab
|
||||
var prefabPath = $"{assetFolder}/VrmIntegrated.prefab";
|
||||
Debug.Log(prefabPath);
|
||||
PrefabUtility.SaveAsPrefabAsset(copy, prefabPath, out bool success);
|
||||
if (!success)
|
||||
{
|
||||
// prefab
|
||||
var prefabPath = $"{assetFolder}/VrmIntegrated.prefab";
|
||||
Debug.Log(prefabPath);
|
||||
PrefabUtility.SaveAsPrefabAsset(copy, prefabPath, out bool success);
|
||||
if (!success)
|
||||
{
|
||||
throw new System.Exception($"PrefabUtility.SaveAsPrefabAsset: {prefabPath}");
|
||||
}
|
||||
|
||||
// destroy scene
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
throw new System.Exception($"PrefabUtility.SaveAsPrefabAsset: {prefabPath}");
|
||||
}
|
||||
else
|
||||
|
||||
// destroy scene
|
||||
UnityEngine.Object.DestroyImmediate(copy);
|
||||
|
||||
var prefabReference = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||||
foreach (var clip in clips)
|
||||
{
|
||||
// do nothing. keep scene
|
||||
var so = new SerializedObject(clip);
|
||||
so.Update();
|
||||
// clip.Prefab = copy;
|
||||
var prop = so.FindProperty("m_prefab");
|
||||
prop.objectReferenceValue = prefabReference;
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
|
|
@ -79,7 +80,7 @@ namespace VRM
|
|||
/// Preview 用のObject参照
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
GameObject m_prefab;
|
||||
public GameObject m_prefab;
|
||||
public GameObject Prefab
|
||||
{
|
||||
set { m_prefab = value; }
|
||||
|
|
@ -142,5 +143,15 @@ namespace VRM
|
|||
/// </summary>
|
||||
[SerializeField]
|
||||
public bool IsBinary;
|
||||
|
||||
public void CopyFrom(BlendShapeClip src)
|
||||
{
|
||||
IsBinary = src.IsBinary;
|
||||
MaterialValues = src.MaterialValues.ToArray();
|
||||
Values = src.Values.ToArray();
|
||||
Preset = src.Preset;
|
||||
name = src.name;
|
||||
Prefab = src.Prefab;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user