using UnityEngine; using UnityEngine.Events; using System.Collections.Generic; using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute; namespace Lean.Common { /// This component allows you make the current GameObject selectable. [HelpURL(LeanHelper.HelpUrlPrefix + "LeanSelectable")] public class LeanSelectable : MonoBehaviour { [System.Serializable] public class LeanSelectEvent : UnityEvent {} public static LinkedList Instances = new LinkedList(); [System.NonSerialized] private LinkedListNode 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; /// This is invoked every time this object is selected. /// NOTE: This may occur multiple times. public UnityEvent OnSelected { get { if (onSelected == null) onSelected = new UnityEvent(); return onSelected; } } [SerializeField] private UnityEvent onSelected; /// This is invoked every time this object is deselected. /// NOTE: This may occur multiple times. public UnityEvent OnDeselected { get { if (onDeselected == null) onDeselected = new UnityEvent(); return onDeselected; } } [FSA("OnDeselect")] [SerializeField] private UnityEvent onDeselected; public static event System.Action OnAnyEnabled; public static event System.Action OnAnyDisabled; public static event System.Action OnAnySelected; public static event System.Action OnAnyDeselected; protected static List tempSelectables = new List(); /// This will tell you how many LeanSelect components in the scene currently have this object selected. 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; } } /// This will tell you if this object is self selected, or selected by any LeanSelect components in the scene. 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); } } /// This deselects all objects in the scene. 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