chunk 1: core gameplay scripts scenes runtime assets
This commit is contained in:
319
Assets/Scripts/Managers/AnimationManager.cs
Normal file
319
Assets/Scripts/Managers/AnimationManager.cs
Normal file
@@ -0,0 +1,319 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user