From 43033ae0ddcff4f235e5f2c0b338d4d3b4455b9e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 18 Aug 2023 17:35:03 +0900 Subject: [PATCH] =?UTF-8?q?Vrm10RuntimeLookAt=20=E3=82=84=E3=82=8A?= =?UTF-8?q?=E3=81=AA=E3=81=8A=E3=81=97=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Vrm10Runtime/Vrm10Runtime.cs | 36 +++----- .../Vrm10Runtime/Vrm10RuntimeLookAt.cs | 90 +++++++++++++++---- 2 files changed, 84 insertions(+), 42 deletions(-) diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index 599778319..24ea8a369 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -202,6 +202,12 @@ namespace UniVRM10 { Expression.SetWeight(k, v()); } + + // look at + if (VrmAnimation.LookAt.HasValue) + { + LookAt.SetLookAtInput(VrmAnimation.LookAt.Value); + } } // 2. Control Rig @@ -213,34 +219,16 @@ namespace UniVRM10 constraint.Process(); } - // 4. Gaze control - LookAtInput lookAtInput = default; - if (VrmAnimation != null && VrmAnimation.LookAt.HasValue) - { - // VrmAnimation から LookAt を供給される - lookAtInput = VrmAnimation.LookAt.Value; - } - else if (m_instance.LookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform + if (m_instance.LookAtTargetType == VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform && m_instance.LookAtTarget != null) { - // Transform 追跡で 視線を計算する - lookAtInput = new LookAtInput { WorldPosition = m_instance.LookAtTarget.position }; - } - else - { - // 事前に LookAt.SetYawPitchManually を呼び出し済みであることが期待される - lookAtInput = new LookAtInput { YawPitch = new LookAtEyeDirection(LookAt.Yaw, LookAt.Pitch, 0, 0) }; + // Transform 追跡で視線を生成する。 + // 値を上書きします。 + LookAt.SetLookAtInput(new LookAtInput { WorldPosition = m_instance.LookAtTarget.position }); } - LookAtEyeDirection eyeDirection = default; - if (lookAtInput.YawPitch.HasValue) - { - eyeDirection = lookAtInput.YawPitch.Value; - } - else if (lookAtInput.WorldPosition.HasValue) - { - eyeDirection = LookAt.Process(lookAtInput.WorldPosition.Value); - } + // 4. Gaze control + var eyeDirection = LookAt.Process(); // 5. Apply Expression // LookAt の角度制限などはこちらで処理されます。 diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs index db66cf427..4d140b3c5 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeLookAt.cs @@ -4,22 +4,8 @@ using UnityEngine; namespace UniVRM10 { - public sealed class Vrm10RuntimeLookAt + public sealed class Vrm10RuntimeLookAt : ILookAtEyeDirectionProvider { - public float Yaw { get; private set; } - public float Pitch { get; private set; } - /// - /// Yaw/Pitch 値を直接設定します。 - /// LookAtTargetTypes が SpecifiedTransform の場合、ここで設定しても値は上書きされます。 - /// - /// Headボーンのforwardに対するyaw角(度) - /// Headボーンのforwardに対するpitch角(度) - public void SetYawPitchManually(float yaw, float pitch) - { - Yaw = yaw; - Pitch = pitch; - } - private readonly VRM10ObjectLookAt _lookAt; private readonly Transform _head; private readonly Vector3 _lookAtOriginTransformLocalPosition; @@ -27,7 +13,23 @@ namespace UniVRM10 internal ILookAtEyeDirectionApplicable EyeDirectionApplicable { get; } + /// + /// 入力値。適宜更新可。 + /// + public LookAtInput LookAtInput { get; private set; } + + // LookAtInput をそのまま Set + public void SetLookAtInput(LookAtInput eyeInput) + { + LookAtInput = eyeInput; + } + + /// + /// 出力値。Process() のみが更新する + /// public LookAtEyeDirection EyeDirection { get; private set; } + public float Yaw => EyeDirection.LeftYaw; + public float Pitch => EyeDirection.LeftPitch; /// /// Transform that indicates the position center of eyes. @@ -64,12 +66,33 @@ namespace UniVRM10 } } - internal LookAtEyeDirection Process(Vector3 worldPosition) + internal LookAtEyeDirection Process() { LookAtOriginTransform.localPosition = _lookAtOriginTransformLocalPosition; LookAtOriginTransform.localRotation = _lookAtOriginTransformLocalRotation; - var (yaw, pitch) = CalculateYawPitchFromLookAtPosition(worldPosition); - return new LookAtEyeDirection(yaw, pitch, 0, 0); + + if (LookAtInput.YawPitch is LookAtEyeDirection dir) + { + EyeDirection = dir; + } + else if (LookAtInput.WorldPosition is Vector3 worldPosition) + { + // NOTE: 指定された Transform の位置を向くように Yaw/Pitch を計算して適用する + var (yaw, pitch) = CalculateYawPitchFromLookAtPosition(worldPosition); + EyeDirection = new LookAtEyeDirection(yaw, pitch, 0, 0); + } + return EyeDirection; + } + + /// + /// Yaw/Pitch 値を直接設定します。 + /// Vrm10Instance.LookAtTargetTypes が SpecifiedTransform の場合、ここで設定しても値は上書きされます。 + /// + /// Headボーンのforwardに対するyaw角(度) + /// Headボーンのforwardに対するpitch角(度) + public void SetYawPitchManually(float yaw, float pitch) + { + LookAtInput = new LookAtInput { YawPitch = new LookAtEyeDirection(yaw, pitch, 0, 0) }; } public (float Yaw, float Pitch) CalculateYawPitchFromLookAtPosition(Vector3 lookAtWorldPosition) @@ -89,5 +112,36 @@ namespace UniVRM10 return lookAtOrigin; } + + #region Obsolete + [Obsolete("Use " + nameof(LookAtOriginTransform))] + public Transform GetLookAtOrigin(Transform head) + { + return LookAtOriginTransform; + } + + [Obsolete("Use " + nameof(SetYawPitchManually))] + public void SetLookAtYawPitch(float yaw, float pitch) + { + SetYawPitchManually(yaw, pitch); + } + + [Obsolete("Use " + nameof(Yaw) + " & " + nameof(Pitch))] + public (float, float) GetLookAtYawPitch( + Transform head, + VRM10ObjectLookAt.LookAtTargetTypes lookAtTargetType, + Transform gaze) + { + switch (lookAtTargetType) + { + case VRM10ObjectLookAt.LookAtTargetTypes.SpecifiedTransform: + return CalculateYawPitchFromLookAtPosition(gaze.position); + case VRM10ObjectLookAt.LookAtTargetTypes.YawPitchValue: + return (Yaw, Pitch); + default: + throw new ArgumentOutOfRangeException(nameof(lookAtTargetType), lookAtTargetType, null); + } + } + #endregion } }