HeavenStudio/Assets/Scripts/Util/AnimationHelpers.cs
minenice55 3002e48350
Alternate Control Styles Support (#554)
* add mouse controller

* support different control styles in options

deprecate old input check methods

* fully functional input actions system

* btsds InputAction

* blue bear InputAction

* more games

fix bugs with some input related systems

* coin toss re-toss

* cheer readers touch

* dog ninja touch

* multiple games

* last of the easy games' touch

* more specialized games

* specialized games 2

* finish ktb games

* remove legacy settings disclaimer

* "only" two games left

* karate man touch

* rockers touch

still needs fixes and bad judge strum

* DSGuy flicking animation

* playstyle chart property

* improve performance of minigame preloading

* improve look of cursor

make assetbundles use chunk-based compression
refactor assetbundle loading methods a bit

* prime conductor stream playback to stabilize seeking operations

* fix air rally swing on pad release

* use virtual mouse pointer

* add UniTask

* make BeatAction use UniTask

* implement UniTask to replace some coroutines

* add touch style UI elements and effects

games now support the ability to define two cursor colours if they need split screen touch inputs

* update plugins and buildscript

* implement thresholded pointer position clipping

* fix clamping

* instant show / hide

fix discord game SDK crashes
2023-10-29 19:44:47 +00:00

107 lines
5.5 KiB
C#

using UnityEngine;
using System;
namespace HeavenStudio.Util
{
public static class AnimationHelpers
{
public static bool IsAnimationNotPlaying(this Animator anim)
{
var stateInfo = anim.GetCurrentAnimatorStateInfo(0);
return (stateInfo.normalizedTime >= stateInfo.speed || stateInfo.loop) && !anim.IsInTransition(0);
}
/// <summary>
/// Returns true if animName is currently playing on animator
/// </summary>
/// <param name="anim">Animator to check</param>
/// <param name="animName">name of animation to look out for</param>
public static bool IsPlayingAnimationName(this Animator anim, string animName)
{
var stateInfo = anim.GetCurrentAnimatorStateInfo(0);
return (stateInfo.normalizedTime < stateInfo.speed || stateInfo.loop) && stateInfo.IsName(animName);
}
/// <summary>
/// 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
/// </summary>
/// <param name="anim">Animator to update</param>
/// <param name="animName">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 DoScaledAnimation(this Animator anim, string animName, double startTime, float length = 1f, float timeScale = 1f, int animLayer = -1, bool clamp = false)
{
float pos = Conductor.instance.GetPositionFromBeat(startTime, length) * timeScale;
if (clamp) pos = Mathf.Clamp01(pos);
anim.Play(animName, animLayer, pos);
anim.speed = 1f; //not 0 so these can still play their script events
}
/// <summary>
/// Sets animator progress on an animation according to pos
/// </summary>
/// <param name="anim">Animator to update</param>
/// <param name="animName">name of animation to play</param>
/// <param name="pos">position to set animation progress to (0.0 - 1.0)</param>
/// <param name="animLayer">animator layer to play animation on</param>
public static void DoNormalizedAnimation(this Animator anim, string animName, float pos = 0f, int animLayer = -1)
{
anim.Play(animName, animLayer, pos);
anim.speed = 1f;
}
/// <summary>
/// Plays animation on animator, scaling speed to song BPM
/// call this function once, when playing an animation
/// </summary>
/// <param name="anim">Animator to play animation on</param>
/// <param name="animName">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 DoScaledAnimationFromBeatAsync(this Animator anim, string animName, float timeScale = 1f, double startBeat = 0, int animLayer = -1)
{
float pos = 0;
if (!double.IsNaN(startBeat)) {
var cond = Conductor.instance;
var animClip = Array.Find(anim.runtimeAnimatorController.animationClips, x => x.name == animName);
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.DoScaledAnimationAsync(animName, timeScale, pos, animLayer);
}
/// <summary>
/// Plays animation on animator, scaling speed to song BPM
/// call this function once, when playing an animation
/// </summary>
/// <param name="anim">Animator to play animation on</param>
/// <param name="animName">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 DoScaledAnimationAsync(this Animator anim, string animName, float timeScale = 1f, float startPos = 0f, int animLayer = -1)
{
anim.Play(animName, animLayer, startPos);
anim.speed = (1f / Conductor.instance.pitchedSecPerBeat) * timeScale;
}
/// <summary>
/// Plays animation on animator, at default speed
/// this is the least nessecary function here lol
/// </summary>
/// <param name="anim">Animator to play animation on</param>
/// <param name="animName">name of animation to play</param>
/// <param name="startPos">starting progress of animation</param>
/// <param name="animLayer">animator layer to play animation on</param>
public static void DoUnscaledAnimation(this Animator anim, string animName, float startPos = 0f, int animLayer = -1)
{
anim.Play(animName, animLayer, startPos);
anim.speed = 1f;
}
}
}