facebook twitter hatena line email

「Unity/VRM」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(準備)
(表情変更)
 
(同じ利用者による、間の7版が非表示)
行16: 行16:
 
</pre>
 
</pre>
 
Unityプロジェクトを開いて、Packagesの下に、VRMが、あれば成功。
 
Unityプロジェクトを開いて、Packagesの下に、VRMが、あれば成功。
 +
 +
===モデルを動的に読み込む場合===
 +
pathは適当。読み込み時間は7秒ぐらいかかる。
 +
<pre>
 +
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();
 +
    }
 +
}
 +
</pre>
 +
参考:https://zenn.dev/nishi/articles/c44fc709a7d575
 +
 +
===表情変更===
 +
笑顔に変更
 +
<pre>
 +
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},
 +
});
 +
</pre>
 +
 +
参考:https://vrm-c.github.io/UniVRM/ja/api/0_58_blendshape.html
 +
 +
* SetValuesは、推奨
 +
* ImmediatelySetValueは、非推奨っぽい。
 +
 +
===表情を徐々に変更===
 +
<pre>
 +
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},
 +
            });
 +
        }
 +
    }
 +
}
 +
</pre>

2022年12月18日 (日) 06:03時点における最新版

UnityでVRMを動かす方法

参考:https://konichallengelog.com/unity_vrm_lipsync/

人形素材をDLとインストール

  1. https://3d.nicovideo.jp/works/td32797 からDL
  2. DLしたdirを、UnityのAssets以下にドラッグ
  3. 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},
            });
        }
    }
}