lot's of fixes, fixed animation retargetting, fixed FSM
This commit is contained in:
@@ -9,12 +9,29 @@ namespace Beyond
|
||||
{
|
||||
public class bThirdPersonController : vThirdPersonController
|
||||
{
|
||||
//public bool triggerDieBehaviour = false;
|
||||
protected bool m_isDashing;
|
||||
protected bool m_GodMode = false;
|
||||
|
||||
public bool m_ignoreTriggers = true;
|
||||
|
||||
[Header("Beyond's Custom Settings")]
|
||||
[Tooltip("When 'Use RootMotion' is checked, and this is true, the animation's root motion will control character rotation (for 8-way directional movement). If false, the script will rotate the character to face the input direction.")]
|
||||
public bool useAnimationBasedRotation = false;
|
||||
|
||||
[Header("Beyond's Strafe Combat Settings")]
|
||||
[Tooltip("The minimum horizontal input value to trigger a side roll instead of a forward/backward one.")]
|
||||
[Range(0.1f, 1.0f)]
|
||||
public float strafeRollInputThreshold = 0.3f;
|
||||
|
||||
[Tooltip("The name of the animation state to play when rolling forward while strafing. (This is now disabled)")]
|
||||
public string strafeRollForwardAnim = "Roll_Forward"; // Kept for reference, but won't be used
|
||||
[Tooltip("The name of the animation state to play when rolling backward while strafing.")]
|
||||
public string strafeRollBackwardAnim = "Roll_Backward";
|
||||
[Tooltip("The name of the animation state to play when rolling left while strafing.")]
|
||||
public string strafeRollLeftAnim = "Roll_Left";
|
||||
[Tooltip("The name of the animation state to play when rolling right while strafing.")]
|
||||
public string strafeRollRightAnim = "Roll_Right";
|
||||
|
||||
|
||||
public bool GodMode
|
||||
{
|
||||
get => m_GodMode;
|
||||
@@ -33,92 +50,121 @@ namespace Beyond
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
//var receiver = GetComponent<vAnimatorEventReceiver>();
|
||||
//var ev = new vAnimatorEvent();
|
||||
// ev.
|
||||
}
|
||||
|
||||
public void OnEvadeStart()
|
||||
protected override void RollBehavior()
|
||||
{
|
||||
if (m_GodMode)
|
||||
// If we are not strafing, use the default Invector roll behavior.
|
||||
if (!isStrafing)
|
||||
{
|
||||
base.RollBehavior();
|
||||
return;
|
||||
isImmortal = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEvadeEnd()
|
||||
{
|
||||
if (m_GodMode)
|
||||
// --- Custom Strafe Roll with Root Motion ---
|
||||
if (!isRolling)
|
||||
{
|
||||
return;
|
||||
isImmortal = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ActionsControl()
|
||||
{
|
||||
base.ActionsControl();
|
||||
m_isDashing = IsAnimatorTag("IsDashing");
|
||||
// We apply the root motion position change directly.
|
||||
Vector3 deltaPosition = new Vector3(animator.deltaPosition.x, 0f, animator.deltaPosition.z);
|
||||
Vector3 v = (deltaPosition / Time.deltaTime) * (1f - stopMoveWeight);
|
||||
|
||||
// Apply gravity to the roll if enabled
|
||||
if (rollUseGravity && animator.GetNormalizedTime(baseLayer) >= rollUseGravityTime)
|
||||
{
|
||||
v.y = _rigidbody.linearVelocity.y;
|
||||
}
|
||||
|
||||
_rigidbody.linearVelocity = v;
|
||||
}
|
||||
|
||||
public override void Roll()
|
||||
{
|
||||
OnRoll.Invoke();
|
||||
isRolling = true;
|
||||
|
||||
animator.CrossFadeInFixedTime("Roll", rollTransition, baseLayer);
|
||||
ReduceStamina(rollStamina, false);
|
||||
currentStaminaRecoveryDelay = 2f;
|
||||
// If we are strafing, use our custom directional logic.
|
||||
if (isStrafing)
|
||||
{
|
||||
TriggerStrafeRoll(strafeRollForwardAnim, strafeRollBackwardAnim, strafeRollLeftAnim, strafeRollRightAnim);
|
||||
}
|
||||
else // Otherwise, use the default free-locomotion roll.
|
||||
{
|
||||
OnRoll.Invoke();
|
||||
isRolling = true;
|
||||
animator.CrossFadeInFixedTime("Roll", rollTransition, baseLayer);
|
||||
ReduceStamina(rollStamina, false);
|
||||
currentStaminaRecoveryDelay = 2f;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Dash()
|
||||
{
|
||||
// The Dash logic now mirrors the Roll logic.
|
||||
if (isStrafing)
|
||||
{
|
||||
TriggerStrafeRoll(strafeRollForwardAnim, strafeRollBackwardAnim, strafeRollLeftAnim, strafeRollRightAnim);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnRoll.Invoke();
|
||||
isRolling = true;
|
||||
animator.CrossFadeInFixedTime("Dash", rollTransition, baseLayer);
|
||||
ReduceStamina(rollStamina, false);
|
||||
currentStaminaRecoveryDelay = 2f;
|
||||
}
|
||||
}
|
||||
|
||||
// This is the private helper method that contains the core logic for this feature.
|
||||
private void TriggerStrafeRoll(string forwardAnim, string backwardAnim, string leftAnim, string rightAnim)
|
||||
{
|
||||
OnRoll.Invoke();
|
||||
isRolling = true;
|
||||
|
||||
animator.CrossFadeInFixedTime("Dash", rollTransition, baseLayer);
|
||||
ReduceStamina(rollStamina, false);
|
||||
currentStaminaRecoveryDelay = 2f;
|
||||
|
||||
string animToPlay;
|
||||
|
||||
// Prioritize side rolls based on horizontal input.
|
||||
if (Mathf.Abs(horizontalSpeed) > strafeRollInputThreshold)
|
||||
{
|
||||
animToPlay = horizontalSpeed > 0 ? rightAnim : leftAnim;
|
||||
}
|
||||
// If horizontal input is not met, always default to the backward roll.
|
||||
// This effectively blocks the forward roll.
|
||||
else
|
||||
{
|
||||
animToPlay = backwardAnim;
|
||||
}
|
||||
|
||||
animator.CrossFadeInFixedTime(animToPlay, rollTransition, baseLayer);
|
||||
}
|
||||
|
||||
public void OnEvadeStart() { if (!m_GodMode) isImmortal = true; }
|
||||
public void OnEvadeEnd() { if (!m_GodMode) isImmortal = false; }
|
||||
public override void ActionsControl() { base.ActionsControl(); m_isDashing = IsAnimatorTag("IsDashing"); }
|
||||
|
||||
protected override void DeadAnimation()
|
||||
{
|
||||
if (!isDead)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!triggerDieBehaviour)
|
||||
{
|
||||
triggerDieBehaviour = true;
|
||||
DeathBehaviour();
|
||||
}
|
||||
|
||||
// death by animation
|
||||
if (!isDead) return;
|
||||
if (!triggerDieBehaviour) { triggerDieBehaviour = true; DeathBehaviour(); }
|
||||
if (deathBy == DeathBy.Animation)
|
||||
{
|
||||
int deadLayer = 0;
|
||||
|
||||
var info = animatorStateInfos.GetStateInfoUsingTag("Dead");
|
||||
if (info != null)
|
||||
{
|
||||
if (!animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.99f && groundDistance <= 0.15f)
|
||||
{
|
||||
RemoveComponents();
|
||||
}
|
||||
if (!animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.99f && groundDistance <= 0.15f) RemoveComponents();
|
||||
}
|
||||
}
|
||||
// death by animation & ragdoll after a time
|
||||
else if (deathBy == DeathBy.AnimationWithRagdoll)
|
||||
{
|
||||
int deadLayer = 0;
|
||||
var info = animatorStateInfos.GetStateInfoUsingTag("Dead");
|
||||
if (info != null)
|
||||
{
|
||||
if (!animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.8f)
|
||||
{
|
||||
onActiveRagdoll.Invoke(null);
|
||||
}
|
||||
if (!animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.8f) onActiveRagdoll.Invoke(null);
|
||||
}
|
||||
}
|
||||
// death by ragdoll
|
||||
else if (deathBy == DeathBy.Ragdoll)
|
||||
{
|
||||
onActiveRagdoll.Invoke(null);
|
||||
@@ -132,17 +178,8 @@ namespace Beyond
|
||||
|
||||
public override void ControlAnimatorRootMotion()
|
||||
{
|
||||
if (!this.enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isRolling)
|
||||
{
|
||||
RollBehavior();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.enabled) return;
|
||||
if (isRolling) { RollBehavior(); return; }
|
||||
if (customAction || lockAnimMovement)
|
||||
{
|
||||
StopCharacterWithLerp();
|
||||
@@ -151,65 +188,80 @@ namespace Beyond
|
||||
}
|
||||
else if (IsAnimatorTag("Attack"))
|
||||
{
|
||||
StopCharacterWithLerp();
|
||||
if (lockRotation) StopCharacterWithLerp();
|
||||
transform.position = animator.rootPosition;
|
||||
}
|
||||
// commented for test
|
||||
//else if (inputSmooth.magnitude == 0 && isGrounded && !isSliding)
|
||||
//{
|
||||
// if (!ignoreAnimatorMovement)
|
||||
// {
|
||||
// animator.ApplyBuiltinRootMotion();
|
||||
// transform.position = animator.rootPosition;
|
||||
// transform.rotation = animator.rootRotation;
|
||||
// }
|
||||
//}
|
||||
|
||||
if (useRootMotion)
|
||||
{
|
||||
MoveCharacter(moveDirection);
|
||||
}
|
||||
if (useRootMotion) MoveCharacter(moveDirection);
|
||||
}
|
||||
|
||||
protected override void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (!m_ignoreTriggers)
|
||||
onActionEnter.Invoke(other);
|
||||
if (!m_ignoreTriggers) onActionEnter.Invoke(other);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Call this in OnTriggerEnter or OnTriggerStay to check if enter in triggerActions
|
||||
/// </summary>
|
||||
/// <param name="other">collider trigger</param>
|
||||
protected override void OnTriggerStay(Collider other)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckForAutoCrouch(other);
|
||||
}
|
||||
catch (UnityException e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
}
|
||||
if (!m_ignoreTriggers)
|
||||
base.OnTriggerStay(other);
|
||||
try { CheckForAutoCrouch(other); }
|
||||
catch (UnityException e) { Debug.LogWarning(e.Message); }
|
||||
if (!m_ignoreTriggers) base.OnTriggerStay(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this in OnTriggerExit to check if exit of triggerActions
|
||||
/// </summary>
|
||||
/// <param name="other"></param>
|
||||
protected override void OnTriggerExit(Collider other)
|
||||
{
|
||||
AutoCrouchExit(other);
|
||||
if (!m_ignoreTriggers)
|
||||
base.OnTriggerExit(other);
|
||||
if (!m_ignoreTriggers) base.OnTriggerExit(other);
|
||||
}
|
||||
|
||||
//animation event handling
|
||||
void DrawWeaponLowLeft() { }
|
||||
|
||||
public override void ControlRotationType()
|
||||
{
|
||||
if (lockAnimRotation || lockRotation || customAction || isRolling) return;
|
||||
bool validInput = input != Vector3.zero || (isStrafing ? strafeSpeed.rotateWithCamera : freeSpeed.rotateWithCamera);
|
||||
if (validInput)
|
||||
{
|
||||
if (lockAnimMovement)
|
||||
{
|
||||
inputSmooth = Vector3.Lerp(inputSmooth, input, (isStrafing ? strafeSpeed.movementSmooth : freeSpeed.movementSmooth) * Time.deltaTime);
|
||||
}
|
||||
Vector3 dir = (isStrafing && isGrounded && (!isSprinting || sprintOnlyFree == false) || (freeSpeed.rotateWithCamera && input == Vector3.zero)) && rotateTarget ? rotateTarget.forward : moveDirection;
|
||||
if (isStrafing || !useAnimationBasedRotation) RotateToDirection(dir);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAnimatorParameters()
|
||||
{
|
||||
if (disableAnimations) return;
|
||||
animator.SetBool(vAnimatorParameters.IsStrafing, isStrafing);
|
||||
animator.SetBool(vAnimatorParameters.IsSprinting, isSprinting);
|
||||
animator.SetBool(vAnimatorParameters.IsSliding, isSliding && !isRolling);
|
||||
animator.SetBool(vAnimatorParameters.IsCrouching, isCrouching);
|
||||
animator.SetBool(vAnimatorParameters.IsGrounded, isGrounded);
|
||||
animator.SetBool(vAnimatorParameters.IsDead, isDead);
|
||||
animator.SetFloat(vAnimatorParameters.GroundDistance, groundDistance);
|
||||
animator.SetFloat(vAnimatorParameters.GroundAngle, GroundAngleFromDirection());
|
||||
if (!isGrounded) animator.SetFloat(vAnimatorParameters.VerticalVelocity, verticalVelocity);
|
||||
{
|
||||
if (isStrafing)
|
||||
{
|
||||
animator.SetFloat(vAnimatorParameters.InputHorizontal, horizontalSpeed, strafeSpeed.animationSmooth, Time.fixedDeltaTime);
|
||||
animator.SetFloat(vAnimatorParameters.InputVertical, verticalSpeed, strafeSpeed.animationSmooth, Time.fixedDeltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
animator.SetFloat(vAnimatorParameters.InputVertical, verticalSpeed, freeSpeed.animationSmooth, Time.fixedDeltaTime);
|
||||
animator.SetFloat(vAnimatorParameters.InputHorizontal, useAnimationBasedRotation ? horizontalSpeed : 0, freeSpeed.animationSmooth, Time.fixedDeltaTime);
|
||||
}
|
||||
animator.SetFloat(vAnimatorParameters.InputMagnitude, Mathf.LerpUnclamped(inputMagnitude, 0f, stopMoveWeight), isStrafing ? strafeSpeed.animationSmooth : freeSpeed.animationSmooth, Time.fixedDeltaTime);
|
||||
if (useLeanMovementAnim && inputMagnitude >= 0.1f)
|
||||
{
|
||||
animator.SetFloat(vAnimatorParameters.RotationMagnitude, rotationMagnitude, leanSmooth, Time.fixedDeltaTime);
|
||||
}
|
||||
else if (useTurnOnSpotAnim && inputMagnitude < 0.1f)
|
||||
{
|
||||
animator.SetFloat(vAnimatorParameters.RotationMagnitude, (float)System.Math.Round(rotationMagnitude, 2), rotationMagnitude == 0 ? 0.1f : 0.01f, Time.fixedDeltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user