SamsonGame/Assets/Sources/Lean/GUI/Scripts/LeanPulse.cs

201 lines
5.9 KiB
C#

using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using Lean.Transition;
using Lean.Common;
namespace Lean.Gui
{
/// <summary>This component allows you to trigger a transition and/or event at regular intervals.</summary>
[HelpURL(LeanGui.HelpUrlPrefix + "LeanPulse")]
[AddComponentMenu(LeanGui.ComponentMenuPrefix + "Pulse")]
public class LeanPulse : MonoBehaviour
{
[System.Serializable] public class IntEvent : UnityEvent<int> {}
/// <summary>This stores all active and enabled LeanPulse instances, so you can manually pulse them by name from anywhere.</summary>
public static LinkedList<LeanPulse> Instances = new LinkedList<LeanPulse>();
/// <summary>This tells you how many pulses remain until this component stops.
/// -1 = unlimited</summary>
public int RemainingPulses { set { remainingPulses = value; } get { return remainingPulses; } } [SerializeField] private int remainingPulses = -1;
/// <summary>When this reaches 0, and RemainingPulses is not 0, this component will pulse.</summary>
public float RemainingTime { set { remainingTime = value; } get { return remainingTime; } } [SerializeField] private float remainingTime;
/// <summary>This allows you to control the amount of seconds between each pulse.
/// -1 = Manual Pulses Only</summary>
public float TimeInterval { set { timeInterval = value; } get { return timeInterval; } } [SerializeField] private float timeInterval = 1.0f;
/// <summary>This allows you to choose where in the game loop this pulse will update.</summary>
public LeanTiming Timing { set { timing = value; } get { return timing; } } [SerializeField] private LeanTiming timing;
/// <summary>This allows you to perform an animation when this UI element pulses.
/// You can create a new transition GameObject by right clicking the transition name, and selecting <b>Create</b>.
/// For example, the <b>LeanPlaySound (Play Sound Transition)</b> component can be used to play a pulse sound.</summary>
public LeanPlayer PulseTransitions { get { if (pulseTransitions == null) pulseTransitions = new LeanPlayer(); return pulseTransitions; } } [SerializeField] private LeanPlayer pulseTransitions;
/// <summary>This allows you to perform an action when this UI element pulses.
/// int = RemainingPulses</summary>
public IntEvent OnPulse { get { if (onPulse == null) onPulse = new IntEvent(); return onPulse; } } [SerializeField] private IntEvent onPulse;
[System.NonSerialized]
private LinkedListNode<LeanPulse> link;
/// <summary>This will pulse, as long as you have remaining pulses.</summary>
[ContextMenu("Try Pulse")]
public void TryPulse()
{
if (remainingPulses >= 0)
{
if (remainingPulses > 0)
{
remainingPulses--;
}
else
{
return;
}
}
remainingTime = timeInterval;
Pulse();
}
/// <summary>This allows you to manually force this component to pulse right now.</summary>
[ContextMenu("Pulse")]
public void Pulse()
{
if (pulseTransitions != null)
{
pulseTransitions.Begin();
}
if (onPulse != null)
{
onPulse.Invoke(remainingPulses);
}
}
/// <summary>This method calls TryPulse on all active and enabled LeanPulse instances with the specified GameObject name.</summary>
public static void TryPulseAll(string name)
{
var node = Instances.First;
for (var i = Instances.Count - 1; i >= 0; i--)
{
var instance = node.Value;
if (instance.name == name)
{
instance.TryPulse();
}
node = node.Next;
}
}
/// <summary>This method calls Pulse on all active and enabled LeanPulse instances with the specified GameObject name.</summary>
public static void PulseAll(string name)
{
var node = Instances.First;
for (var i = Instances.Count - 1; i >= 0; i--)
{
var instance = node.Value;
if (instance.name == name)
{
instance.Pulse();
}
node = node.Next;
}
}
protected virtual void OnEnable()
{
link = Instances.AddLast(this);
}
protected virtual void OnDisable()
{
Instances.Remove(link);
link = null;
}
protected virtual void Update()
{
var finalUpdate = LeanTransition.GetTiming(timing);
if (LeanTransition.GetTimingAbs(finalUpdate) == LeanTiming.Update)
{
UpdatePulse(finalUpdate > 0 ? Time.deltaTime : Time.unscaledDeltaTime);
}
}
protected virtual void LateUpdate()
{
var finalUpdate = LeanTransition.GetTiming(timing);
if (LeanTransition.GetTimingAbs(finalUpdate) == LeanTiming.LateUpdate)
{
UpdatePulse(finalUpdate > 0 ? Time.deltaTime : Time.unscaledDeltaTime);
}
}
protected virtual void FixedUpdate()
{
var finalUpdate = LeanTransition.GetTiming(timing);
if (LeanTransition.GetTimingAbs(finalUpdate) == LeanTiming.FixedUpdate)
{
UpdatePulse(finalUpdate > 0 ? Time.fixedDeltaTime : Time.fixedUnscaledDeltaTime);
}
}
private void UpdatePulse(float delta)
{
remainingTime -= delta;
if (remainingTime <= 0.0f)
{
remainingTime = timeInterval;
TryPulse();
}
}
}
}
#if UNITY_EDITOR
namespace Lean.Gui.Editor
{
using TARGET = LeanPulse;
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(TARGET))]
public class LeanPulse_Editor : LeanEditor
{
protected override void OnInspector()
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
Draw("remainingPulses", "This tells you how many pulses remain until this component stops.\n\n-1 = unlimited");
Draw("remainingTime", "When this reaches 0, and RemainingPulses is not 0, this component will pulse.");
Draw("timeInterval", "This allows you to control the amount of seconds between each pulse.\n\n-1 = Manual Pulses Only");
Draw("timing", "This allows you to choose where in the game loop this pulse will update.");
Separator();
Draw("pulseTransitions", "This allows you to perform an animation when this UI element pulses.");
Separator();
Draw("onPulse");
}
}
}
#endif