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;
}
}