using UnityEngine; using UnityEngine.Events; using UnityEngine.Serialization; using Lean.Common; using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute; namespace Lean.Touch { /// This component calls OnDown when a finger begins touching the screen on top of this UI element. /// NOTE: This requires you to enable the RaycastTarget setting on your UI graphic. [RequireComponent(typeof(RectTransform))] [HelpURL(LeanTouch.PlusHelpUrlPrefix + "LeanFingerDownCanvas")] [AddComponentMenu(LeanTouch.ComponentPathPrefix + "Finger Down Canvas")] public class LeanFingerDownCanvas : MonoBehaviour { [System.Serializable] public class LeanFingerEvent : UnityEvent {} [System.Serializable] public class Vector3Event : UnityEvent {} /// Ignore fingers with StartedOverGui? public bool IgnoreStartedOverGui { set { ignoreStartedOverGui = value; } get { return ignoreStartedOverGui; } } [FSA("IgnoreStartedOverGui")] [SerializeField] private bool ignoreStartedOverGui = true; /// If the specified object is set and isn't selected, then this component will do nothing. public LeanSelectable RequiredSelectable { set { requiredSelectable = value; } get { return requiredSelectable; } } [FSA("RequiredSelectable")] [SerializeField] private LeanSelectable requiredSelectable; /// Called on the first frame the conditions are met. public LeanFingerEvent OnFinger { get { if (onFinger == null) onFinger = new LeanFingerEvent(); return onFinger; } } [FormerlySerializedAs("onDown")] [FormerlySerializedAs("OnDown")] [SerializeField] private LeanFingerEvent onFinger; /// The method used to find world coordinates from a finger. See LeanScreenDepth documentation for more information. public LeanScreenDepth ScreenDepth = new LeanScreenDepth(LeanScreenDepth.ConversionType.DepthIntercept); /// Called on the first frame the conditions are met. /// Vector3 = Start point based on the ScreenDepth settings. public Vector3Event OnWorld { get { if (onWorld == null) onWorld = new Vector3Event(); return onWorld; } } [SerializeField] private Vector3Event onWorld; public bool ElementOverlapped(LeanFinger finger) { var results = LeanTouch.RaycastGui(finger.ScreenPosition, -1); if (results != null && results.Count > 0) { if (results[0].gameObject == gameObject) { return true; } } return false; } protected virtual void OnEnable() { LeanTouch.OnFingerDown += HandleFingerDown; } protected virtual void OnDisable() { LeanTouch.OnFingerDown -= HandleFingerDown; } private void HandleFingerDown(LeanFinger finger) { if (ignoreStartedOverGui == true && finger.IsOverGui == true) { return; } if (requiredSelectable != null && requiredSelectable.IsSelected == false) { return; } if (ElementOverlapped(finger) == true) { if (onFinger != null) { onFinger.Invoke(finger); } if (onWorld != null) { var position = ScreenDepth.Convert(finger.StartScreenPosition, gameObject); onWorld.Invoke(position); } } } } } #if UNITY_EDITOR namespace Lean.Touch.Editor { using TARGET = LeanFingerDownCanvas; [UnityEditor.CanEditMultipleObjects] [UnityEditor.CustomEditor(typeof(TARGET))] public class LeanFingerDownCanvas_Editor : LeanEditor { protected override void OnInspector() { TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts); Draw("ignoreStartedOverGui", "Ignore fingers with StartedOverGui?"); Draw("requiredSelectable", "If the specified object is set and isn't selected, then this component will do nothing."); Separator(); var showUnusedEvents = DrawFoldout("Show Unused Events", "Show all events?"); if (Any(tgts, t => t.OnFinger.GetPersistentEventCount() > 0) == true || showUnusedEvents == true) { Draw("onFinger"); } if (Any(tgts, t => t.OnWorld.GetPersistentEventCount() > 0) == true || showUnusedEvents == true) { Draw("ScreenDepth"); Draw("onWorld"); } } } } #endif