Merge pull request #2464 from ousttrue/fix/expression_override

[1.0] Expression の override と binary の組み合わせの挙動を実装
This commit is contained in:
ousttrue 2024-10-24 17:06:30 +09:00 committed by GitHub
commit 3b4f72ed87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 28093 additions and 333 deletions

View File

@ -75,15 +75,45 @@ namespace UniVRM10
{
if (key.IsBlink)
{
actualWeights[key] = actualWeights[key] * blinkMultiplier;
if (_expressions[key].IsBinary)
{
if (blinkMultiplier < 1.0f)
{
actualWeights[key] = 0.0f;
}
}
else
{
actualWeights[key] = actualWeights[key] * blinkMultiplier;
}
}
else if (key.IsLookAt)
{
actualWeights[key] = actualWeights[key] * lookAtMultiplier;
if (_expressions[key].IsBinary)
{
if (lookAtMultiplier < 1.0f)
{
actualWeights[key] = 0.0f;
}
}
else
{
actualWeights[key] = actualWeights[key] * lookAtMultiplier;
}
}
else if (key.IsMouth)
{
actualWeights[key] = actualWeights[key] * mouthMultiplier;
if (_expressions[key].IsBinary)
{
if (mouthMultiplier < 1.0f)
{
actualWeights[key] = 0.0f;
}
}
else
{
actualWeights[key] = actualWeights[key] * mouthMultiplier;
}
}
}

View File

@ -0,0 +1,54 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!86 &8600000
CustomRenderTexture:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: FaceCameraTarget
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
m_ForcedFallbackFormat: 4
m_DownscaleFallback: 0
m_IsAlphaChannelOptional: 0
serializedVersion: 5
m_Width: 300
m_Height: 300
m_AntiAliasing: 1
m_MipCount: -1
m_DepthStencilFormat: 94
m_ColorFormat: 8
m_MipMap: 0
m_GenerateMips: 1
m_SRGB: 0
m_UseDynamicScale: 0
m_BindMS: 0
m_EnableCompatibleFormat: 1
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
m_Aniso: 0
m_MipBias: 0
m_WrapU: 1
m_WrapV: 1
m_WrapW: 1
m_Dimension: 2
m_VolumeDepth: 1
m_ShadowSamplingMode: 2
m_Material: {fileID: 0}
m_InitSource: 0
m_InitMaterial: {fileID: 0}
m_InitColor: {r: 1, g: 1, b: 1, a: 1}
m_InitTexture: {fileID: 0}
m_UpdateMode: 0
m_InitializationMode: 2
m_UpdateZoneSpace: 0
m_CurrentUpdateZoneSpace: 0
m_UpdateZones: []
m_UpdatePeriod: 0
m_ShaderPass: 0
m_CubemapFaceMask: 4294967295
m_DoubleBuffered: 0
m_WrapUpdateZones: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 30519662c19bd4842a70b1f1ea87a8be
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 8600000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -6,23 +7,27 @@ namespace UniVRM10.VRM10Viewer
{
public class VRM10AIUEO : MonoBehaviour
{
[SerializeField]
public Vrm10Instance Controller;
private void Reset()
{
Controller = GetComponent<Vrm10Instance>();
}
Coroutine m_coroutine;
[SerializeField]
float m_wait = 0.5f;
private void Awake()
public float Aa = 0.0f;
public float Ih = 0.0f;
public float Ou = 0.0f;
public float Ee = 0.0f;
public float Oh = 0.0f;
void SetWeight(ExpressionPreset preset, float value)
{
if (Controller == null)
switch (preset)
{
Controller = GetComponent<Vrm10Instance>();
case ExpressionPreset.aa: Aa = value; break;
case ExpressionPreset.ih: Ih = value; break;
case ExpressionPreset.ou: Ou = value; break;
case ExpressionPreset.ee: Ee = value; break;
case ExpressionPreset.oh: Oh = value; break;
default: break;
}
}
@ -30,17 +35,17 @@ namespace UniVRM10.VRM10Viewer
{
for (var value = 0.0f; value <= 1.0f; value += velocity)
{
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
SetWeight(preset, value);
yield return null;
}
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 1.0f);
SetWeight(preset, 1.0f);
yield return new WaitForSeconds(wait);
for (var value = 1.0f; value >= 0; value -= velocity)
{
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
SetWeight(preset, value);
yield return null;
}
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 0);
SetWeight(preset, 0);
yield return new WaitForSeconds(wait * 2);
}

