319 lines
15 KiB
C#
319 lines
15 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// Centralized animation manager class that handles playing animations
|
|
/// and provides an abstraction layer between animation names and animation triggers.
|
|
/// </summary>
|
|
public class AnimationManager : MonoBehaviour
|
|
{
|
|
private Animator animator;
|
|
private Dictionary<string, string> animationMappings = new Dictionary<string, string>();
|
|
|
|
[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<Animator>();
|
|
InitializeAnimationMappings();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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;
|
|
*/
|
|
}
|
|
|
|
/// <summary>
|
|
/// Play an animation by name, using the mapping to find the actual animation to play.
|
|
/// Uses cross-fade for smooth transitions between animations.
|
|
/// </summary>
|
|
/// <param name="animationName">The logical animation name (from AnimationNames class)</param>
|
|
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}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Play a reaction animation with proper alignment to the attack.
|
|
/// </summary>
|
|
/// <param name="reactionName">The reaction animation to play</param>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if an animation exists in the animator controller.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the animation is a reaction animation.
|
|
/// </summary>
|
|
private bool IsReactionAnimation(string animationName)
|
|
{
|
|
return animationName.Contains("Reaction") ||
|
|
animationName.Contains("Hit") ||
|
|
animationName.Contains("Stagger") ||
|
|
animationName.Contains("Block");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the mapped animation name for a logical animation name.
|
|
/// </summary>
|
|
/// <param name="animationName">The logical animation name</param>
|
|
/// <returns>The mapped animation name</returns>
|
|
public string GetMappedAnimationName(string animationName)
|
|
{
|
|
string mappedAnimation;
|
|
if (animationMappings.TryGetValue(animationName, out mappedAnimation))
|
|
{
|
|
return mappedAnimation;
|
|
}
|
|
return animationName; // Fallback to the original animation name
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update a specific animation mapping.
|
|
/// </summary>
|
|
/// <param name="logicalName">The logical animation name</param>
|
|
/// <param name="actualAnimationName">The actual animation name to play</param>
|
|
public void UpdateAnimationMapping(string logicalName, string actualAnimationName)
|
|
{
|
|
animationMappings[logicalName] = actualAnimationName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if the current animation matches any of the specified animations.
|
|
/// </summary>
|
|
/// <param name="animationNames">Array of animation names to check</param>
|
|
/// <returns>True if the current animation matches any of the specified animations</returns>
|
|
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;
|
|
}
|
|
} |