// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved. // This code can only be used under the standard Unity Asset Store End User License Agreement // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms using System; using System.Collections.Generic; using Doozy.Runtime.Reactor.Animations; using Doozy.Runtime.Reactor.Targets; using Doozy.Runtime.Reactor.Ticker; using Doozy.Runtime.UIManager.Components; using UnityEngine; // ReSharper disable UnusedMember.Global namespace Doozy.Runtime.UIManager.Animators { /// /// Specialized animator component used to animate a set of Sprites for a Reactor Sprite Target /// by listening to a UISelectable (controller) selection state changes. /// [AddComponentMenu("Doozy/UI/Components/Animators/UISelectable Sprite Animator")] public class UISelectableSpriteAnimator : BaseUISelectableAnimator { [SerializeField] private ReactorSpriteTarget SpriteTarget; /// Reference to a sprite target component public ReactorSpriteTarget spriteTarget => SpriteTarget; /// Check if a sprite target is referenced or not public bool hasSpriteTarget => SpriteTarget != null; [SerializeField] private SpriteAnimation NormalAnimation; /// Animation for the Normal selection state public SpriteAnimation normalAnimation => NormalAnimation ?? (NormalAnimation = new SpriteAnimation(spriteTarget)); [SerializeField] private SpriteAnimation HighlightedAnimation; /// Animation for the Highlighted selection state public SpriteAnimation highlightedAnimation => HighlightedAnimation ?? (HighlightedAnimation = new SpriteAnimation(spriteTarget)); [SerializeField] private SpriteAnimation PressedAnimation; /// Animation for the Pressed selection state public SpriteAnimation pressedAnimation => PressedAnimation ?? (PressedAnimation = new SpriteAnimation(spriteTarget)); [SerializeField] private SpriteAnimation SelectedAnimation; /// Animation for the Selected selection state public SpriteAnimation selectedAnimation => SelectedAnimation ?? (SelectedAnimation = new SpriteAnimation(spriteTarget)); [SerializeField] private SpriteAnimation DisabledAnimation; /// Animation for the Disabled selection state public SpriteAnimation disabledAnimation => DisabledAnimation ?? (DisabledAnimation = new SpriteAnimation(spriteTarget)); /// Get the animation triggered by the given selection state /// Target selection state public SpriteAnimation GetAnimation(UISelectionState state) => state switch { UISelectionState.Normal => normalAnimation, UISelectionState.Highlighted => highlightedAnimation, UISelectionState.Pressed => pressedAnimation, UISelectionState.Selected => selectedAnimation, UISelectionState.Disabled => disabledAnimation, _ => throw new ArgumentOutOfRangeException(nameof(state), state, null) }; #if UNITY_EDITOR protected override void Reset() { FindTarget(); foreach (UISelectionState state in UISelectable.uiSelectionStates) ResetAnimation(state); base.Reset(); } #endif public void FindTarget() { if (SpriteTarget != null) return; SpriteTarget = ReactorSpriteTarget.FindTarget(gameObject); UpdateSettings(); } protected override void Awake() { FindTarget(); UpdateSettings(); base.Awake(); } protected override void OnDestroy() { base.OnDestroy(); foreach (UISelectionState state in UISelectable.uiSelectionStates) GetAnimation(state)?.Recycle(); } /// Returns True if the givens selection state is enabled and the animation is not null. /// Selection state public override bool IsStateEnabled(UISelectionState state) => GetAnimation(state).isEnabled; /// Update the animations settings (if a colorTarget is referenced) public override void UpdateSettings() { if (spriteTarget == null) return; foreach (UISelectionState state in UISelectable.uiSelectionStates) GetAnimation(state)?.SetTarget(spriteTarget); } /// Stop all animations public override void StopAllReactions() { foreach (UISelectionState state in UISelectable.uiSelectionStates) GetAnimation(state)?.Stop(); } /// Reset all the reactions to their initial values (if the animation is enabled) /// If true, forced will ignore if the animation is enabled or not public override void ResetToStartValues(bool forced = false) { if(normalAnimation.isActive) normalAnimation.Stop(); if(highlightedAnimation.isActive) highlightedAnimation.Stop(); if(pressedAnimation.isActive) pressedAnimation.Stop(); if(selectedAnimation.isActive) selectedAnimation.Stop(); if(disabledAnimation.isActive) disabledAnimation.Stop(); normalAnimation.ResetToStartValues(); highlightedAnimation.ResetToStartValues(); pressedAnimation.ResetToStartValues(); selectedAnimation.ResetToStartValues(); disabledAnimation.ResetToStartValues(); if (spriteTarget == null) return; spriteTarget.sprite = normalAnimation.sprites[normalAnimation.startFrame]; #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(rectTransform); UnityEditor.SceneView.RepaintAll(); #endif } /// Set animation heartbeat public override List SetHeartbeat() { var list = new List(); for (int i = 0; i < 5; i++) list.Add(new T()); normalAnimation.animation.SetHeartbeat(list[0]); highlightedAnimation.animation.SetHeartbeat(list[1]); pressedAnimation.animation.SetHeartbeat(list[2]); selectedAnimation.animation.SetHeartbeat(list[3]); disabledAnimation.animation.SetHeartbeat(list[4]); return list; } /// Play the animation for the given selection state /// Selection state public override void Play(UISelectionState state) => GetAnimation(state)?.Play(); /// Reset the animation for the given selection state /// Selection state private void ResetAnimation(UISelectionState state) { SpriteAnimation a = GetAnimation(state); a.animation.Reset(); a.animation.enabled = false; a.animation.settings.duration = 0.5f; } } }