Skip to content

Instantly share code, notes, and snippets.

@toiro
Created October 2, 2018 20:40
Show Gist options
  • Save toiro/0c7fbc38fa6eda18fafce6ec9b7d8417 to your computer and use it in GitHub Desktop.
Save toiro/0c7fbc38fa6eda18fafce6ec9b7d8417 to your computer and use it in GitHub Desktop.
Oculus Lipsync Unity から VRM の BlendShapePreset を利用してリップシンクする。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRM;
public class OVRLipSyncVRMTarget : MonoBehaviour {
public VRMBlendShapeProxy VRM;
// smoothing amount
[Range(1, 100)]
[Tooltip("Smoothing of 1 will yield only the current predicted viseme, 100 will yield an extremely smooth viseme response.")]
public int smoothAmount = 70;
// Look for a lip-sync Context (should be set at the same level as this component)
private OVRLipSyncContextBase lipsyncContext = null;
private readonly static BlendShapePreset[] lipsyncClips =
{
BlendShapePreset.A,
BlendShapePreset.E,
BlendShapePreset.I,
BlendShapePreset.O,
BlendShapePreset.U,
};
// Use this for initialization
void Start () {
// morph target needs to be set manually; possibly other components will need the same
if (VRM == null)
{
Debug.LogError("OVRLipSyncVRMTarget.Start Error: " +
"Please set the target VRM Blend Shape Proxy to be controlled!");
return;
}
// make sure there is a phoneme context assigned to this object
lipsyncContext = GetComponent<OVRLipSyncContextBase>();
if (lipsyncContext == null)
{
Debug.LogError("OVRLipSyncVRMTarget.Start Error: " +
"No OVRLipSyncContext component on this object!");
}
else
{
// Send smoothing amount to context
lipsyncContext.Smoothing = smoothAmount;
}
}
// Update is called once per frame
void Update () {
if ((lipsyncContext != null) && (VRM != null))
{
// get the current viseme frame
OVRLipSync.Frame frame = lipsyncContext.GetCurrentPhonemeFrame();
if (frame != null)
{
SetVisemeToVRMTarget(frame);
}
// Update smoothing value
if (smoothAmount != lipsyncContext.Smoothing)
{
lipsyncContext.Smoothing = smoothAmount;
}
}
}
/// <summary>
/// Sets the viseme to VRM target.
/// </summary>
void SetVisemeToVRMTarget(OVRLipSync.Frame frame)
{
for (int i = 0; i < lipsyncClips.Length; i++)
{
VRM.SetValue(lipsyncClips[i], frame.Visemes[i + 10]);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment