using System; using UnityEngine; namespace FramedAnimator { [RequireComponent(typeof(SpriteRenderer))] public class Animator : MonoBehaviour { [SerializeField] private new Animation animation; public string CurrentAnimation => animation.name; private float _currentFrame; private int _renderingFrame; private int _limit; private SpriteRenderer _renderer; private bool _animationEnded; public event Action OnAnimationEnd; private void Awake() { _renderer = GetComponent(); } private void Update() { if (_renderingFrame >= _limit) { TryCallAnimationEnd(); return; } UpdateAnimationFrame(); } private void UpdateAnimationFrame() { _currentFrame += Time.deltaTime * animation.FrameRate; _renderingFrame = Mathf.Clamp(Mathf.FloorToInt(_currentFrame), 0, _limit); _renderer.sprite = animation.GetFrame(_renderingFrame); } private void TryCallAnimationEnd() { if (_renderingFrame < animation.FrameCount - 1 || _animationEnded) return; _currentFrame += Time.deltaTime * animation.FrameRate; _renderingFrame = Mathf.FloorToInt(_currentFrame); if (_renderingFrame <= _limit) return; _animationEnded = true; OnAnimationEnd?.Invoke(animation.name); } public void ChangeAnimation(Animation anim) { _animationEnded = false; _limit = _renderingFrame = 0; _currentFrame = 0f; animation = anim; _renderer.sprite = animation.GetFrame(_renderingFrame); } public void PlayUntil(float fraction) { _limit = Mathf.RoundToInt(animation.FrameCount * Mathf.Clamp01(fraction)); _limit = Mathf.Clamp(_limit, 0, animation.FrameCount - 1); } } }