using System.Collections; using System.Collections.Generic; using UnityEngine; /// /// Centralized animation manager class that handles playing animations /// and provides an abstraction layer between animation names and animation triggers. /// public class AnimationManager : MonoBehaviour { private Animator animator; private Dictionary animationMappings = new Dictionary(); [SerializeField] private float defaultTransitionDuration = 0.15f; // Default cross fade time [SerializeField] private float reactionTransitionDuration = 0.05f; // Faster transition for reactions // Track the current animation state private string currentAnimationName; private float hitAlignmentOffset = 0.1f; // Small offset to align hit reactions precisely private void Awake() { animator = GetComponent(); InitializeAnimationMappings(); } /// /// Initialize the mappings between logical animation names and actual animation triggers. /// This is where you can update animation names without changing the rest of the codebase. /// private void InitializeAnimationMappings() { // By default, map each animation name to itself foreach (var field in typeof(AnimationNames).GetFields()) { if (field.IsLiteral && !field.IsInitOnly) { string animName = (string)field.GetValue(null); animationMappings[animName] = animName; } } // MAP OLD ANIMATIONS TO NEW ANIMATIONS // ACTIVE ANIMATIONS - These are the only ones that will work // Basic Punch Moves - Keep only specified animations animationMappings[AnimationNames.Jab] = AnimationNames.Jab; animationMappings[AnimationNames.Haymaker] = AnimationNames.Haymaker; animationMappings[AnimationNames.SpinningBackfist] = AnimationNames.SpinningBackfist; animationMappings[AnimationNames.ElbowSmash] = AnimationNames.ElbowSmash; animationMappings[AnimationNames.AirPunch] = AnimationNames.AirPunch; // Basic Kick Moves - Keep only specified animations animationMappings[AnimationNames.LowKick] = AnimationNames.LowKick; animationMappings[AnimationNames.BasicKick] = AnimationNames.BasicKick; // Add SumoSlap from vicious moves to active list animationMappings[AnimationNames.SumoSlap] = AnimationNames.SumoSlap; // Weapon Animations - active when weapon equipped animationMappings[AnimationNames.BatOne] = AnimationNames.BatOne; animationMappings[AnimationNames.BatTwo] = AnimationNames.BatTwo; animationMappings[AnimationNames.HammerOne] = AnimationNames.HammerOne; animationMappings[AnimationNames.HammerTwo] = AnimationNames.HammerTwo; // Pickup animation animationMappings[AnimationNames.WeaponPickup] = AnimationNames.WeaponPickup; // Keep reaction animations for the active moves animationMappings[AnimationNames.JabReaction] = AnimationNames.JabReaction; animationMappings[AnimationNames.HaymakerReaction] = AnimationNames.HaymakerReaction; animationMappings[AnimationNames.SpinningBackfistReaction] = AnimationNames.SpinningBackfistReaction; animationMappings[AnimationNames.ElbowSmashReaction] = AnimationNames.ElbowSmashReaction; animationMappings[AnimationNames.AirPunchReaction] = AnimationNames.AirPunchReaction; animationMappings[AnimationNames.LowKickReaction] = AnimationNames.LowKickReaction; animationMappings[AnimationNames.SumoSlapReaction] = AnimationNames.SumoSlapReaction; // Map Input Actions to Animation Names for active animations animationMappings["Punch"] = AnimationNames.Jab; animationMappings["Strike"] = AnimationNames.Haymaker; animationMappings["Kick"] = AnimationNames.LowKick; // Direct mappings for active animations animationMappings["Jab"] = AnimationNames.Jab; animationMappings["Haymaker"] = AnimationNames.Haymaker; animationMappings["SpinningBackfist"] = AnimationNames.SpinningBackfist; animationMappings["ElbowSmash"] = AnimationNames.ElbowSmash; animationMappings["AirPunch"] = AnimationNames.AirPunch; animationMappings["LowKick"] = AnimationNames.LowKick; animationMappings["BasicKick"] = AnimationNames.BasicKick; animationMappings["SumoSlap"] = AnimationNames.SumoSlap; // COMMENTED ANIMATIONS - Kept for future implementation /* // Basic Punch Moves - Map old punches to new animations animationMappings[AnimationNames.Right] = AnimationNames.Haymaker; animationMappings[AnimationNames.LeftHook] = AnimationNames.Chop; animationMappings[AnimationNames.RightHook] = AnimationNames.SpinningBackfist; animationMappings[AnimationNames.LeftElbow] = AnimationNames.ElbowSmash; animationMappings[AnimationNames.RightElbow] = AnimationNames.ChargePunch; animationMappings[AnimationNames.RightBody] = AnimationNames.GroundPound; animationMappings[AnimationNames.PowerPunchLeft] = AnimationNames.Uppercut; animationMappings[AnimationNames.SupermanPunch] = AnimationNames.AirPunch; animationMappings[AnimationNames.SpecialBackfist] = AnimationNames.SpinningBackfist; animationMappings[AnimationNames.Chop] = AnimationNames.Chop; animationMappings[AnimationNames.GroundPound] = AnimationNames.GroundPound; animationMappings[AnimationNames.Uppercut] = AnimationNames.Uppercut; // Basic Kick Moves - Map old kicks to new animations animationMappings[AnimationNames.FrontKickRight] = AnimationNames.DropKick; animationMappings[AnimationNames.BodyKickRight] = AnimationNames.AirKick; animationMappings[AnimationNames.KneeRight] = AnimationNames.LowKick; animationMappings[AnimationNames.BackSideKick] = AnimationNames.Claymore; animationMappings[AnimationNames.LegKickRight] = AnimationNames.LowKick; animationMappings[AnimationNames.LegPowerKickRight] = AnimationNames.SuperKick; animationMappings[AnimationNames.AirKick] = AnimationNames.AirKick; animationMappings[AnimationNames.Claymore] = AnimationNames.Claymore; animationMappings[AnimationNames.SuperKick] = AnimationNames.SuperKick; // Hit Reactions - Map old hit reactions to new hit reactions animationMappings[AnimationNames.RightHookHitReaction] = AnimationNames.SpinningBackfistReaction; animationMappings[AnimationNames.BodyKickHitReaction] = AnimationNames.AirKickReaction; animationMappings[AnimationNames.HookHitReaction] = AnimationNames.ChopReaction; animationMappings[AnimationNames.JabHitReaction] = AnimationNames.JabReaction; animationMappings[AnimationNames.LegKickHitReaction] = AnimationNames.LowKickReaction; animationMappings[AnimationNames.UppercutPowerHitReaction] = AnimationNames.HaymakerReaction; animationMappings[AnimationNames.OverhandHitReaction] = AnimationNames.GroundPoundReaction; animationMappings[AnimationNames.ChopReaction] = AnimationNames.ChopReaction; animationMappings[AnimationNames.GroundPoundReaction] = AnimationNames.GroundPoundReaction; animationMappings[AnimationNames.AirKickReaction] = AnimationNames.AirKickReaction; // Jump Moves animationMappings["Jump"] = AnimationNames.JumpBack; animationMappings[AnimationNames.JumpBack] = AnimationNames.JumpBack; animationMappings[AnimationNames.JumpLeft] = AnimationNames.JumpLeft; animationMappings[AnimationNames.JumpRight] = AnimationNames.JumpRight; // Block Moves animationMappings[AnimationNames.BlockStepBack] = AnimationNames.BlockStepBack; animationMappings[AnimationNames.BlockBodyLeft] = AnimationNames.BlockBodyLeft; animationMappings[AnimationNames.BlockLeg] = AnimationNames.BlockLeg; animationMappings[AnimationNames.Block] = AnimationNames.Block; animationMappings["Block"] = AnimationNames.Block; // Other movement animationMappings["Sprint"] = "Sprint"; // Special Moves and Finishers - Map all special moves from the input system animationMappings[AnimationNames.Clothesline] = AnimationNames.Clothesline; animationMappings[AnimationNames.Spear] = AnimationNames.Spear; animationMappings[AnimationNames.RKO] = AnimationNames.RKO; animationMappings[AnimationNames.Claymore] = AnimationNames.Claymore; animationMappings[AnimationNames.SuperDDT] = AnimationNames.SuperDDT; animationMappings[AnimationNames.RockBottom] = AnimationNames.RockBottom; animationMappings[AnimationNames.TroubleInParadise] = AnimationNames.TroubleInParadise; animationMappings[AnimationNames.SwantonBomb] = AnimationNames.SwantonBomb; animationMappings[AnimationNames.Pedigree] = AnimationNames.Pedigree; animationMappings[AnimationNames.GorillaPress] = AnimationNames.GorillaPress; animationMappings[AnimationNames.Headbutt] = AnimationNames.Headbutt; animationMappings[AnimationNames.KOPunch] = AnimationNames.KOPunch; */ } /// /// Play an animation by name, using the mapping to find the actual animation to play. /// Uses cross-fade for smooth transitions between animations. /// /// The logical animation name (from AnimationNames class) public void PlayAnimation(string animationName) { if (animator == null) { Debug.LogError("Animator component is missing"); return; } if (!AnimationExists(animationName)) { Debug.LogWarning($"Animation '{animationName}' does not exist in the animator"); return; } string mappedAnimation; if (animationMappings.TryGetValue(animationName, out mappedAnimation)) { // Store current animation currentAnimationName = mappedAnimation; // Determine if this is a reaction animation bool isReactionAnimation = IsReactionAnimation(mappedAnimation); // Choose transition duration based on animation type float transitionDuration = isReactionAnimation ? reactionTransitionDuration : defaultTransitionDuration; // Use CrossFade for smoother transitions animator.CrossFade(mappedAnimation, transitionDuration, 0, 0); } else { // Fallback to playing the animation directly animator.CrossFade(animationName, defaultTransitionDuration, 0, 0); currentAnimationName = animationName; Debug.LogWarning($"No mapping found for animation: {animationName}"); } } /// /// Play a reaction animation with proper alignment to the attack. /// /// The reaction animation to play public void PlayReactionAnimation(string reactionName) { if (animator == null) { Debug.LogError("Animator component is missing"); return; } if (!AnimationExists(reactionName)) { Debug.LogWarning($"Reaction animation '{reactionName}' does not exist in the animator"); return; } string mappedReaction; if (animationMappings.TryGetValue(reactionName, out mappedReaction)) { // Use a very quick transition for reactions to make them look more impactful animator.CrossFade(mappedReaction, reactionTransitionDuration, 0, hitAlignmentOffset); currentAnimationName = mappedReaction; } else { // Fallback animator.CrossFade(reactionName, reactionTransitionDuration, 0, hitAlignmentOffset); currentAnimationName = reactionName; } } /// /// Check if an animation exists in the animator controller. /// private bool AnimationExists(string animationName) { if (animator == null) return false; // Get all animation clips from the animator controller RuntimeAnimatorController ac = animator.runtimeAnimatorController; if (ac == null) return false; AnimationClip[] clips = ac.animationClips; foreach (AnimationClip clip in clips) { if (clip.name == animationName) return true; } return false; } /// /// Checks if the animation is a reaction animation. /// private bool IsReactionAnimation(string animationName) { return animationName.Contains("Reaction") || animationName.Contains("Hit") || animationName.Contains("Stagger") || animationName.Contains("Block"); } /// /// Get the mapped animation name for a logical animation name. /// /// The logical animation name /// The mapped animation name public string GetMappedAnimationName(string animationName) { string mappedAnimation; if (animationMappings.TryGetValue(animationName, out mappedAnimation)) { return mappedAnimation; } return animationName; // Fallback to the original animation name } /// /// Update a specific animation mapping. /// /// The logical animation name /// The actual animation name to play public void UpdateAnimationMapping(string logicalName, string actualAnimationName) { animationMappings[logicalName] = actualAnimationName; } /// /// Check if the current animation matches any of the specified animations. /// /// Array of animation names to check /// True if the current animation matches any of the specified animations public bool IsPlayingAnimation(params string[] animationNames) { if (animator == null || animator.GetCurrentAnimatorClipInfo(0).Length == 0) return false; string currentAnimName = animator.GetCurrentAnimatorClipInfo(0)[0].clip.name; foreach (var animName in animationNames) { string mappedAnim = GetMappedAnimationName(animName); if (currentAnimName == mappedAnim) return true; } return false; } }