// 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; using Doozy.Runtime.Reactor.Animations; using Doozy.Runtime.Reactor.Reflection; using Doozy.Runtime.Reactor.Ticker; using Doozy.Runtime.UIManager.Components; using UnityEngine; // ReSharper disable MemberCanBePrivate.Global namespace Doozy.Runtime.UIManager.Animators { /// /// Specialized animator component used to animate an int value /// by listening to a target UISelectable (controller) selection state changes. /// [AddComponentMenu("Doozy/UI/Components/Animators/UISelectable Int Animator")] public class UISelectableIntAnimator : BaseUISelectableAnimator { /// Int value target accessed via reflection public ReflectedInt ValueTarget = new ReflectedInt(); /// Check if the value target is set up correctly public bool isValid => ValueTarget.IsValid(); [SerializeField] private IntAnimation NormalAnimation; /// Animation for the Normal selection state public IntAnimation normalAnimation => NormalAnimation ?? (NormalAnimation = new IntAnimation(ValueTarget)); [SerializeField] private IntAnimation HighlightedAnimation; /// Animation for the Highlighted selection state public IntAnimation highlightedAnimation => HighlightedAnimation ?? (HighlightedAnimation = new IntAnimation(ValueTarget)); [SerializeField] private IntAnimation PressedAnimation; /// Animation for the Pressed selection state public IntAnimation pressedAnimation => PressedAnimation ?? (PressedAnimation = new IntAnimation(ValueTarget)); [SerializeField] private IntAnimation SelectedAnimation; /// Animation for the Selected selection state public IntAnimation selectedAnimation => SelectedAnimation ?? (SelectedAnimation = new IntAnimation(ValueTarget)); [SerializeField] private IntAnimation DisabledAnimation; /// Animation for the Disabled selection state public IntAnimation disabledAnimation => DisabledAnimation ?? (DisabledAnimation = new IntAnimation(ValueTarget)); /// Returns TRUE if any animation is active public bool anyAnimationIsActive => normalAnimation.isActive || highlightedAnimation.isActive || pressedAnimation.isActive || selectedAnimation.isActive || disabledAnimation.isActive; /// Get the animation triggered by the given selection state /// Target selection state public IntAnimation 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() { ValueTarget ??= new ReflectedInt(); base.Reset(); foreach (UISelectionState state in UISelectable.uiSelectionStates) ResetAnimation(state); } #endif protected override void Awake() { 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() { foreach (UISelectionState state in UISelectable.uiSelectionStates) { var a = GetAnimation(state); if(a == null) continue; a.SetTarget(ValueTarget); if(a.isPlaying) a.UpdateValues(); } } /// 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 (ValueTarget == null || !ValueTarget.IsValid()) return; ValueTarget.SetValue(normalAnimation.startValue); #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) { var a = GetAnimation(state); a.animation.enabled = true; a.animation.fromReferenceValue = ReferenceValue.CurrentValue; a.animation.toReferenceValue = ReferenceValue.StartValue; a.animation.settings.duration = 0.2f; } } }