using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using Lean.Transition;
using Lean.Common;
namespace Lean.Gui
{
/// This component allows you to trigger a transition and/or event at regular intervals.
[HelpURL(LeanGui.HelpUrlPrefix + "LeanPulse")]
[AddComponentMenu(LeanGui.ComponentMenuPrefix + "Pulse")]
public class LeanPulse : MonoBehaviour
{
[System.Serializable] public class IntEvent : UnityEvent {}
/// This stores all active and enabled LeanPulse instances, so you can manually pulse them by name from anywhere.
public static LinkedList Instances = new LinkedList();
/// This tells you how many pulses remain until this component stops.
/// -1 = unlimited
public int RemainingPulses { set { remainingPulses = value; } get { return remainingPulses; } } [SerializeField] private int remainingPulses = -1;
/// When this reaches 0, and RemainingPulses is not 0, this component will pulse.
public float RemainingTime { set { remainingTime = value; } get { return remainingTime; } } [SerializeField] private float remainingTime;
/// This allows you to control the amount of seconds between each pulse.
/// -1 = Manual Pulses Only
public float TimeInterval { set { timeInterval = value; } get { return timeInterval; } } [SerializeField] private float timeInterval = 1.0f;
/// This allows you to choose where in the game loop this pulse will update.
public LeanTiming Timing { set { timing = value; } get { return timing; } } [SerializeField] private LeanTiming timing;
/// 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 Create.
/// For example, the LeanPlaySound (Play Sound Transition) component can be used to play a pulse sound.
public LeanPlayer PulseTransitions { get { if (pulseTransitions == null) pulseTransitions = new LeanPlayer(); return pulseTransitions; } } [SerializeField] private LeanPlayer pulseTransitions;
/// This allows you to perform an action when this UI element pulses.
/// int = RemainingPulses
public IntEvent OnPulse { get { if (onPulse == null) onPulse = new IntEvent(); return onPulse; } } [SerializeField] private IntEvent onPulse;
[System.NonSerialized]
private LinkedListNode link;
/// This will pulse, as long as you have remaining pulses.
[ContextMenu("Try Pulse")]
public void TryPulse()
{
if (remainingPulses >= 0)
{
if (remainingPulses > 0)
{
remainingPulses--;
}
else
{
return;
}
}
remainingTime = timeInterval;
Pulse();
}
/// This allows you to manually force this component to pulse right now.
[ContextMenu("Pulse")]
public void Pulse()
{
if (pulseTransitions != null)
{
pulseTransitions.Begin();
}
if (onPulse != null)
{
onPulse.Invoke(remainingPulses);
}
}
/// This method calls TryPulse on all active and enabled LeanPulse instances with the specified GameObject name.
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;
}
}
/// This method calls Pulse on all active and enabled LeanPulse instances with the specified GameObject name.
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