using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using DG.Tweening; namespace UDE_HAND_INTERACTION { [RequireComponent(typeof(HandInteraction))] public class FingerUseInteraction : MonoBehaviour { public HandInteraction PreposeInteraction; public Transform Trigger; [SerializeField] private SnapAxis Axis = SnapAxis.Z; [SerializeField] [Range(0f, 1f)] private float ReleaseThresold = 0.5f; [SerializeField] [Range(0f, 1f)] private float ActiveThresold = 0.7f; [SerializeField] private float TriggerProcessLength = 0.2f; public bool CoherentActive = false; [SerializeField, Space] private UnityEvent WhenUseActive; [SerializeField] private UnityEvent WhenUseDisable; private Vector3 OriginalPos; private Vector3 CurPos; private int AxisIndex = 0; private bool InUseActive = false; private Dictionary FingerRate = new(); // Start is called before the first frame update void Start() { GetComponent().SetUseInteract(); PreposeInteraction.SetUseInteract(); OriginalPos = Trigger.localPosition; switch(Axis) { case SnapAxis.X: AxisIndex = 0; break; case SnapAxis.Y: AxisIndex = 1; break; case SnapAxis.Z: AxisIndex = 2; break; } } public Quaternion[] FingerConfig(float Rate, int FingerIndex) { HandPose CurPose = GetComponent().HandPose; HandPose TarPose = PreposeInteraction.HandPose; int Index = FingerIndex * 3; Quaternion[] CurQuaternions = new Quaternion[3] { CurPose.JointRotations[Index], CurPose.JointRotations[Index + 1], CurPose.JointRotations[Index + 2] }; Quaternion[] TarQuaternions = new Quaternion[3] { TarPose.JointRotations[Index], TarPose.JointRotations[Index + 1], TarPose.JointRotations[Index + 2] }; FingerRate[FingerIndex] = Rate; float Res = 0; foreach(float rate in FingerRate.Values) { Res = Math.Max(Res, rate); } float UseRate = Mathf.Clamp01(Res); Vector3 Pos = OriginalPos; Pos[AxisIndex] += UseRate * TriggerProcessLength; CurPos = Pos; Trigger.DOLocalMove(Pos, 0.1f); Quaternion[] ResRot = new Quaternion[3]; for(int i = 0; i < 3; ++i) { ResRot[i] = Quaternion.Lerp(CurQuaternions[i], TarQuaternions[i], UseRate); } TriggerCheck(); return ResRot; } private void TriggerCheck() { if (Vector3.Distance(CurPos, OriginalPos) >= Math.Abs(TriggerProcessLength) * ActiveThresold && (!InUseActive || CoherentActive)) { InUseActive = true; WhenUseActive.Invoke(); Debug.Log("Use Active"); } else if (Vector3.Distance(CurPos, OriginalPos) <= Math.Abs(TriggerProcessLength) * ReleaseThresold && (InUseActive || CoherentActive)) { InUseActive = false; WhenUseDisable.Invoke(); Debug.Log("Use Release"); } } private void Update() { if (InUseActive && !GetComponentInParent().IsFollow) { InUseActive = false; WhenUseDisable.Invoke(); } } public void ResetInteraction() { FingerRate.Clear(); } } }