View File

@ -9,23 +9,27 @@ namespace UniVRM10.VRM10Viewer
/// </summary>
public class VRM10AutoExpression : MonoBehaviour
{
[SerializeField]
public Vrm10Instance Controller;
private void Reset()
{
Controller = GetComponent<Vrm10Instance>();
}
Coroutine m_coroutine;
[SerializeField]
float m_wait = 0.5f;
private void Awake()
public float Happy = 0.0f;
public float Angry = 0.0f;
public float Sad = 0.0f;
public float Relaxed = 0.0f;
public float Surprised = 0.0f;
void SetWeight(ExpressionPreset preset, float value)
{
if (Controller == null)
switch (preset)
{
Controller = GetComponent<Vrm10Instance>();
case ExpressionPreset.happy: Happy = value; break;
case ExpressionPreset.angry: Angry = value; break;
case ExpressionPreset.sad: Sad = value; break;
case ExpressionPreset.relaxed: Relaxed = value; break;
case ExpressionPreset.surprised: Surprised = value; break;
default: break;
}
}
@ -33,17 +37,17 @@ namespace UniVRM10.VRM10Viewer
{
for (var value = 0.0f; value <= 1.0f; value += velocity)
{
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
SetWeight(preset, value);
yield return null;
}
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 1.0f);
SetWeight(preset, 1.0f);
yield return new WaitForSeconds(wait);
for (var value = 1.0f; value >= 0; value -= velocity)
{
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), value);
SetWeight(preset, value);
yield return null;
}
Controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(preset), 0);
SetWeight(preset, 0);
yield return new WaitForSeconds(wait * 2);
}

View File

@ -10,8 +10,6 @@ namespace UniVRM10.VRM10Viewer
/// </summary>
public class VRM10Blinker : MonoBehaviour
{
Vrm10Instance m_controller;
[FormerlySerializedAs("m_interVal")]
[SerializeField]
public float Interval = 5.0f;
@ -46,6 +44,8 @@ namespace UniVRM10.VRM10Viewer
}
}
public float BlinkValue = 0;
IEnumerator BlinkRoutine()
{
while (true)
@ -72,10 +72,10 @@ namespace UniVRM10.VRM10Viewer
break;
}
m_controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(ExpressionPreset.blink), value);
BlinkValue = value;
yield return null;
}
m_controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(ExpressionPreset.blink), 1.0f);
BlinkValue = 1.0f;
// wait...
yield return new WaitForSeconds(ClosingTime);
@ -91,16 +91,15 @@ namespace UniVRM10.VRM10Viewer
break;
}
m_controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(ExpressionPreset.blink), value);
BlinkValue = value;
yield return null;
}
m_controller.Runtime.Expression.SetWeight(ExpressionKey.CreateFromPreset(ExpressionPreset.blink), 0);
BlinkValue = 0;
}
}
private void OnEnable()
{
m_controller = GetComponent<Vrm10Instance>();
m_coroutine = StartCoroutine(BlinkRoutine());
}

View File

