OVRLipSyncMicInput 사용 시 마이크를 간단히 선택하십시오.

31487 단어 C#Unityvrmovrtech

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에서도 바뀌는 기본값이 있지...?그렇게 생각하지만 생각하지 않기로 했다.

좋은 웹페이지 즐겨찾기