OldBlueWater/BlueWater/Assets/Doozy/Runtime/UIManager/Animators/UIToggleUIAnimator.cs

272 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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.Collections.Generic;
using Doozy.Runtime.Common.Layouts;
using Doozy.Runtime.Common.Utils;
using Doozy.Runtime.Reactor;
using Doozy.Runtime.Reactor.Animations;
using Doozy.Runtime.Reactor.Ticker;
using Doozy.Runtime.UIManager.Containers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Doozy.Runtime.UIManager.Animators
{
/// <summary>
/// Specialized animator component used to animate a RectTransforms position, rotation, scale and alpha
/// by listening to a UIToggle (controller) onToggleValueChangedCallback.
/// </summary>
[AddComponentMenu("Doozy/UI/Components/Animators/UIToggle UIAnimator")]
[RequireComponent(typeof(CanvasGroup))]
[RequireComponent(typeof(RectTransform))]
public class UIToggleUIAnimator : BaseUIToggleAnimator
{
private CanvasGroup m_CanvasGroup;
/// <summary> Reference to the CanvasGroup component </summary>
public CanvasGroup canvasGroup => m_CanvasGroup ? m_CanvasGroup : m_CanvasGroup = GetComponent<CanvasGroup>();
[SerializeField] private UIAnimation OnAnimation;
/// <summary> Container Show Animation </summary>
public UIAnimation onAnimation => OnAnimation ?? (OnAnimation = new UIAnimation(rectTransform));
[SerializeField] private UIAnimation OffAnimation;
/// <summary> Container Hide Animation </summary>
public UIAnimation offAnimation => OffAnimation ?? (OffAnimation = new UIAnimation(rectTransform));
public bool anyAnimationIsActive => onAnimation.isActive || offAnimation.isActive;
private bool isInLayoutGroup { get; set; }
private Vector3 localPosition { get; set; }
private UIBehaviourHandler uiBehaviourHandler { get; set; }
private bool updateStartPositionInLateUpdate { get; set; }
protected override bool onAnimationIsActive => onAnimation.isActive;
protected override bool offAnimationIsActive => offAnimation.isActive;
protected override UnityAction playOnAnimation => () => onAnimation.Play();
protected override UnityAction playOffAnimation => () => offAnimation.Play();
protected override UnityAction reverseOnAnimation => () => onAnimation.Reverse();
protected override UnityAction reverseOffAnimation => () => offAnimation.Reverse();
protected override UnityAction instantPlayOnAnimation => () => onAnimation.SetProgressAtOne();
protected override UnityAction instantPlayOffAnimation => () => offAnimation.SetProgressAtOne();
protected override UnityAction stopOnAnimation => () => onAnimation.Stop();
protected override UnityAction stopOffAnimation => () => offAnimation.Stop();
protected override UnityAction addResetToOnStateCallback => () => offAnimation.OnFinishCallback.AddListener(ResetToOnState);
protected override UnityAction removeResetToOnStateCallback => () => offAnimation.OnFinishCallback.RemoveListener(ResetToOnState);
protected override UnityAction addResetToOffStateCallback => () => onAnimation.OnFinishCallback.AddListener(ResetToOffState);
protected override UnityAction removeResetToOffStateCallback => () => onAnimation.OnFinishCallback.RemoveListener(ResetToOffState);
#if UNITY_EDITOR
protected override void Reset()
{
ResetAnimation(onAnimation);
ResetAnimation(offAnimation);
onAnimation.animationType = UIAnimationType.Show;
onAnimation.Move.enabled = true;
onAnimation.Move.fromDirection = MoveDirection.Left;
offAnimation.animationType = UIAnimationType.Hide;
offAnimation.Move.enabled = true;
offAnimation.Move.toDirection = MoveDirection.Right;
base.Reset();
}
#endif
protected override void Awake()
{
if (!Application.isPlaying) return;
animatorInitialized = false;
m_RectTransform = GetComponent<RectTransform>();
m_CanvasGroup = GetComponent<CanvasGroup>();
UpdateLayout();
}
protected override void OnEnable()
{
if (!Application.isPlaying) return;
base.OnEnable();
updateStartPositionInLateUpdate = true;
}
protected override void OnDisable()
{
if (!Application.isPlaying) return;
base.OnDisable();
if (onAnimation.isPlaying) onAnimation.SetProgressAtOne();
if (offAnimation.isPlaying) offAnimation.SetProgressAtOne();
RefreshLayout();
}
protected override void OnDestroy()
{
base.OnDestroy();
OnAnimation?.Recycle();
OffAnimation?.Recycle();
}
private void LateUpdate()
{
if (!animatorInitialized) return;
if (!isInLayoutGroup) return;
if (!isConnected) return;
if (!controller.isActiveAndEnabled) return;
if (anyAnimationIsActive) return;
if (!updateStartPositionInLateUpdate && localPosition == rectTransform.localPosition) return;
if (CanvasUpdateRegistry.IsRebuildingLayout()) return;
RefreshLayout();
UpdateStartPosition();
}
private void UpdateLayout()
{
isInLayoutGroup = rectTransform.IsInLayoutGroup();
uiBehaviourHandler = null;
if (!isInLayoutGroup) return;
LayoutGroup layout = rectTransform.GetLayoutGroupInParent();
if (layout == null) return;
uiBehaviourHandler = layout.GetUIBehaviourHandler();
System.Diagnostics.Debug.Assert(uiBehaviourHandler != null, nameof(uiBehaviourHandler) + " != null");
uiBehaviourHandler.SetDirty();
}
/// <summary> Refresh the layout the container is in </summary>
private void RefreshLayout()
{
if (uiBehaviourHandler == null) return;
uiBehaviourHandler.RefreshLayout();
}
/// <summary> Update the start position of the container </summary>
public void UpdateStartPosition()
{
// if (name.Contains("#")) Debug.Log($"({Time.frameCount}) [{name}] {nameof(UpdateStartPosition)}");
Vector3 anchoredPosition3D = rectTransform.anchoredPosition3D;
onAnimation.startPosition = anchoredPosition3D;
offAnimation.startPosition = anchoredPosition3D;
if (onAnimation.Move.isPlaying) onAnimation.Move.UpdateValues();
if (offAnimation.Move.isPlaying) offAnimation.Move.UpdateValues();
localPosition = rectTransform.localPosition;
updateStartPositionInLateUpdate = false;
}
/// <summary> Refresh the layout and then the start position of the container </summary>
private void RefreshStartPosition()
{
if (!isConnected) return;
if (anyAnimationIsActive) return;
if (!controller.isActiveAndEnabled) return;
RefreshLayout();
UpdateStartPosition();
}
/// <summary> Update the animations settings (if a colorTarget is referenced) </summary>
public override void UpdateSettings()
{
onAnimation.SetTarget(rectTransform, canvasGroup);
offAnimation.SetTarget(rectTransform, canvasGroup);
}
/// <summary> Stop all animations </summary>
public override void StopAllReactions()
{
onAnimation.Stop();
offAnimation.Stop();
}
/// <summary> Reset all the reactions to their initial values (if the animation is enabled) </summary>
/// <param name="forced"> If true, forced will ignore if the animation is enabled or not </param>
public override void ResetToStartValues(bool forced = false)
{
if (m_RectTransform == null) return;
if (onAnimation.isActive) onAnimation.Stop();
if (offAnimation.isActive) offAnimation.Stop();
onAnimation.ResetToStartValues(forced);
offAnimation.ResetToStartValues(forced);
rectTransform.anchoredPosition3D = onAnimation.startPosition;
rectTransform.localEulerAngles = onAnimation.startRotation;
rectTransform.localScale = onAnimation.startScale;
canvasGroup.alpha = onAnimation.startAlpha;
#if UNITY_EDITOR
UnityEditor.EditorUtility.SetDirty(rectTransform);
UnityEditor.SceneView.RepaintAll();
#endif
}
/// <summary> Set animation heartbeat </summary>
public override List<Heartbeat> SetHeartbeat<T>()
{
var list = new List<Heartbeat>();
for (int i = 0; i < 8; i++) list.Add(new T());
onAnimation.Move.SetHeartbeat(list[0]);
onAnimation.Rotate.SetHeartbeat(list[1]);
onAnimation.Scale.SetHeartbeat(list[2]);
onAnimation.Fade.SetHeartbeat(list[3]);
offAnimation.Move.SetHeartbeat(list[4]);
offAnimation.Rotate.SetHeartbeat(list[5]);
offAnimation.Scale.SetHeartbeat(list[6]);
offAnimation.Fade.SetHeartbeat(list[7]);
return list;
}
/// <summary> Set a new start position value (RectTransform.anchoredPosition3D) for all animations </summary>
/// <param name="value"> New start position </param>
public void SetStartPosition(Vector3 value)
{
onAnimation.startPosition = value;
offAnimation.startPosition = value;
}
/// <summary> Set a new start rotation value (RectTransform.localEulerAngles) for both show and hide animations </summary>
/// <param name="value"> New start rotation </param>
public void SetStartRotation(Vector3 value)
{
onAnimation.startRotation = value;
offAnimation.startRotation = value;
}
/// <summary> Set a new start scale value (RectTransform.localScale) for both show and hide animations </summary>
/// <param name="value"> New start scale </param>
public void SetStartScale(Vector3 value)
{
onAnimation.startScale = value;
offAnimation.startScale = value;
}
/// <summary> Set a new start alpha value (CanvasGroup.alpha) for both show and hide animations </summary>
/// <param name="value"> New start scale </param>
public void SetStartAlpha(float value)
{
onAnimation.startAlpha = value;
offAnimation.startAlpha = value;
}
private static void ResetAnimation(UIAnimation target)
{
target.Move.Reset();
target.Rotate.Reset();
target.Scale.Reset();
target.Fade.Reset();
target.Move.fromReferenceValue = ReferenceValue.StartValue;
target.Rotate.fromReferenceValue = ReferenceValue.StartValue;
target.Scale.fromReferenceValue = ReferenceValue.StartValue;
target.Fade.fromReferenceValue = ReferenceValue.StartValue;
target.Move.settings.duration = UIContainer.k_DefaultAnimationDuration;
target.Rotate.settings.duration = UIContainer.k_DefaultAnimationDuration;
target.Scale.settings.duration = UIContainer.k_DefaultAnimationDuration;
target.Fade.settings.duration = UIContainer.k_DefaultAnimationDuration;
}
}
}