@ -7,73 +7,20 @@ namespace UniVRM10.VRM10Viewer
class Loaded : IDisposable
{
RuntimeGltfInstance m_instance;
Vrm10Instance m_controller;
public Vrm10Instance Instance => m_controller;
public Vrm10RuntimeControlRig ControlRig => m_controller.Runtime.ControlRig;
public Vrm10Runtime Runtime => m_controller.Runtime;
Vrm10Instance m_vrm;
public Vrm10Instance Instance => m_vrm;
public Vrm10RuntimeControlRig ControlRig => m_vrm.Runtime.ControlRig;
public Vrm10Runtime Runtime => m_vrm.Runtime;
VRM10AIUEO m_lipSync;
bool m_enableLipSyncValue;
public bool EnableLipSyncValue
{
set
{
if (m_enableLipSyncValue == value) return;
m_enableLipSyncValue = value;
if (m_lipSync != null)
{
m_lipSync.enabled = m_enableLipSyncValue;
}
}
}
VRM10AutoExpression m_autoExpression;
bool m_enableAutoExpressionValue;
public bool EnableAutoExpressionValue
{
set
{
if (m_enableAutoExpressionValue == value) return;
m_enableAutoExpressionValue = value;
if (m_autoExpression != null)
{
m_autoExpression.enabled = m_enableAutoExpressionValue;
}
}
}
VRM10Blinker m_blink;
bool m_enableBlinkValue;
public bool EnableBlinkValue
{
set
{
if (m_blink == value) return;
m_enableBlinkValue = value;
if (m_blink != null)
{
m_blink.enabled = m_enableBlinkValue;
}
}
}
public Loaded(RuntimeGltfInstance instance, Transform lookAtTarget)
public Loaded(RuntimeGltfInstance instance)
{
m_instance = instance;
m_controller = instance.GetComponent<Vrm10Instance>();
if (m_controller != null)
m_vrm = instance.GetComponent<Vrm10Instance>();
if (m_vrm != null)
{
// VRM
m_controller.UpdateType = Vrm10Instance.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
{
m_lipSync = instance.gameObject.AddComponent<VRM10AIUEO>();
m_blink = instance.gameObject.AddComponent<VRM10Blinker>();
m_autoExpression = instance.gameObject.AddComponent<VRM10AutoExpression>();
m_controller.LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform;
m_controller.LookAtTarget = lookAtTarget;
}
m_vrm.UpdateType = Vrm10Instance.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
m_vrm.LookAtTargetType = VRM10ObjectLookAt.LookAtTargetTypes.YawPitchValue;
}
var animation = instance.GetComponent<Animation>();
@ -90,4 +37,4 @@ namespace UniVRM10.VRM10Viewer
GameObject.Destroy(m_instance.gameObject);
}
}
}
}

View File

