Files
beyond/Assets/Scripts/InvectorDerivatives/bGenericAction.cs
2024-11-20 15:21:28 +01:00

337 lines
14 KiB
C#

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.\n<b><size=12>You can use <color=red>vGenericActionReceiver</color> component to filter events by action name</size></b>",
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($"<b>GenericAction: </b>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($"<b>GenericAction: </b><color=blue>Holding Input</color> ");
}
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($"<b>GenericAction: </b>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($"<b>GenericAction: </b><color=blue>Holding Input</color>");
}
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;
}
}
}