hellbound/Assets/Sources/Lean/Common/Extras/LeanSelectable.cs

251 lines
5.8 KiB
C#

using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute;
namespace Lean.Common
{
/// <summary>This component allows you make the current GameObject selectable.</summary>
[HelpURL(LeanHelper.HelpUrlPrefix + "LeanSelectable")]
public class LeanSelectable : MonoBehaviour
{
[System.Serializable] public class LeanSelectEvent : UnityEvent<LeanSelect> {}
public static LinkedList<LeanSelectable> Instances = new LinkedList<LeanSelectable>(); [System.NonSerialized] private LinkedListNode<LeanSelectable> instancesNode;
public bool SelfSelected { set { if (selfSelected != value) { selfSelected = value; if (value == true) InvokeOnSelected(null); else InvokeOnDeslected(null); } } get { return selfSelected; } } [SerializeField] private bool selfSelected;
/// <summary>This is invoked every time this object is selected.
/// NOTE: This may occur multiple times.</summary>
public UnityEvent OnSelected { get { if (onSelected == null) onSelected = new UnityEvent(); return onSelected; } } [SerializeField] private UnityEvent onSelected;
/// <summary>This is invoked every time this object is deselected.
/// NOTE: This may occur multiple times.</summary>
public UnityEvent OnDeselected { get { if (onDeselected == null) onDeselected = new UnityEvent(); return onDeselected; } } [FSA("OnDeselect")] [SerializeField] private UnityEvent onDeselected;
public static event System.Action<LeanSelectable> OnAnyEnabled;
public static event System.Action<LeanSelectable> OnAnyDisabled;
public static event System.Action<LeanSelect, LeanSelectable> OnAnySelected;
public static event System.Action<LeanSelect, LeanSelectable> OnAnyDeselected;
protected static List<LeanSelectable> tempSelectables = new List<LeanSelectable>();
/// <summary>This will tell you how many <b>LeanSelect</b> components in the scene currently have this object selected.</summary>
public int SelectedCount
{
get
{
var count = 0;
if (selfSelected == true)
{
count += 1;
}
foreach (var select in LeanSelect.Instances)
{
if (select.IsSelected(this) == true)
{
count += 1;
}
}
return count;
}
}
/// <summary>This will tell you if this object is self selected, or selected by any <b>LeanSelect</b> components in the scene.</summary>
public bool IsSelected
{
get
{
if (selfSelected == true)
{
return true;
}
foreach (var select in LeanSelect.Instances)
{
if (select.IsSelected(this) == true)
{
return true;
}
}
return false;
}
}
public static int IsSelectedCount
{
get
{
var count = 0;
foreach (var selectable in Instances)
{
if (selectable.IsSelected == true)
{
count += 1;
}
}
return count;
}
}
[ContextMenu("Deselect")]
public void Deselect()
{
SelfSelected = false;
foreach (var select in LeanSelect.Instances)
{
select.Deselect(this);
}
}
/// <summary>This deselects all objects in the scene.</summary>
public static void DeselectAll()
{
foreach (var select in LeanSelect.Instances)
{
select.DeselectAll();
}
foreach (var selectable in LeanSelectable.Instances)
{
selectable.SelfSelected = false;
}
}
public void InvokeOnSelected(LeanSelect select)
{
if (onSelected != null)
{
onSelected.Invoke();
}
if (OnAnySelected != null)
{
OnAnySelected.Invoke(select, this);
}
}
public void InvokeOnDeslected(LeanSelect select)
{
if (onDeselected != null)
{
onDeselected.Invoke();
}
if (OnAnyDeselected != null)
{
OnAnyDeselected.Invoke(select, this);
}
}
protected virtual void OnEnable()
{
instancesNode = Instances.AddLast(this);
if (OnAnyEnabled != null)
{
OnAnyEnabled.Invoke(this);
}
}
protected virtual void OnDisable()
{
Instances.Remove(instancesNode); instancesNode = null;
if (OnAnyDisabled != null)
{
OnAnyDisabled.Invoke(this);
}
}
protected virtual void OnDestroy()
{
Deselect();
}
}
}
#if UNITY_EDITOR
namespace Lean.Common.Editor
{
using TARGET = LeanSelectable;
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(TARGET))]
public class LeanSelectable_Editor : LeanEditor
{
[System.NonSerialized] TARGET tgt; [System.NonSerialized] TARGET[] tgts;
protected override void OnInspector()
{
GetTargets(out tgt, out tgts);
DrawSelected();
Separator();
var showUnusedEvents = DrawFoldout("Show Unused Events", "Show all events?");
DrawEvents(showUnusedEvents);
}
private void DrawSelected()
{
BeginDisabled();
UnityEditor.EditorGUILayout.Toggle(new GUIContent("Is Selected", "This will tell you if this object is self selected, or selected by any LeanSelect components in the scene."), tgt.IsSelected);
EndDisabled();
BeginIndent();
if (Draw("selfSelected") == true)
{
Each(tgts, t => t.SelfSelected = serializedObject.FindProperty("selfSelected").boolValue, true);
}
BeginDisabled();
foreach (var select in LeanSelect.Instances)
{
if (IsSelectedByAnyTgt(select) == true)
{
UnityEditor.EditorGUILayout.ObjectField(new GUIContent("selectedBy"), select, typeof(LeanSelect), true);
}
}
EndDisabled();
EndIndent();
}
private bool IsSelectedByAnyTgt(LeanSelect select)
{
foreach (var tgt in tgts)
{
if (select.IsSelected(tgt) == true)
{
return true;
}
}
return false;
}
protected virtual void DrawEvents(bool showUnusedEvents)
{
if (showUnusedEvents == true || Any(tgts, t => t.OnSelected.GetPersistentEventCount() > 0))
{
Draw("onSelected");
}
if (showUnusedEvents == true || Any(tgts, t => t.OnDeselected.GetPersistentEventCount() > 0))
{
Draw("onDeselected");
}
}
}
}
#endif