@ -25,7 +25,7 @@ namespace VRM.VRM10RokuroCamera
class _Rokuro
{
public float Yaw;
public float Yaw = 180.0f;
public float Pitch;
public float ShiftX;
public float ShiftY;
@ -71,11 +71,6 @@ namespace VRM.VRM10RokuroCamera
private List<Coroutine> _activeCoroutines = new List<Coroutine>();
private void OnEnable()
{
// left mouse drag
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(0, diff =>
{
_currentCamera.Rotate(diff.x * RotateSpeed, diff.y * RotateSpeed);
})));
// right mouse drag
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(1, diff =>
{

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
@ -11,8 +12,12 @@ namespace UniVRM10.VRM10Viewer
{
public class VRM10ViewerUI : MonoBehaviour
{
[SerializeField]
GameObject Root = default;
[SerializeField]
Text m_version = default;
[SerializeField]
Transform m_faceCamera = default;
[Header("UI")]
[SerializeField]
@ -27,34 +32,18 @@ namespace UniVRM10.VRM10Viewer
[SerializeField]
Toggle m_showBoxMan = default;
[SerializeField]
Toggle m_enableLipSync = default;
[SerializeField]
Toggle m_enableAutoBlink = default;
[SerializeField]
Toggle m_enableAutoExpression = default;
[SerializeField]
Toggle m_useAsync = default;
[SerializeField]
GameObject m_target = default;
[SerializeField]
TextAsset m_motion;
// springbone
[SerializeField]
[SerializeField, Header("springbone")]
Toggle m_useSpringboneSingelton = default;
[SerializeField]
Toggle m_springbonePause = default;
[SerializeField]
Toggle m_springboneScaling = default;
[SerializeField]
Slider m_springboneExternalX = default;
[SerializeField]
@ -67,7 +56,112 @@ namespace UniVRM10.VRM10Viewer
[SerializeField]
Button m_reconstructSpringBone = default;
GameObject Root = default;
[SerializeField, Header("expression")]
Toggle m_enableAutoExpression = default;
[Serializable]
class EmotionFields
{
public Slider m_expression;
public Toggle m_binary;
public bool m_useOverride;
public Dropdown m_overrideMouth;
public Dropdown m_overrideBlink;
public Dropdown m_overrideLookAt;
public void Reset(ObjectMap map, string name, bool useOveride)
{
m_expression = map.Get<Slider>($"Slider{name}");
m_binary = map.Get<Toggle>($"Binary{name}");
m_useOverride = useOveride;
if (useOveride)
{
m_overrideMouth = map.Get<Dropdown>($"Override{name}Mouth");
m_overrideBlink = map.Get<Dropdown>($"Override{name}Blink");
m_overrideLookAt = map.Get<Dropdown>($"Override{name}LookAt");
}
}
static int GetOverrideIndex(UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType value)
{
switch (value)
{
case UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType.none: return 0;
case UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType.block: return 1;
case UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType.blend: return 2;
default: return -1;
}
}
static UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType ToOverrideType(int index)
{
switch (index)
{
case 0: return UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType.none;
case 1: return UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType.block;
case 2: return UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType.blend;
default: throw new ArgumentException();
}
}
public void OnLoad(VRM10Expression expression)
{
m_binary.isOn = expression.IsBinary;
if (m_useOverride)
{
m_overrideMouth.SetValueWithoutNotify(GetOverrideIndex(expression.OverrideMouth));
m_overrideBlink.SetValueWithoutNotify(GetOverrideIndex(expression.OverrideBlink));
m_overrideLookAt.SetValueWithoutNotify(GetOverrideIndex(expression.OverrideLookAt));
}
}
public void ApplyRuntime(VRM10Expression expression)
{
expression.IsBinary = m_binary.isOn;
if (m_useOverride)
{
expression.OverrideMouth = ToOverrideType(m_overrideMouth.value);
expression.OverrideBlink = ToOverrideType(m_overrideBlink.value);
expression.OverrideLookAt = ToOverrideType(m_overrideLookAt.value);
}
}
}
[SerializeField]
EmotionFields m_happy;
[SerializeField]
EmotionFields m_angry;
[SerializeField]
EmotionFields m_sad;
[SerializeField]
EmotionFields m_relaxed;
[SerializeField]
EmotionFields m_surprised;
[SerializeField]
Toggle m_enableLipSync = default;
[SerializeField]
EmotionFields m_lipAa = default;
[SerializeField]
EmotionFields m_lipIh = default;
[SerializeField]
EmotionFields m_lipOu = default;
[SerializeField]
EmotionFields m_lipEe = default;
[SerializeField]
EmotionFields m_lipOh = default;
[SerializeField]
Toggle m_enableAutoBlink = default;
[SerializeField]
EmotionFields m_blink = default;
[SerializeField]
GameObject m_lookAtTarget = default;
[SerializeField]
Toggle m_useLookAtTarget = default;
[SerializeField]
Slider m_yaw = default;
[SerializeField]
Slider m_pitch = default;
IVrm10Animation m_src = default;
public IVrm10Animation Motion
@ -123,28 +217,23 @@ namespace UniVRM10.VRM10Viewer
[SerializeField]
Text m_textDistributionOther = default;
public void Reset()
public void Reset(ObjectMap map)
{
#if UNITY_2022_3_OR_NEWER
var texts = GameObject.FindObjectsByType<Text>(FindObjectsSortMode.InstanceID);
#else
var texts = GameObject.FindObjectsOfType<Text>();
#endif
m_textModelTitle = texts.First(x => x.name == "Title (1)");
m_textModelVersion = texts.First(x => x.name == "Version (1)");
m_textModelAuthor = texts.First(x => x.name == "Author (1)");
m_textModelCopyright = texts.First(x => x.name == "Copyright (1)");
m_textModelContact = texts.First(x => x.name == "Contact (1)");
m_textModelReference = texts.First(x => x.name == "Reference (1)");
m_textModelTitle = map.Get<Text>("Title (1)");
m_textModelVersion = map.Get<Text>("Version (1)");
m_textModelAuthor = map.Get<Text>("Author (1)");
m_textModelCopyright = map.Get<Text>("Copyright (1)");
m_textModelContact = map.Get<Text>("Contact (1)");
m_textModelReference = map.Get<Text>("Reference (1)");
m_textPermissionAllowed = texts.First(x => x.name == "AllowedUser (1)");
m_textPermissionViolent = texts.First(x => x.name == "Violent (1)");
m_textPermissionSexual = texts.First(x => x.name == "Sexual (1)");
m_textPermissionCommercial = texts.First(x => x.name == "Commercial (1)");
m_textPermissionOther = texts.First(x => x.name == "Other (1)");
m_textPermissionAllowed = map.Get<Text>("AllowedUser (1)");
m_textPermissionViolent = map.Get<Text>("Violent (1)");
m_textPermissionSexual = map.Get<Text>("Sexual (1)");
m_textPermissionCommercial = map.Get<Text>("Commercial (1)");
m_textPermissionOther = map.Get<Text>("Other (1)");
m_textDistributionLicense = texts.First(x => x.name == "LicenseType (1)");
m_textDistributionOther = texts.First(x => x.name == "OtherLicense (1)");
m_textDistributionLicense = map.Get<Text>("LicenseType (1)");
m_textDistributionOther = map.Get<Text>("OtherLicense (1)");
#if UNITY_2022_3_OR_NEWER
var images = GameObject.FindObjectsByType<RawImage>(FindObjectsSortMode.InstanceID);
@ -230,22 +319,11 @@ namespace UniVRM10.VRM10Viewer
[SerializeField]
ToggleGroup ToggleMotion = default;
public void Reset()
public void Reset(ObjectMap map)
{
#if UNITY_2022_3_OR_NEWER
var toggles = GameObject.FindObjectsByType<Toggle>(FindObjectsSortMode.InstanceID);
#else
var toggles = GameObject.FindObjectsOfType<Toggle>();
#endif
ToggleMotionTPose = toggles.First(x => x.name == "TPose");
ToggleMotionBVH = toggles.First(x => x.name == "BVH");
#if UNITY_2022_3_OR_NEWER
var groups = GameObject.FindObjectsByType<ToggleGroup>(FindObjectsSortMode.InstanceID);
#else
var groups = GameObject.FindObjectsOfType<ToggleGroup>();
#endif
ToggleMotion = groups.First(x => x.name == "_Motion_");
ToggleMotionTPose = map.Get<Toggle>("TPose");
ToggleMotionBVH = map.Get<Toggle>("BVH");
ToggleMotion = map.Get<ToggleGroup>("_Motion_");
}
public bool IsTPose
@ -261,47 +339,71 @@ namespace UniVRM10.VRM10Viewer
[SerializeField]
UIFields m_ui = default;
class ObjectMap
{
Dictionary<string, GameObject> _map = new();
public IReadOnlyDictionary<string, GameObject> Objects => _map;
public ObjectMap(GameObject root)
{
foreach (var x in root.GetComponentsInChildren<Transform>())
{
_map[x.name] = x.gameObject;
}
}
public T Get<T>(string name) where T : Component
{
return _map[name].GetComponent<T>();
}
}
private void Reset()
{
#if UNITY_2022_3_OR_NEWER
var buttons = GameObject.FindObjectsByType<Button>(FindObjectsSortMode.InstanceID);
#else
var buttons = GameObject.FindObjectsOfType<Button>();
#endif
m_openModel = buttons.First(x => x.name == "OpenModel");
m_openMotion = buttons.First(x => x.name == "OpenMotion");
m_pastePose = buttons.First(x => x.name == "PastePose");
var map = new ObjectMap(gameObject);
Root = map.Objects["Root"];
m_openModel = map.Get<Button>("OpenModel");
m_openMotion = map.Get<Button>("OpenMotion");
m_pastePose = map.Get<Button>("PastePose");
m_showBoxMan = map.Get<Toggle>("ShowBoxMan");
m_useAsync = map.Get<Toggle>("UseAsync");
m_useSpringboneSingelton = map.Get<Toggle>("UseSingleton");
m_springbonePause = map.Get<Toggle>("PauseSpringBone");
m_resetSpringBone = map.Get<Button>("ResetSpringBone");
m_reconstructSpringBone = map.Get<Button>("ReconstructSpringBone");
m_version = map.Get<Text>("VrmVersion");
m_texts.Reset(map);
m_ui.Reset(map);
m_springboneScaling = map.Get<Toggle>("ScalingSpringBone");
m_springboneExternalX = map.Get<Slider>("SliderExternalX");
m_springboneExternalY = map.Get<Slider>("SliderExternalY");
m_springboneExternalZ = map.Get<Slider>("SliderExternalZ");
m_enableAutoExpression = map.Get<Toggle>("EnableAutoExpression");
m_happy.Reset(map, "Happy", true);
m_angry.Reset(map, "Angry", true);
m_sad.Reset(map, "Sad", true);
m_relaxed.Reset(map, "Relaxed", true);
m_surprised.Reset(map, "Surprised", true);
m_enableLipSync = map.Get<Toggle>("EnableLipSync");
m_lipAa.Reset(map, "Aa", false);
m_lipIh.Reset(map, "Ih", false);
m_lipOu.Reset(map, "Ou", false);
m_lipEe.Reset(map, "Ee", false);
m_lipOh.Reset(map, "Oh", false);
m_enableAutoBlink = map.Get<Toggle>("EnableAutoBlink");
m_blink.Reset(map, "Blink", false);
m_useLookAtTarget = map.Get<Toggle>("UseLookAtTarget");
m_yaw = map.Get<Slider>("SliderYaw");
m_pitch = map.Get<Slider>("SliderPitch");
#if UNITY_2022_3_OR_NEWER
var toggles = GameObject.FindObjectsByType<Toggle>(FindObjectsSortMode.InstanceID);
m_lookAtTarget = GameObject.FindFirstObjectByType<VRM10TargetMover>().gameObject;
#else
var toggles = GameObject.FindObjectsOfType<Toggle>();
#endif
m_showBoxMan = toggles.First(x => x.name == "ShowBoxMan");
m_enableLipSync = toggles.First(x => x.name == "EnableLipSync");
m_enableAutoBlink = toggles.First(x => x.name == "EnableAutoBlink");
m_enableAutoExpression = toggles.First(x => x.name == "EnableAutoExpression");
m_useAsync = toggles.First(x => x.name == "UseAsync");
m_useSpringboneSingelton = toggles.First(x => x.name == "UseSingleton");
m_springbonePause = toggles.First(x => x.name == "PauseSpringBone");
m_resetSpringBone = buttons.First(x => x.name == "ResetSpringBone");
#if UNITY_2022_3_OR_NEWER
var texts = GameObject.FindObjectsByType<Text>(FindObjectsSortMode.InstanceID);
#else
var texts = GameObject.FindObjectsOfType<Text>();
#endif
m_version = texts.First(x => x.name == "VrmVersion");
m_texts.Reset();
m_ui.Reset();
#if UNITY_2022_3_OR_NEWER
m_target = GameObject.FindFirstObjectByType<VRM10TargetMover>().gameObject;
#else
m_target = GameObject.FindObjectOfType<VRM10TargetMover>().gameObject;
m_lookAtTarget = GameObject.FindObjectOfType<VRM10TargetMover>().gameObject;
#endif
}
@ -362,8 +464,16 @@ namespace UniVRM10.VRM10Viewer
}
}
VRM10AutoExpression m_autoEmotion;
VRM10Blinker m_autoBlink;
VRM10AIUEO m_autoLipsync;
private void Start()
{
m_autoEmotion = gameObject.AddComponent<VRM10AutoExpression>();
m_autoBlink = gameObject.AddComponent<VRM10Blinker>();
m_autoLipsync = gameObject.AddComponent<VRM10AIUEO>();
m_version.text = string.Format("VRMViewer {0}.{1}",
VRM10SpecVersion.MAJOR, VRM10SpecVersion.MINOR);
@ -415,9 +525,7 @@ namespace UniVRM10.VRM10Viewer
if (m_loaded != null)
{
m_loaded.EnableLipSyncValue = m_enableLipSync.isOn;
m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn;
m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn;
var vrm = m_loaded.Instance;
if (m_loaded.Runtime != null)
{
@ -431,13 +539,103 @@ namespace UniVRM10.VRM10Viewer
m_loaded.Runtime.VrmAnimation = Motion;
}
m_loaded.Runtime.SpringBone.SetModelLevel(m_loaded.Instance.transform, new BlittableModelLevel
m_loaded.Runtime.SpringBone.SetModelLevel(vrm.transform, new BlittableModelLevel
{
ExternalForce = new Vector3(m_springboneExternalX.value, m_springboneExternalY.value, m_springboneExternalZ.value),
StopSpringBoneWriteback = m_springbonePause.isOn,
SupportsScalingAtRuntime = m_springboneScaling.isOn,
});
}
m_happy.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Happy);
m_angry.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Angry);
m_sad.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Sad);
m_relaxed.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Relaxed);
m_surprised.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Surprised);
m_lipAa.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Aa);
m_lipIh.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Ih);
m_lipOu.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Ou);
m_lipEe.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Ee);
m_lipOh.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Oh);
m_blink.ApplyRuntime(m_loaded.Instance.Vrm.Expression.Blink);
if (m_enableAutoExpression.isOn)
{
vrm.Runtime.Expression.SetWeight(ExpressionKey.Happy, m_autoEmotion.Happy);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Angry, m_autoEmotion.Angry);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Sad, m_autoEmotion.Sad);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Relaxed, m_autoEmotion.Relaxed);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Surprised, m_autoEmotion.Surprised);
m_happy.m_expression.SetValueWithoutNotify(m_autoEmotion.Happy);
m_angry.m_expression.SetValueWithoutNotify(m_autoEmotion.Angry);
m_sad.m_expression.SetValueWithoutNotify(m_autoEmotion.Sad);
m_relaxed.m_expression.SetValueWithoutNotify(m_autoEmotion.Relaxed);
m_surprised.m_expression.SetValueWithoutNotify(m_autoEmotion.Surprised);
}
else
{
vrm.Runtime.Expression.SetWeight(ExpressionKey.Happy, m_happy.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Angry, m_angry.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Sad, m_sad.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Relaxed, m_relaxed.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Surprised, m_surprised.m_expression.value);
}
if (m_enableLipSync.isOn)
{
vrm.Runtime.Expression.SetWeight(ExpressionKey.Aa, m_autoLipsync.Aa);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Ih, m_autoLipsync.Ih);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Ou, m_autoLipsync.Ou);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Ee, m_autoLipsync.Ee);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Oh, m_autoLipsync.Oh);
m_lipAa.m_expression.SetValueWithoutNotify(m_autoLipsync.Aa);
m_lipIh.m_expression.SetValueWithoutNotify(m_autoLipsync.Ih);
m_lipOu.m_expression.SetValueWithoutNotify(m_autoLipsync.Ou);
m_lipEe.m_expression.SetValueWithoutNotify(m_autoLipsync.Ee);
m_lipOh.m_expression.SetValueWithoutNotify(m_autoLipsync.Oh);
}
else
{
vrm.Runtime.Expression.SetWeight(ExpressionKey.Aa, m_lipAa.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Ih, m_lipIh.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Ou, m_lipOu.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Ee, m_lipEe.m_expression.value);
vrm.Runtime.Expression.SetWeight(ExpressionKey.Oh, m_lipOh.m_expression.value);
}
if (m_enableAutoBlink.isOn)
{
vrm.Runtime.Expression.SetWeight(ExpressionKey.Blink, m_autoBlink.BlinkValue);
m_blink.m_expression.SetValueWithoutNotify(m_autoBlink.BlinkValue);
}
else
{
vrm.Runtime.Expression.SetWeight(ExpressionKey.Blink, m_blink.m_expression.value);
}
if (m_useLookAtTarget.isOn)
{
var (yaw, pitch) = vrm.Runtime.LookAt.CalculateYawPitchFromLookAtPosition(m_lookAtTarget.transform.position);
vrm.Runtime.LookAt.SetYawPitchManually(yaw, pitch);
m_yaw.value = yaw;
m_pitch.value = pitch;
}
else
{
vrm.Runtime.LookAt.SetYawPitchManually(m_yaw.value, m_pitch.value);
}
if (vrm.TryGetBoneTransform(HumanBodyBones.Head, out var head))
{
var initLocarlRotation = vrm.DefaultTransformStates[head].LocalRotation;
var r = head.rotation * Quaternion.Inverse(initLocarlRotation);
var pos = head.position
+ (r * Vector3.forward * 0.7f)
+ (r * Vector3.up * 0.07f)
;
m_faceCamera.position = pos;
m_faceCamera.rotation = r;
}
}
}
@ -596,8 +794,20 @@ namespace UniVRM10.VRM10Viewer
var instance = vrm10Instance.GetComponent<RuntimeGltfInstance>();
instance.ShowMeshes();
instance.EnableUpdateWhenOffscreen();
m_loaded = new Loaded(instance, m_target.transform);
m_loaded = new Loaded(instance);
m_showBoxMan.isOn = false;
m_happy.OnLoad(m_loaded.Instance.Vrm.Expression.Happy);
m_angry.OnLoad(m_loaded.Instance.Vrm.Expression.Angry);
m_sad.OnLoad(m_loaded.Instance.Vrm.Expression.Sad);
m_relaxed.OnLoad(m_loaded.Instance.Vrm.Expression.Relaxed);
m_surprised.OnLoad(m_loaded.Instance.Vrm.Expression.Surprised);
m_lipAa.OnLoad(m_loaded.Instance.Vrm.Expression.Aa);
m_lipIh.OnLoad(m_loaded.Instance.Vrm.Expression.Ih);
m_lipOu.OnLoad(m_loaded.Instance.Vrm.Expression.Ou);
m_lipEe.OnLoad(m_loaded.Instance.Vrm.Expression.Ee);
m_lipOh.OnLoad(m_loaded.Instance.Vrm.Expression.Oh);
m_blink.OnLoad(m_loaded.Instance.Vrm.Expression.Blink);
}
catch (Exception ex)
{

View File

@ -17,6 +17,9 @@ namespace VRM.SimpleViewer
/// </summary>
public class ViewerUI : MonoBehaviour
{
[SerializeField]
TextFields m_texts = default;
#region UI
[SerializeField]
Text m_version = default;
@ -146,9 +149,6 @@ namespace VRM.SimpleViewer
}
}
[SerializeField]
TextFields m_texts = default;
[Serializable]
class UIFields
{