// 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 UnityEngine; namespace Doozy.Runtime.Reactor.Internal { [Serializable] public abstract class DynamicReaction : Reaction { internal Type typeOfPropertyType { get; set; } internal Type typeOfValueType { get; set; } [SerializeField] protected internal T2 FromValue; [SerializeField] protected internal T2 ToValue; [SerializeField] protected internal T2 CurrentValue; /// Start value public T2 fromValue => FromValue; /// End (target) value public T2 toValue => ToValue; /// Current value public T2 currentValue => CurrentValue; /// Getter for the reaction's from value public PropertyGetter getter { get; set; } /// Setter for the reaction's current value public PropertySetter setter { get; set; } /// Computed target values for each cycle protected T2[] cycleValues { get; set; } /// Current cycle start (from) value protected T2 cycleFrom => currentCycleIndex == 0 ? FromValue : cycleValues[currentCycleIndex - 1]; /// Current cycle target (to) value protected T2 cycleTo => currentCycleIndex == 0 ? ToValue : cycleValues[currentCycleIndex]; public ReactionCallback OnValueChangedCallback; protected DynamicReaction() { typeOfPropertyType = typeof(T1); typeOfValueType = typeof(T2); } public abstract float GetProgressAtValue(T2 value); public override void Reset() { base.Reset(); getter = null; setter = null; OnValueChangedCallback = null; } /// Set from (start) value /// From value /// If TRUE, FromValue = CurrentValue + value public abstract Reaction SetFrom(T2 value, bool relative = false); /// Set to (end) value /// To value /// If TRUE, ToValue = CurrentValue + value public abstract Reaction SetTo(T2 value, bool relative = false); /// /// Set current value. If the reaction is active, it will stop. /// /// Current value public virtual Reaction SetValue(T2 value) { if (isActive) Stop(); CurrentValue = value; // SetProgressAt(GetProgressAtValue(value)); return this; } /// /// Play the reaction from the current value to the given absolute or relative value /// /// To value /// If TRUE, ToValue = CurrentValue + value public virtual Reaction PlayToValue(T2 value, bool relative = false) { if (isActive) Stop(); SetFrom(CurrentValue); SetTo(value, relative); Play(); return this; } /// /// Play the reaction from the given absolute or relative value to the current value /// /// From value /// If TRUE, FromValue = CurrentValue + value public virtual Reaction PlayFromValue(T2 value, bool relative = false) { if (isActive) Stop(); SetFrom(value, relative); SetTo(CurrentValue); Play(); return this; } /// /// Play the reaction from the given start from value to the end to value /// /// From value /// To value /// Play in reverse? public virtual Reaction Play(T2 from, T2 to, bool reversed = false) { SetFrom(from); SetTo(to); Play(reversed); return this; } public override void Stop(bool silent = false, bool recycle = false) { switch (settings.playMode) { case PlayMode.Normal: // elapsedDuration = direction == PlayDirection.Forward ? targetDuration : startDuration; break; case PlayMode.PingPong: // elapsedDuration = direction == PlayDirection.Forward ? startDuration : targetDuration; break; case PlayMode.Spring: case PlayMode.Shake: if (isPlaying) { elapsedDuration = direction == PlayDirection.Forward ? startDuration : targetDuration; UpdateCurrentValue(); } break; default: throw new ArgumentOutOfRangeException(); } base.Stop(silent, recycle); } protected override void ComputeNormal() { base.ComputeNormal(); cycleValues = new[] { ToValue }; } protected override void ComputePingPong() { base.ComputePingPong(); cycleValues = new[] { ToValue, FromValue }; } protected override void ComputeSpring() { base.ComputeSpring(); cycleValues = new T2[numberOfCycles]; } protected override void ComputeShake() { base.ComputeShake(); cycleValues = new T2[numberOfCycles]; } } }