using System; using System.Collections.Generic; using System.Linq; using SLSFramework.General; using SLSUtilities.FunctionalAnimation; using UnityEngine; using UnityEngine.Serialization; namespace Cielonos.MainGame.Characters { public partial class AnimationSubcontrollerBase : SubcontrollerBase { public Animator animator; public Dictionary disruptionStatus; public bool isDuringRootMotion; public bool isDisablingMoveXZ; public bool isDisablingMoveY; public BaseAnimationGroup defaultAnimationGroup; public FunctionalAnimationSubmodule fullBodyFuncAnimSm; public Dictionary> registeredFunctions; public List lastFrameIntervals { get; private set; } public List currentIntervals { get; private set; } public override void Initialize() { base.Initialize(); fullBodyFuncAnimSm = new FunctionalAnimationSubmodule(this, "FullBodyAction"); registeredFunctions = new Dictionary>(); defaultAnimationGroup?.SetUp(this); disruptionStatus = new Dictionary() { { DisruptionType.NormalExternal, false }, { DisruptionType.NormalAction, false }, { DisruptionType.Movement, false } }; lastFrameIntervals = new List(); currentIntervals = new List(); RegisterDefaultFunctions(); } protected virtual void Update() { fullBodyFuncAnimSm?.UpdateTime(); UpdateIntervalInfo(); } protected virtual void LateUpdate() { fullBodyFuncAnimSm?.UpdateEvents(); } } public partial class AnimationSubcontrollerBase { protected virtual void UpdateIntervalInfo() { if (fullBodyFuncAnimSm?.currentRuntimeFuncAnim == null) { isDuringRootMotion = false; return; } lastFrameIntervals = currentIntervals; currentIntervals = fullBodyFuncAnimSm.currentRuntimeFuncAnim.GetEnablingIntervals(); disruptionStatus[DisruptionType.NormalExternal] = currentIntervals.Any(interval => interval.intervalType == IntervalType.ExternalDisruption); disruptionStatus[DisruptionType.NormalAction] = currentIntervals.Any(interval => interval.intervalType == IntervalType.ActionDisruption); disruptionStatus[DisruptionType.Movement] = currentIntervals.Any(interval => interval.intervalType == IntervalType.MovementDisruption); isDuringRootMotion = currentIntervals.Any(interval => interval.intervalType == IntervalType.RootMotion); } } public partial class AnimationSubcontrollerBase { public virtual void RegisterDefaultFunctions() { } } public partial class AnimationSubcontrollerBase { public virtual bool SetGetHitDisruption(DisruptionType disruptionType, BreakthroughType breakthroughType) { if (owner.reactionSc.breakthroughResistances[breakthroughType].value) { return false; } if (fullBodyFuncAnimSm.Stop(disruptionType)) { return true; } return false; } public virtual void PlayGetHitMediumAnimation(Vector3 direction = default) { int fullBodyActionIndex = animator.GetLayerIndex("FullBodyAction"); if (animator.HasState(fullBodyActionIndex, Animator.StringToHash("GetHitMediumFront"))) { float normalizedTransitionDuration = 0.1f / animator.GetCurrentAnimatorStateInfo(fullBodyActionIndex).length; if (direction == default) { animator.CrossFade("GetHitMediumFront", normalizedTransitionDuration, fullBodyActionIndex, 0); return; } direction.y = 0; direction = direction.normalized; float angle = Vector3.SignedAngle(transform.forward, direction, Vector3.up); if (angle > -45f && angle <= 45f) { animator.CrossFade("GetHitMediumBack", normalizedTransitionDuration, fullBodyActionIndex, 0); } else if (angle > 45f && angle <= 135f) { animator.CrossFade("GetHitMediumLeft", normalizedTransitionDuration, fullBodyActionIndex, 0); } else if (angle > -135f && angle <= -45f) { animator.CrossFade("GetHitMediumRight", normalizedTransitionDuration, fullBodyActionIndex, 0); } else { animator.CrossFade("GetHitMediumFront", normalizedTransitionDuration, fullBodyActionIndex, 0); } } else { if (animator.HasState(fullBodyActionIndex, Animator.StringToHash("GetHit"))) { animator.CrossFade("GetHit", 0.1f, fullBodyActionIndex, 0); } else { animator.CrossFade("Empty", 0f, fullBodyActionIndex, 0); } } } } }