SamsonGame/Assets/Sources/Lean/Touch/Extras/LeanSelectByFinger.cs

209 lines
6.4 KiB
C#

using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using Lean.Common;
using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute;
namespace Lean.Touch
{
/// <summary>This component allows you to select LeanSelectable components.
/// To use it, you can call the SelectScreenPosition method from somewhere (e.g. the LeanFingerTap.OnTap event).</summary>
[HelpURL(LeanTouch.HelpUrlPrefix + "LeanSelectByFinger")]
[AddComponentMenu(LeanTouch.ComponentPathPrefix + "Select By Finger")]
public class LeanSelectByFinger : LeanSelect
{
[System.Serializable] public class LeanSelectableLeanFingerEvent : UnityEvent<LeanSelectable, LeanFinger> {}
public LeanScreenQuery ScreenQuery = new LeanScreenQuery(LeanScreenQuery.MethodType.Raycast);
/// <summary>If you enable this then any selected object will automatically be deselected if the finger used to select it is no longer touching the screen.</summary>
public bool DeselectWithFingers { set { deselectWithFingers = value; } get { return deselectWithFingers; } } [SerializeField] private bool deselectWithFingers;
/// <summary>This is invoked when an object is selected.</summary>
public LeanSelectableLeanFingerEvent OnSelectedFinger { get { if (onSelectedFinger == null) onSelectedFinger = new LeanSelectableLeanFingerEvent(); return onSelectedFinger; } } [SerializeField] private LeanSelectableLeanFingerEvent onSelectedFinger;
public static event System.Action<LeanSelectByFinger, LeanSelectable, LeanFinger> OnAnySelectedFinger;
/// <summary>This method allows you to initiate selection at the finger's <b>StartScreenPosition</b>.
/// NOTE: This method be called from somewhere for this component to work (e.g. LeanFingerTap).</summary>
public void SelectStartScreenPosition(LeanFinger finger)
{
SelectScreenPosition(finger, finger.StartScreenPosition);
}
/// <summary>This method allows you to initiate selection at the finger's current <b>ScreenPosition</b>.
/// NOTE: This method be called from somewhere for this component to work (e.g. LeanFingerTap).</summary>
public void SelectScreenPosition(LeanFinger finger)
{
SelectScreenPosition(finger, finger.ScreenPosition);
}
/// <summary>This method allows you to initiate selection of a finger at a custom screen position.
/// NOTE: This method be called from a custom script for this component to work.</summary>
public void SelectScreenPosition(LeanFinger finger, Vector2 screenPosition)
{
var point = default(Vector3);
var result = ScreenQuery.Query<LeanSelectable>(gameObject, screenPosition, ref point);
Select(result, finger);
}
/// <summary>This method allows you to manually select an object with the specified finger using this component's selection settings.</summary>
public void Select(LeanSelectable selectable, LeanFinger finger)
{
if (TrySelect(selectable) == true)
{
var selectableByFinger = selectable as LeanSelectableByFinger;
if (selectableByFinger != null)
{
if (selectableByFinger.SelectingFingers.Contains(finger) == false)
{
selectableByFinger.SelectingFingers.Add(finger);
}
selectableByFinger.OnSelectedFinger.Invoke(finger);
LeanSelectableByFinger.InvokeAnySelectedFinger(this, selectableByFinger, finger);
if (finger.Up == true)
{
selectableByFinger.OnSelectedFingerUp.Invoke(finger);
selectableByFinger.SelectingFingers.Remove(finger);
}
}
if (onSelectedFinger != null) onSelectedFinger.Invoke(selectable, finger);
if (OnAnySelectedFinger != null) OnAnySelectedFinger.Invoke(this, selectable, finger);
}
else
{
if (finger.Up == false)
{
var selectableByFinger = selectable as LeanSelectableByFinger;
if (selectableByFinger != null)
{
if (selectableByFinger.SelectingFingers.Contains(finger) == false)
{
selectableByFinger.SelectingFingers.Add(finger);
}
}
}
}
}
protected virtual void Update()
{
if (deselectWithFingers == true && selectables != null)
{
for (var i = selectables.Count - 1; i >= 0; i--)
{
var selectable = selectables[i];
if (ShouldRemoveSelectable(selectable) == true)
{
Deselect(selectable);
}
}
}
}
private bool ShouldRemoveSelectable(LeanSelectable selectable)
{
var selectableByFinger = selectable as LeanSelectableByFinger;
if (selectableByFinger != null)
{
foreach (var finger in selectableByFinger.SelectingFingers)
{
if (finger.Up == false)
{
return false;
}
}
}
return true;
}
/// <summary>This allows you to replace the currently selected objects with the ones in the specified list. This is useful if you're doing box selection or switching selection groups.</summary>
public void ReplaceSelection(List<LeanSelectable> newSelectables, LeanFinger finger)
{
if (newSelectables != null)
{
// Deselect missing selectables
if (selectables != null)
{
for (var i = selectables.Count - 1; i >= 0; i--)
{
var selectable = selectables[i];
if (newSelectables.Contains(selectable) == false)
{
Deselect(selectable);
}
}
}
// Select new selectables
foreach (var selectable in newSelectables)
{
if (selectables == null || selectables.Contains(selectable) == false)
{
var selectableByFinger = selectable as LeanSelectableByFinger;
if (selectableByFinger != null)
{
Select(selectableByFinger, finger);
}
else
{
Select(selectable);
}
}
}
}
else
{
DeselectAll();
}
}
}
}
#if UNITY_EDITOR
namespace Lean.Touch.Editor
{
using TARGET = LeanSelectByFinger;
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(TARGET))]
public class LeanSelectByFinger_Editor : Common.Editor.LeanSelect_Editor
{
[System.NonSerialized] TARGET tgt; [System.NonSerialized] TARGET[] tgts;
protected override void OnInspector()
{
GetTargets(out tgt, out tgts);
Draw("ScreenQuery");
Draw("deselectWithFingers", "If you enable this then any selected object will automatically be deselected if the finger used to select it is no longer touching the screen.");
base.OnInspector();
}
protected override void DrawEvents(bool showUnusedEvents)
{
base.DrawEvents(showUnusedEvents);
if (Any(tgts, t => t.OnSelectedFinger.GetPersistentEventCount() > 0) == true || showUnusedEvents == true)
{
Draw("onSelectedFinger");
}
}
}
}
#endif