mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-06 17:55:22 -05:00
158 lines
4.8 KiB
C#
158 lines
4.8 KiB
C#
using System.IO;
|
|
using UniGLTF;
|
|
using UnityEngine;
|
|
|
|
namespace VRM.RuntimeExporterSample
|
|
{
|
|
|
|
public class VRMRuntimeExporter : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
public bool UseNormalize = true;
|
|
|
|
[SerializeField]
|
|
public bool BakeBlendShapes = false;
|
|
|
|
GameObject m_model;
|
|
|
|
void OnGUI()
|
|
{
|
|
if (GUILayout.Button("Load"))
|
|
{
|
|
Load();
|
|
}
|
|
UseNormalize = GUILayout.Toggle(UseNormalize, "UseNormalize");
|
|
|
|
GUI.enabled = m_model != null;
|
|
|
|
if (GUILayout.Button("Add custom blend shape"))
|
|
{
|
|
AddBlendShapeClip(m_model);
|
|
}
|
|
|
|
if (GUILayout.Button("Export"))
|
|
{
|
|
Export(m_model, UseNormalize, BakeBlendShapes);
|
|
}
|
|
}
|
|
|
|
async void Load()
|
|
{
|
|
#if UNITY_STANDALONE_WIN
|
|
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
|
#elif UNITY_EDITOR
|
|
var path = UnityEditor.EditorUtility.OpenFilePanel("Open VRM", "", "vrm");
|
|
#else
|
|
var path = Application.dataPath + "/default.vrm";
|
|
#endif
|
|
if (string.IsNullOrEmpty(path))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var loaded = await VrmUtility.LoadAsync(path);
|
|
loaded.ShowMeshes();
|
|
loaded.EnableUpdateWhenOffscreen();
|
|
|
|
if (m_model != null)
|
|
{
|
|
GameObject.Destroy(m_model.gameObject);
|
|
}
|
|
|
|
m_model = loaded.gameObject;
|
|
}
|
|
|
|
static void AddBlendShapeClip(GameObject go)
|
|
{
|
|
// get or create blendshape proxy
|
|
var proxy = go.GetComponent<VRMBlendShapeProxy>();
|
|
if (proxy == null)
|
|
{
|
|
proxy = go.AddComponent<VRMBlendShapeProxy>();
|
|
}
|
|
|
|
// get or create blendshapeavatar
|
|
var avatar = proxy.BlendShapeAvatar;
|
|
if (avatar == null)
|
|
{
|
|
avatar = ScriptableObject.CreateInstance<BlendShapeAvatar>();
|
|
proxy.BlendShapeAvatar = avatar;
|
|
}
|
|
|
|
// add blendshape clip to avatar.Clips
|
|
var clip = ScriptableObject.CreateInstance<BlendShapeClip>();
|
|
var name = $"custom#{avatar.Clips.Count}";
|
|
UniGLTFLogger.Log($"Add {name}");
|
|
// unity asset name
|
|
clip.name = name;
|
|
// vrm export name
|
|
clip.BlendShapeName = name;
|
|
clip.Preset = BlendShapePreset.Unknown;
|
|
|
|
clip.IsBinary = false;
|
|
clip.Values = new BlendShapeBinding[]
|
|
{
|
|
new BlendShapeBinding
|
|
{
|
|
RelativePath = "mesh/face", // target Renderer relative path from root
|
|
Index = 0, // BlendShapeIndex in SkinnedMeshRenderer
|
|
Weight = 75f // BlendShape weight, range is [0-100]
|
|
},
|
|
};
|
|
clip.MaterialValues = new MaterialValueBinding[]
|
|
{
|
|
new MaterialValueBinding
|
|
{
|
|
MaterialName = "Alicia_body", // target_material_name
|
|
ValueName = "_Color", // target_material_property_name,
|
|
BaseValue = new Vector4(1, 1, 1, 1), // Target value when the Weight value of BlendShapeClip is 0
|
|
TargetValue = new Vector4(0, 0, 0, 1), // Target value when the Weight value of BlendShapeClip is 1
|
|
},
|
|
};
|
|
avatar.Clips.Add(clip);
|
|
|
|
// done
|
|
}
|
|
|
|
|
|
static void Export(GameObject model, bool useNormalize, bool bakeBlendShape)
|
|
{
|
|
//#if UNITY_STANDALONE_WIN
|
|
#if false
|
|
var path = FileDialogForWindows.SaveDialog("save VRM", Application.dataPath + "/export.vrm");
|
|
#else
|
|
var path = Application.dataPath + "/../export.vrm";
|
|
#endif
|
|
if (string.IsNullOrEmpty(path))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var bytes = useNormalize ? ExportCustom(model, false, bakeBlendShape) : ExportSimple(model);
|
|
|
|
File.WriteAllBytes(path, bytes);
|
|
UniGLTFLogger.Log($"export to {path}");
|
|
}
|
|
|
|
static byte[] ExportSimple(GameObject model)
|
|
{
|
|
var vrm = VRMExporter.Export(new UniGLTF.GltfExportSettings(), model, new RuntimeTextureSerializer());
|
|
var bytes = vrm.ToGlbBytes();
|
|
return bytes;
|
|
}
|
|
|
|
static byte[] ExportCustom(GameObject exportRoot, bool forceTPose, bool bakeBlendShape)
|
|
{
|
|
// normalize
|
|
VRMBoneNormalizer.Execute(exportRoot, forceTPose, bakeBlendShape);
|
|
|
|
return ExportSimple(exportRoot);
|
|
}
|
|
|
|
void OnExported(UniGLTF.glTF vrm)
|
|
{
|
|
UniGLTFLogger.Log("exported");
|
|
}
|
|
}
|
|
}
|