OVRLipSyncMicInput 사용 시 마이크를 간단히 선택하십시오.
OVRLipSyncMicInput을 사용할 때 마이크를 선택하는 것은 매우 번거롭다
OVRLipSync를 사용해 VRM 모델 입구를 이동하려고 할 때 마이크를 원활하게 전환하지 못한다.
OVRLipSyncMicInput.cs
사용하려면방송 전
재생 후
사용한 마이크의 맨 아래 항목
Selected Device
에 마이크를 배열하여 첫 번째 요소에 들어가는 문자열입니다.그걸로 움직이는 거야.전환하려면 만지작거리거나 외부에서 삽입해야 하기 때문에 삽입을 결정합니다.만든 물건
이번에 한 건 VRM 모형에 LipSync를 만들었기 때문에 그 부분을 포함하는 cs입니다.Unity Editor의 작업만 구상합니다.
VRMLipSyncContextMorphTarget.cs
VRMLipSyncContextMorphTarget.cs
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using VRM;
namespace Component
{
[RequireComponent(typeof(OVRLipSyncMicInput))]
[DefaultExecutionOrder(10000)]
public class VRMLipSyncContextMorphTarget : OVRLipSyncContext
{
[SerializeField] private VRMBlendShapeProxy shapeProxy;
[SerializeField, Range(0.0f, 2.0f)] private float visemesVolume = 2.0f;
[HideInInspector] public string selected;
private BlendShapePreset[] visemePresets = {
BlendShapePreset.Neutral,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.Unknown,
BlendShapePreset.A,
BlendShapePreset.E,
BlendShapePreset.I,
BlendShapePreset.O,
BlendShapePreset.U
};
private void Start()
{
var micInput = GetComponent<OVRLipSyncMicInput>();
micInput.StopMicrophone();
micInput.selectedDevice = selected;
micInput.StartMicrophone();
}
void LateUpdate()
{
if (shapeProxy == null) return;
var frame = GetCurrentPhonemeFrame();
var values = visemePresets.Select((preset, i) => BlendShapePairBuilder(preset, frame.Visemes[i]));
shapeProxy.SetValues(values);
}
private KeyValuePair<BlendShapeKey, float> BlendShapePairBuilder(BlendShapePreset preset, float viseme)
{
return new KeyValuePair<BlendShapeKey, float>(BlendShapeKey.CreateFromPreset(preset), viseme * visemesVolume);
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(VRMLipSyncContextMorphTarget))]
public class VRMLipSyncContextMorphTargetEditor : Editor
{
private VRMLipSyncContextMorphTarget vrmLipSyncContextMorphTarget;
private int selectedIndex;
private string selectedIndexKey = $"{nameof(VRMLipSyncContextMorphTarget)}.{nameof(selectedIndex)}";
void OnEnable()
{
vrmLipSyncContextMorphTarget = (VRMLipSyncContextMorphTarget)target;
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
EditorGUI.BeginChangeCheck();
selectedIndex = EditorPrefs.GetInt(selectedIndexKey);
var micDevices = Microphone.devices;
var label = "Select Microphone";
var index = micDevices.Length > 0 && selectedIndex < micDevices.Length ? EditorGUILayout.Popup(label, selectedIndex, micDevices) : -1;
if (!EditorGUI.EndChangeCheck()) return;
Undo.RecordObject(vrmLipSyncContextMorphTarget, nameof(VRMLipSyncContextMorphTarget));
selectedIndex = index;
EditorPrefs.SetInt(selectedIndexKey, selectedIndex);
vrmLipSyncContextMorphTarget.selected = micDevices[index];
}
}
#endif
}
Inspector로 표시하면 다음과 같습니다.그리고 마이크를 고를 때.
이렇게 하면 훨씬 수월해진다.
평이한 해설
VRM에 반영된 부분은 생략됩니다.
부터
OVRLipSyncMicInput.cs
[RequireComponent(typeof(OVRLipSyncMicInput))]
// OVRLipSyncMicInputのStart()の後に切り替えたいため
[DefaultExecutionOrder(10000)]
public class VRMLipSyncContextMorphTarget : OVRLipSyncContext
{
[SerializeField] private VRMBlendShapeProxy shapeProxy;
[SerializeField, Range(0.0f, 2.0f)] private float visemesVolume = 2.0f;
// Inspectorで選択したマイクの名前を保持する
[HideInInspector] public string selected;
~~~ 省略 ~~~
private void Start()
{
// OVRLipSyncMicInputの初期化が終わってるはずなので切り替え処理を入れる
var micInput = GetComponent<OVRLipSyncMicInput>();
micInput.StopMicrophone();
micInput.selectedDevice = selected;
micInput.StartMicrophone();
}
~~~ 省略 ~~~
다음 VRMLipSyncContextMorphTarget.cs
[CustomEditor(typeof(VRMLipSyncContextMorphTarget))]
public class VRMLipSyncContextMorphTargetEditor : Editor
{
private VRMLipSyncContextMorphTarget vrmLipSyncContextMorphTarget;
private int selectedIndex;
// EditorPrefsに保存するときのキー
private string selectedIndexKey = $"{nameof(VRMLipSyncContextMorphTarget)}.{nameof(selectedIndex)}";
void OnEnable()
{
vrmLipSyncContextMorphTarget = (VRMLipSyncContextMorphTarget)target;
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
EditorGUI.BeginChangeCheck();
selectedIndex = EditorPrefs.GetInt(selectedIndexKey);
// UnityEngineで用意されているマイクの取得処理
var micDevices = Microphone.devices;
var label = "Select Microphone";
// Inspectorで選択したマイクを取得する
var index = micDevices.Length > 0 && selectedIndex < micDevices.Length ? EditorGUILayout.Popup(label, selectedIndex, micDevices) : -1;
// Popupで変更がなければ処理を行わない
if (!EditorGUI.EndChangeCheck()) return;
Undo.RecordObject(vrmLipSyncContextMorphTarget, nameof(VRMLipSyncContextMorphTarget));
selectedIndex = index;
EditorPrefs.SetInt(selectedIndexKey, selectedIndex);
// VRMLipSyncContextMorphTargetに保持させる
vrmLipSyncContextMorphTarget.selected = micDevices[index];
}
}
총결산
오랜만에 Inspector 확장을 했는데 UI를 쉽게 선택할 수 있어서 너무 좋아요.만들면 사실 다른 Component에서도 바뀌는 기본값이 있지...?그렇게 생각하지만 생각하지 않기로 했다.
Reference
이 문제에 관하여(OVRLipSyncMicInput 사용 시 마이크를 간단히 선택하십시오.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mizotake/articles/52933725d6e24fd754f9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)