Unity/VRM
提供: 初心者エンジニアの簡易メモ
UnityでVRMを動かす方法
参考:https://konichallengelog.com/unity_vrm_lipsync/
人形素材をDLとインストール
- https://3d.nicovideo.jp/works/td32797 からDL
- DLしたdirを、UnityのAssets以下にドラッグ
- VRM内の青色アイコンのPrefabを、ヒエラルキーにドラッグして、表示されればOK
UniVRMのインストール
Package/manifest.jsonのdependencies以下に、com.vrmc〜の4行追加
"dependencies": {
"com.vrmc.vrmshaders": "https://github.com/vrm-c/UniVRM.git?path=/Assets/VRMShaders#v0.107.0",
"com.vrmc.gltf": "https://github.com/vrm-c/UniVRM.git?path=/Assets/UniGLTF#v0.107.0",
"com.vrmc.univrm": "https://github.com/vrm-c/UniVRM.git?path=/Assets/VRM#v0.107.0",
"com.vrmc.vrm": "https://github.com/vrm-c/UniVRM.git?path=/Assets/VRM10#v0.107.0",
Unityプロジェクトを開いて、Packagesの下に、VRMが、あれば成功。
モデルを動的に読み込む場合
pathは適当。読み込み時間は7秒ぐらいかかる。
using UnityEngine;
using UniGLTF;
using VRM;
using VRMShaders;
public class SampleScene : MonoBehaviour
{
async void Start()
{
string path = Application.streamingAssetsPath + "/../Alicia_VRM/Alicia/VRM/AliciaSolid.vrm";
Debug.Log(path);
RuntimeGltfInstance instance = await VrmUtility.LoadAsync(path, new RuntimeOnlyAwaitCaller());
instance.ShowMeshes();
}
}
参考:https://zenn.dev/nishi/articles/c44fc709a7d575
表情変更
笑顔に変更
using UnityEngine;
using UniGLTF;
using VRM;
using VRMShaders;
VRMBlendShapeProxy proxy = vrmObj.GetComponent<VRMBlendShapeProxy>();
proxy.SetValues(new Dictionary<BlendShapeKey, float>
{
{BlendShapeKey.CreateFromPreset(BlendShapePreset.Joy), 1.0f},
});
参考:https://vrm-c.github.io/UniVRM/ja/api/0_58_blendshape.html
- SetValuesは、推奨
- ImmediatelySetValueは、非推奨っぽい。
表情を徐々に変更
using UnityEngine;
using UniGLTF;
using VRM;
using VRMShaders;
public class SampleScene : MonoBehaviour
{
[SerializeField] GameObject vrmObj;
void Start()
{
VrmStart();
}
void VrmStart()
{
float sec = 0;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.Angry));
sec += 0.5f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.A));
sec += 0.5f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.I));
sec += 0.5f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.U));
sec += 0.5f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.E));
sec += 0.5f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.O));
sec += 1f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.Fun));
sec += 1f;
StartCoroutine(DelayVRMBlend(sec, BlendShapePreset.Joy));
}
VRMBlendShapeProxy proxy;
IEnumerator DelayVRMBlend(float delay, BlendShapePreset preset)
{
yield return new WaitForSeconds(delay);
if (proxy == null)
{
proxy = vrmObj.GetComponent<VRMBlendShapeProxy>();
}
ResetBlendShape();
proxy.SetValues(new Dictionary<BlendShapeKey, float>
{
{BlendShapeKey.CreateFromPreset(preset), 1.0f},
});
}
// 初期化
void ResetBlendShape()
{
if (proxy != null)
{
proxy.SetValues(new Dictionary<BlendShapeKey, float>
{
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Neutral), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.A), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.I), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.U), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.E), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.O), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Blink), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Joy), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Angry), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Sorrow), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Fun), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.LookUp), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.LookDown), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.LookLeft), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.LookRight), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Blink_L), 0f},
{ BlendShapeKey.CreateFromPreset(BlendShapePreset.Blink_R), 0f},
});
}
}
}
