using UnityEngine;
using UnityEngine.Events;
using Lean.Common;
using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute;
namespace Lean.Touch
{
/// This component modifies LeanDragTrail to draw straight lines.
/// NOTE: This requires you to enable LeanTouch.RecordFingers.
[ExecuteInEditMode]
[HelpURL(LeanTouch.PlusHelpUrlPrefix + "LeanDragLine")]
[AddComponentMenu(LeanTouch.ComponentPathPrefix + "Drag Line")]
public class LeanDragLine : LeanDragTrail
{
[System.Serializable] public class Vector3Vector3Event : UnityEvent {}
[System.Serializable] public class Vector3Event : UnityEvent {}
/// The StartWidth and EndWidth values will be increased by this value multiplied by the line length.
/// 0 = No change.
public float WidthScale { set { widthScale = value; } get { return widthScale; } } [FSA("WidthScale")] [SerializeField] private float widthScale = 0.0f;
/// The minimum length of the straight line in world space.
/// -1 = Unrestricted.
public float LengthMin { set { lengthMin = value; } get { return lengthMin; } } [FSA("LengthMin")] [SerializeField] private float lengthMin = -1.0f;
/// The maximum length of the straight line in world space.
/// -1 = Unrestricted.
public float LengthMax { set { lengthMax = value; } get { return lengthMax; } } [FSA("LengthMax")] [SerializeField] private float lengthMax = -1.0f;
/// Enable this if the line should begin from this Transform's position.
public bool StartAtOrigin { set { startAtOrigin = value; } get { return startAtOrigin; } } [FSA("StartAtOrigin")] [SerializeField] private bool startAtOrigin;
/// Drag the line backwards?
public bool Invert { set { invert = value; } get { return invert; } } [FSA("Invert")] [SerializeField] private bool invert;
/// This event gets called when a trail drawing finger goes up.
/// Vector3 = Start world point.
public Vector3Event OnReleasedFrom { get { if (onReleasedFrom == null) onReleasedFrom = new Vector3Event(); return onReleasedFrom; } } [SerializeField] private Vector3Event onReleasedFrom;
/// This event gets called when a trail drawing finger goes up. The parameter contains the end point in world space.
/// Vector3 = End world point.
public Vector3Event OnReleasedTo { get { if (onReleasedTo == null) onReleasedTo = new Vector3Event(); return onReleasedTo; } } [SerializeField] private Vector3Event onReleasedTo;
/// This event gets called when a trail drawing finger goes up. The parameter contains the end point in world space.
/// Vector3 = Vector between start and end world points.
public Vector3Event OnReleasedDelta { get { if (onReleasedDelta == null) onReleasedDelta = new Vector3Event(); return onReleasedDelta; } } [SerializeField] private Vector3Event onReleasedDelta;
/// This event gets called when a trail drawing finger goes up.
/// Vector3 = Start point in world space.
/// Vector3 = End point in world space.
public Vector3Vector3Event OnReleasedFromTo { get { if (onReleasedFromTo == null) onReleasedFromTo = new Vector3Vector3Event(); return onReleasedFromTo; } } [SerializeField] private Vector3Vector3Event onReleasedFromTo;
protected override void UpdateLine(FingerData fingerData, LeanFinger finger, LineRenderer line)
{
var color0 = startColor;
var color1 = endColor;
var width = fingerData.Width;
if (finger != null)
{
// Reserve points
line.positionCount = 2;
// Calculate preliminary points
var point0 = ScreenDepth.Convert(finger.StartScreenPosition, gameObject);
var point1 = ScreenDepth.Convert(finger.ScreenPosition, gameObject);
if (startAtOrigin == true)
{
point0 = transform.position;
}
// Get length, and clamp?
var length = Vector3.Distance(point0, point1);
if (lengthMin >= 0.0f && length < lengthMin)
{
length = lengthMin;
}
if (lengthMax >= 0.0f && length > lengthMax)
{
length = lengthMax;
}
if (invert == true)
{
point1 = point0 - (point1 - point0);
}
// Write straight line
line.SetPosition(0, point0);
line.SetPosition(1, point0 + Vector3.Normalize(point1 - point0) * length);
}
else
{
fingerData.Age += Time.deltaTime;
var alpha = Mathf.InverseLerp(fadeTime, 0.0f, fingerData.Age);
color0.a *= alpha;
color1.a *= alpha;
}
if (widthScale != 0.0f && line.positionCount == 2)
{
var point0 = line.GetPosition(0);
var point1 = line.GetPosition(1);
var length = Vector3.Distance(point0, point1);
width += length * widthScale;
}
line.startColor = color0;
line.endColor = color1;
line.widthMultiplier = width;
}
protected override void HandleFingerUp(LeanFinger finger)
{
var fingerData = LeanFingerData.Find(fingerDatas, finger);
if (fingerData != null)
{
var line = fingerData.Line;
if (line != null && line.positionCount == 2)
{
var worldFrom = line.GetPosition(0);
var worldTo = line.GetPosition(1);
if (onReleasedFrom != null)
{
onReleasedFrom.Invoke(worldFrom);
}
if (onReleasedTo != null)
{
onReleasedTo.Invoke(worldTo);
}
if (onReleasedDelta != null)
{
onReleasedDelta.Invoke(worldTo - worldFrom);
}
if (onReleasedFromTo != null)
{
onReleasedFromTo.Invoke(worldFrom, worldTo);
}
}
fingerData.Finger = null; // The line will gradually fade out in Update
}
}
}
}
#if UNITY_EDITOR
namespace Lean.Touch.Editor
{
using TARGET = LeanDragLine;
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(TARGET))]
public class LeanDragLine_Editor : LeanDragTrail_Editor
{
protected override void OnInspector()
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
base.OnInspector();
Separator();
Draw("widthScale", "The LineRenderer.widthMultiplier values will be increased by this value multiplied by the line length.\n\n0 = No change.");
Draw("lengthMin", "The minimum length of the straight line in world space.\n\n-1 = Unrestricted.");
Draw("lengthMax", "The maximum length of the straight line in world space.\n\n-1 = Unrestricted.");
Draw("startAtOrigin", "Enable this if the line should begin from this Transform's position.");
Draw("invert", "Drag the line backwards?");
Separator();
var usedA = Any(tgts, t => t.OnReleasedFrom.GetPersistentEventCount() > 0);
var usedB = Any(tgts, t => t.OnReleasedTo.GetPersistentEventCount() > 0);
var usedC = Any(tgts, t => t.OnReleasedDelta.GetPersistentEventCount() > 0);
var usedD = Any(tgts, t => t.OnReleasedFromTo.GetPersistentEventCount() > 0);
var showUnusedEvents = DrawFoldout("Show Unused Events", "Show all events?");
if (usedA == true || showUnusedEvents == true)
{
Draw("onReleasedFrom");
}
if (usedB == true || showUnusedEvents == true)
{
Draw("onReleasedTo");
}
if (usedC == true || showUnusedEvents == true)
{
Draw("onReleasedDelta");
}
if (usedD == true || showUnusedEvents == true)
{
Draw("onReleasedFromTo");
}
}
}
}
#endif