using System.Collections; using UnityEngine; namespace Beyond { using Invector; using System; using System.Collections.Generic; using Invector.vCharacterController; using Invector.vCharacterController.vActions; [vClassHeader("bGENERIC ACTION", "Use the vTriggerGenericAction to trigger a simple animation.\nYou can use vGenericActionReceiver component to filter events by action name", iconName = "triggerIcon")] public class bGenericAction : vGenericAction { //public bool useFullBodyLayer = false; //private AnimatorStateInfo layerInfoInUse; //protected override void Awake() //{ // base.Awake(); // //because match target only works by default on base layer, and animations do not crossfade that well on that layer // if (useFullBodyLayer) // { // layerInfoInUse = tpInput.cc.fullBodyInfo; // } // else // { // layerInfoInUse = tpInput.cc.baseLayerInfo; // } // //tpInput.cc.animator.GetCurrentAnimatorStateInfo(triggerAction.animatorLayer); //.get(triggerAction.animatorLayer), 0, 1); //} protected override bool inActionAnimation { get { return !string.IsNullOrEmpty(triggerAction.playAnimation) && tpInput.cc.animator.GetCurrentAnimatorStateInfo(triggerAction.animatorLayer).IsName(triggerAction.playAnimation); // && layerInfoInUse.IsName(triggerAction.playAnimation); } } public override void TriggerActionInput() { if (triggerAction == null || !triggerAction.gameObject.activeInHierarchy) { return; } var bTriggerAction = triggerAction as bTriggerGenericAction; if (!bTriggerAction) { return; } // AutoAction if (triggerAction.inputType == vTriggerGenericAction.InputType.AutoAction && actionConditions) { TriggerActionEvents(); if (!bTriggerAction.useFadeOnMatchingToTarget) { TriggerAnimation(); } } // GetButtonDown else if (triggerAction.inputType == vTriggerGenericAction.InputType.GetButtonDown && actionConditions) { if (triggerAction.actionInput.GetButtonDown()) { TriggerActionEvents(); if (!bTriggerAction.useFadeOnMatchingToTarget) { if (bTriggerAction.animationDelay > 0) { StartCoroutine(StartAnimationDelayedCoroutine(bTriggerAction.animationDelay)); } else { TriggerAnimation(); } } else { if (FadeCanvasGroup.Instance) FadeCanvasGroup.Instance.OnFadeOutEnd.AddListener(TriggerAnimation); } } } // GetDoubleButton else if (triggerAction.inputType == vTriggerGenericAction.InputType.GetDoubleButton && actionConditions) { if (triggerAction.actionInput.GetDoubleButtonDown(triggerAction.doubleButtomTime)) { TriggerActionEvents(); if (!bTriggerAction.useFadeOnMatchingToTarget) { TriggerAnimation(); } } } // GetButtonTimer (Hold Button) else if (triggerAction.inputType == vTriggerGenericAction.InputType.GetButtonTimer) { if (_currentInputDelay <= 0) { var up = false; var t = 0f; // this mode will play the animation while you're holding the button if (triggerAction.playAnimationWhileHoldingButton) { TriggerActionEventsInput(); // call the OnFinishActionInput after the buttomTimer is concluded and reset player settings if (triggerAction.actionInput.GetButtonTimer(ref t, ref up, triggerAction.buttonTimer)) { if (debugMode) { Debug.Log($"GenericAction: Finish Action Input "); } triggerAction.UpdateButtonTimer(0); triggerAction.OnFinishActionInput.Invoke(); ResetActionState(); EndAction(); //ResetTriggerSettings(); } // trigger the Animation and the ActionEvents while your hold the button if (triggerAction && triggerAction.actionInput.inButtomTimer) { if (debugMode) { Debug.Log($"GenericAction: Holding Input "); } triggerAction.UpdateButtonTimer(t); if (!bTriggerAction.useFadeOnMatchingToTarget) { TriggerAnimation(); } } // call OnCancelActionInput if the button is released before ending the buttonTimer if (up && triggerAction) { CancelButtonTimer(); } } // this mode will play the animation after you finish holding the button else /*if (!doingAction)*/ { TriggerActionEventsInput(); // call the OnFinishActionInput after the buttomTimer is concluded and reset player settings if (triggerAction.actionInput.GetButtonTimer(ref t, ref up, triggerAction.buttonTimer)) { if (debugMode) { Debug.Log($"GenericAction: Finish Action Input "); } triggerAction.UpdateButtonTimer(0); triggerAction.OnFinishActionInput.Invoke(); // destroy the triggerAction if checked with destroyAfter if (!bTriggerAction.useFadeOnMatchingToTarget) { TriggerAnimation(); } } // trigger the ActionEvents while your hold the button if (triggerAction && triggerAction.actionInput.inButtomTimer) { if (debugMode) { Debug.Log($"GenericAction: Holding Input"); } triggerAction.UpdateButtonTimer(t); } // call OnCancelActionInput if the button is released before ending the buttonTimer if (up && triggerAction) { CancelButtonTimer(); } } } else { _currentInputDelay -= Time.deltaTime; } } } public override void TriggerAnimation() { if (FadeCanvasGroup.Instance) { FadeCanvasGroup.Instance.OnFadeOutEnd.RemoveListener(TriggerAnimation); } base.TriggerAnimation(); } //only for button down for now private IEnumerator StartAnimationDelayedCoroutine(float delay) { yield return new WaitForSeconds(delay); TriggerAnimation(); } protected override void EvaluateToTargetPosition() { var bTriggerAction = triggerAction as bTriggerGenericAction; if (!bTriggerAction) { return; } if (bTriggerAction.useFadeOnMatchingToTarget && !bTriggerAction.Faded) { return; } var matchTargetPosition = triggerAction.matchTarget.position; switch (triggerAction.avatarTarget) { case AvatarTarget.LeftHand: matchTargetPosition = (triggerAction.matchTarget.position - transform.rotation * transform.InverseTransformPoint(tpInput.animator.GetBoneTransform(HumanBodyBones.LeftHand) .position)); break; case AvatarTarget.RightHand: matchTargetPosition = (triggerAction.matchTarget.position - transform.rotation * transform.InverseTransformPoint(tpInput.animator.GetBoneTransform(HumanBodyBones.RightHand) .position)); break; case AvatarTarget.LeftFoot: matchTargetPosition = (triggerAction.matchTarget.position - transform.rotation * transform.InverseTransformPoint(tpInput.animator.GetBoneTransform(HumanBodyBones.LeftFoot) .position)); break; case AvatarTarget.RightFoot: matchTargetPosition = (triggerAction.matchTarget.position - transform.rotation * transform.InverseTransformPoint(tpInput.animator.GetBoneTransform(HumanBodyBones.RightFoot) .position)); break; } AnimationCurve XZ = triggerAction.matchPositionXZCurve; AnimationCurve Y = triggerAction.matchPositionYCurve; // float normalizedTime = Mathf.Clamp(layerInfoInUse.normalizedTime, 0, 1); float normalizedTime = Mathf.Clamp(tpInput.cc.animatorStateInfos.GetCurrentNormalizedTime(triggerAction.animatorLayer), 0, 1); var localRelativeToTarget = triggerAction.matchTarget.InverseTransformPoint(matchTargetPosition); if (!triggerAction.useLocalX) { localRelativeToTarget.x = triggerAction.matchTarget.InverseTransformPoint(transform.position).x; } if (!triggerAction.useLocalZ) { localRelativeToTarget.z = triggerAction.matchTarget.InverseTransformPoint(transform.position).z; } matchTargetPosition = triggerAction.matchTarget.TransformPoint(localRelativeToTarget); Vector3 rootPosition = tpInput.cc.animator.rootPosition; float evaluatedXZ = XZ.Evaluate(normalizedTime); float evaluatedY = Y.Evaluate(normalizedTime); if (evaluatedXZ < 1f) { rootPosition.x = Mathf.Lerp(rootPosition.x, matchTargetPosition.x, evaluatedXZ); rootPosition.z = Mathf.Lerp(rootPosition.z, matchTargetPosition.z, evaluatedXZ); finishPositionXZMatch = true; } else if (finishPositionXZMatch) { finishPositionXZMatch = false; rootPosition.x = matchTargetPosition.x; rootPosition.z = matchTargetPosition.z; bTriggerAction.OnPlayerMatchTargetPosition?.Invoke(); } if (evaluatedY < 1f) { rootPosition.y = Mathf.Lerp(rootPosition.y, matchTargetPosition.y, evaluatedY); finishPositionYMatch = true; } else if (finishPositionYMatch) { finishPositionYMatch = false; rootPosition.y = matchTargetPosition.y; } transform.position = rootPosition; } protected override void EvaluateToTargetRotation() { var targetEuler = new Vector3(transform.eulerAngles.x, triggerAction.transform.eulerAngles.y, transform.eulerAngles.z); Quaternion targetRotation = Quaternion.Euler(targetEuler); Quaternion rootRotation = tpInput.cc.animator.rootRotation; AnimationCurve rotationCurve = triggerAction.matchRotationCurve; float normalizedTime = tpInput.cc.animatorStateInfos.GetCurrentNormalizedTime(triggerAction.animatorLayer); //variable not used, makes no sense ? +animatorLayer=confusion // normalizedTime = Mathf.Clamp(layerInfoInUse.normalizedTime, 0, 1); float evaluatedCurve = rotationCurve.Evaluate(normalizedTime); if (evaluatedCurve < 1) { rootRotation = Quaternion.Lerp(rootRotation, targetRotation, evaluatedCurve); finishRotationMatch = true; } else if (finishRotationMatch) { finishRotationMatch = false; rootRotation = targetRotation; } transform.rotation = rootRotation; } } }