fix issues with karate man consecutive punch animations
new AnimationHelper methods specifically for working with states in other layers
This commit is contained in:
parent
c46fb5ce9e
commit
6c59c07574
|
@ -219,7 +219,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
|
||||||
|
|
||||||
private bool _lastPunchedHeavy = false;
|
private bool _lastPunchedHeavy = false;
|
||||||
|
|
||||||
public bool Punch(int forceHand = 0, bool touchCharge = false, bool punchedHeavy = false)
|
public bool Punch(int forceHand = 0, bool touchCharge = false, bool punchedHeavy = false, double wantBeat = double.MaxValue)
|
||||||
{
|
{
|
||||||
if (GameManager.instance.currentGame != "karateman") return false;
|
if (GameManager.instance.currentGame != "karateman") return false;
|
||||||
var cond = Conductor.instance;
|
var cond = Conductor.instance;
|
||||||
|
@ -246,7 +246,8 @@ namespace HeavenStudio.Games.Scripts_KarateMan
|
||||||
noNuriJabTime = cond.songPositionInBeatsAsDouble;
|
noNuriJabTime = cond.songPositionInBeatsAsDouble;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (cond.songPositionInBeatsAsDouble <= cond.GetBeatFromSongPos(lastPunchTime + Minigame.NgLateTime() - 1) + 0.25)
|
Debug.Log($"Punching with beat {wantBeat} and lastPunchTime {lastPunchTime}");
|
||||||
|
if (wantBeat <= cond.GetBeatFromSongPos(lastPunchTime + Minigame.NgLateTime() - 1) + 0.25)
|
||||||
{
|
{
|
||||||
lastPunchTime = double.MinValue;
|
lastPunchTime = double.MinValue;
|
||||||
anim.DoScaledAnimationAsync("Straight", 0.5f);
|
anim.DoScaledAnimationAsync("Straight", 0.5f);
|
||||||
|
@ -254,7 +255,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lastPunchTime = cond.songPositionAsDouble;
|
lastPunchTime = cond.GetSongPosFromBeat(wantBeat, true);
|
||||||
anim.DoScaledAnimationAsync("Jab", 0.5f);
|
anim.DoScaledAnimationAsync("Jab", 0.5f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -765,7 +765,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
|
||||||
var joe = KarateMan.instance.Joe;
|
var joe = KarateMan.instance.Joe;
|
||||||
if (state <= -1f || state >= 1f)
|
if (state <= -1f || state >= 1f)
|
||||||
{
|
{
|
||||||
bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2);
|
bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2, caller.startBeat + caller.timer);
|
||||||
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
|
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
|
||||||
CurrentCurve = ItemCurves[6];
|
CurrentCurve = ItemCurves[6];
|
||||||
curveTargetBeat = 1f;
|
curveTargetBeat = 1f;
|
||||||
|
@ -798,7 +798,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2);
|
bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2, caller.startBeat + caller.timer);
|
||||||
DoHitExpression(startBeat + 1f);
|
DoHitExpression(startBeat + 1f);
|
||||||
ItemHitEffect(straight);
|
ItemHitEffect(straight);
|
||||||
status = FlyStatus.Hit;
|
status = FlyStatus.Hit;
|
||||||
|
|
|
@ -11,6 +11,14 @@ namespace HeavenStudio.Util
|
||||||
var stateInfo = anim.GetCurrentAnimatorStateInfo(0);
|
var stateInfo = anim.GetCurrentAnimatorStateInfo(0);
|
||||||
return (stateInfo.normalizedTime >= stateInfo.speed || stateInfo.loop) && !anim.IsInTransition(0);
|
return (stateInfo.normalizedTime >= stateInfo.speed || stateInfo.loop) && !anim.IsInTransition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsAnimationNotPlaying(this Animator anim, int layer)
|
||||||
|
{
|
||||||
|
if (anim == null) return true;
|
||||||
|
var stateInfo = anim.GetCurrentAnimatorStateInfo(layer);
|
||||||
|
return (stateInfo.normalizedTime >= stateInfo.speed || stateInfo.loop) && !anim.IsInTransition(layer);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if animName is currently playing on animator
|
/// Returns true if animName is currently playing on animator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -24,6 +32,19 @@ namespace HeavenStudio.Util
|
||||||
return (stateInfo.normalizedTime < stateInfo.speed || stateInfo.loop) && isPlaying;
|
return (stateInfo.normalizedTime < stateInfo.speed || stateInfo.loop) && isPlaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if animName is currently playing on animator on a specific layer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anim">Animator to check</param>
|
||||||
|
/// <param name="animNames">name(s) of animation to look out for</param>
|
||||||
|
public static bool IsPlayingAnimationNames(this Animator anim, int layer, params string[] animNames)
|
||||||
|
{
|
||||||
|
if (anim == null) return false;
|
||||||
|
var stateInfo = anim.GetCurrentAnimatorStateInfo(layer);
|
||||||
|
var isPlaying = Array.Exists(animNames, animName => stateInfo.IsName(animName));
|
||||||
|
return (stateInfo.normalizedTime < stateInfo.speed || stateInfo.loop) && isPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets animator's progress on an animation based on current song beat between startTime and length
|
/// Sets animator's progress on an animation based on current song beat between startTime and length
|
||||||
/// function must be called in actor's Update loop to update properly
|
/// function must be called in actor's Update loop to update properly
|
||||||
|
@ -43,6 +64,27 @@ namespace HeavenStudio.Util
|
||||||
anim.speed = 1f; //not 0 so these can still play their script events
|
anim.speed = 1f; //not 0 so these can still play their script events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets animator's progress on a state based on current song beat between startTime and length
|
||||||
|
/// function must be called in actor's Update loop to update properly
|
||||||
|
/// also sets the speed of the state 1x speed
|
||||||
|
/// Animator must have a float parameter named "{state}_Speed" for this to work, and have the state's speed multiplier mapped to that parameter in the state tree
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anim">Animator to update</param>
|
||||||
|
/// <param name="state">name of animation to play</param>
|
||||||
|
/// <param name="startTime">reference start time of animation (progress 0.0)</param>
|
||||||
|
/// <param name="length">duration of animation (progress 1.0)</param>
|
||||||
|
/// <param name="timeScale">multiplier for animation progress (smaller values make animation slower)</param>
|
||||||
|
/// <param name="animLayer">animator layer to play animation on</param>
|
||||||
|
public static void DoScaledState(this Animator anim, string state, double startTime, double length = 1, float timeScale = 1f, int animLayer = -1, bool clamp = false, bool ignoreSwing = true)
|
||||||
|
{
|
||||||
|
if (anim == null) return;
|
||||||
|
float pos = Conductor.instance.GetPositionFromBeat(startTime, length, ignoreSwing: ignoreSwing) * timeScale;
|
||||||
|
if (clamp) pos = Mathf.Clamp01(pos);
|
||||||
|
anim.Play(state, animLayer, pos);
|
||||||
|
anim.SetFloat($"{state}_Speed", 1);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets animator progress on an animation according to pos
|
/// Sets animator progress on an animation according to pos
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -85,6 +127,36 @@ namespace HeavenStudio.Util
|
||||||
anim.DoScaledAnimationAsync(animName, timeScale, pos, animLayer);
|
anim.DoScaledAnimationAsync(animName, timeScale, pos, animLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the speed of an animation state on an animator, scaled to the BPM, then plays it
|
||||||
|
/// Animator must have a float parameter named "{state}Speed" for this to work, and have the state's speed multiplier mapped to that parameter in the state tree
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anim">Animator to play animation on</param>
|
||||||
|
/// <param name="state">name of animation to play</param>
|
||||||
|
/// <param name="timeScale">multiplier for animation speed</param>
|
||||||
|
/// <param name="startBeat">beat that this animation would start on</param>
|
||||||
|
/// <param name="animLayer">animator layer to play animation on</param>
|
||||||
|
public static void DoScaledStateFromBeatAsync(this Animator anim, string animName, float timeScale = 1f, double startBeat = 0, int animLayer = -1)
|
||||||
|
{
|
||||||
|
if (anim == null) return;
|
||||||
|
float pos = 0;
|
||||||
|
if (!double.IsNaN(startBeat)) {
|
||||||
|
var cond = Conductor.instance;
|
||||||
|
var animClip = Array.Find(anim.runtimeAnimatorController.animationClips, x => x.name == animName);
|
||||||
|
if (animClip == null) {
|
||||||
|
Debug.LogError("Animation clip " + animName + " not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
double animLength = cond.SecsToBeats(animClip.length, cond.GetBpmAtBeat(startBeat));
|
||||||
|
pos = cond.GetPositionFromBeat(startBeat, animLength) * timeScale;
|
||||||
|
} else {
|
||||||
|
Debug.LogWarning("DoScaledAnimationFromBeatAsync()'s startBeat was NaN; using DoScaledAnimationAsync() instead.");
|
||||||
|
}
|
||||||
|
anim.DoScaledStateAsync(animName, timeScale, pos, animLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Plays animation on animator, scaling speed to song BPM
|
/// Plays animation on animator, scaling speed to song BPM
|
||||||
/// call this function once, when playing an animation
|
/// call this function once, when playing an animation
|
||||||
|
@ -101,6 +173,21 @@ namespace HeavenStudio.Util
|
||||||
anim.speed = (1f / Conductor.instance.pitchedSecPerBeat) * timeScale;
|
anim.speed = (1f / Conductor.instance.pitchedSecPerBeat) * timeScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the speed of an animation state on an animator, scaled to the BPM, then plays it
|
||||||
|
/// Animator must have a float parameter named "{state}Speed" for this to work, and have the state's speed multiplier mapped to that parameter in the state tree
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anim">Animator to play animation on</param>
|
||||||
|
/// <param name="state">name of animation to play</param>
|
||||||
|
/// <param name="timeScale">multiplier for animation speed</param>
|
||||||
|
/// <param name="startPos">starting progress of animation</param>
|
||||||
|
/// <param name="animLayer">animator layer to play animation on</param>
|
||||||
|
public static void DoScaledStateAsync(this Animator anim, string state, float timeScale = 1f, float startPos = 0f, int animLayer = -1)
|
||||||
|
{
|
||||||
|
if (anim == null) return;
|
||||||
|
anim.PlayStateAtSpeed(state, (1f / Conductor.instance.pitchedSecPerBeat) * timeScale, startPos, animLayer);
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetScaledAnimationSpeed(this Animator anim, float timeScale = 0.5f)
|
public static void SetScaledAnimationSpeed(this Animator anim, float timeScale = 0.5f)
|
||||||
{
|
{
|
||||||
if (anim == null) return;
|
if (anim == null) return;
|
||||||
|
@ -121,5 +208,21 @@ namespace HeavenStudio.Util
|
||||||
anim.Play(animName, animLayer, startPos);
|
anim.Play(animName, animLayer, startPos);
|
||||||
anim.speed = 1f;
|
anim.speed = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the speed of an animation state on an animator, then plays it
|
||||||
|
/// Animator must have a float parameter named "{state}_Speed" for this to work, and have the state's speed multiplier mapped to that parameter in the state tree
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="anim">Animator to play animation on</param>
|
||||||
|
/// <param name="state">name of animation to play</param>
|
||||||
|
/// <param name="timeScale">multiplier for animation speed</param>
|
||||||
|
/// <param name="startPos">starting progress of animation</param>
|
||||||
|
/// <param name="animLayer">animator layer to play animation on</param>
|
||||||
|
public static void PlayStateAtSpeed(this Animator anim, string state, float timeScale = 1f, float startPos = 0f, int animLayer = -1)
|
||||||
|
{
|
||||||
|
if (anim == null) return;
|
||||||
|
anim.SetFloat($"{state}_Speed", timeScale);
|
||||||
|
anim.Play(state, animLayer, startPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue