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

221 lines
6.4 KiB
C#

using UnityEngine;
using System.Collections.Generic;
using Lean.Common;
using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute;
namespace Lean.Touch
{
/// <summary>This component draws trails behind fingers.
/// NOTE: This requires you to enable the LeanTouch.RecordFingers setting.</summary>
[ExecuteInEditMode]
[HelpURL(LeanTouch.HelpUrlPrefix + "LeanDragTrail")]
[AddComponentMenu(LeanTouch.ComponentPathPrefix + "Drag Trail")]
public class LeanDragTrail : MonoBehaviour
{
// This class stores additional data for each LeanFinger
[System.Serializable]
public class FingerData : LeanFingerData
{
public LineRenderer Line;
public float Age;
public float Width;
}
/// <summary>The method used to find fingers to use with this component. See LeanFingerFilter documentation for more information.</summary>
public LeanFingerFilter Use = new LeanFingerFilter(true);
/// <summary>The method used to convert between screen coordinates, and world coordinates.</summary>
public LeanScreenDepth ScreenDepth = new LeanScreenDepth(LeanScreenDepth.ConversionType.FixedDistance, Physics.DefaultRaycastLayers, 10.0f);
/// <summary>The line prefab that will be used to render the trails.</summary>
public LineRenderer Prefab { set { prefab = value; } get { return prefab; } } [FSA("Prefab")] [SerializeField] private LineRenderer prefab;
/// <summary>The maximum amount of active trails.
/// -1 = Unlimited.</summary>
public int MaxTrails { set { maxTrails = value; } get { return maxTrails; } } [FSA("MaxTrails")] [SerializeField] private int maxTrails = -1;
/// <summary>How many seconds it takes for each trail to disappear after a finger is released.</summary>
public float FadeTime { set { fadeTime = value; } get { return fadeTime; } } [FSA("FadeTime")] [SerializeField] protected float fadeTime = 1.0f;
/// <summary>The color of the trail start.</summary>
public Color StartColor { set { startColor = value; } get { return startColor; } } [FSA("StartColor")] [SerializeField] protected Color startColor = Color.white;
/// <summary>The color of the trail end.</summary>
public Color EndColor { set { endColor = value; } get { return endColor; } } [FSA("EndColor")] [SerializeField] protected Color endColor = Color.white;
// This stores all the links between fingers and LineRenderer instances
[SerializeField]
protected List<FingerData> fingerDatas = new List<FingerData>();
/// <summary>If you've set Use to ManuallyAddedFingers, then you can call this method to manually add a finger.</summary>
public void AddFinger(LeanFinger finger)
{
Use.AddFinger(finger);
}
/// <summary>If you've set Use to ManuallyAddedFingers, then you can call this method to manually remove a finger.</summary>
public void RemoveFinger(LeanFinger finger)
{
Use.RemoveFinger(finger);
}
/// <summary>If you've set Use to ManuallyAddedFingers, then you can call this method to manually remove all fingers.</summary>
public void RemoveAllFingers()
{
Use.RemoveAllFingers();
}
#if UNITY_EDITOR
protected virtual void Reset()
{
Use.UpdateRequiredSelectable(gameObject);
}
#endif
protected virtual void Awake()
{
Use.UpdateRequiredSelectable(gameObject);
}
protected virtual void OnEnable()
{
LeanTouch.OnFingerUp += HandleFingerUp;
}
protected virtual void OnDisable()
{
LeanTouch.OnFingerUp -= HandleFingerUp;
}
protected virtual void Update()
{
// Get the fingers we want to use
var fingers = Use.UpdateAndGetFingers(true);
for (var i = 0; i < fingers.Count; i++)
{
var finger = fingers[i];
if (LeanFingerData.Exists(fingerDatas, finger) == false)
{
// Too many active links?
if (maxTrails >= 0 && LeanFingerData.Count(fingerDatas) >= maxTrails)
{
continue;
}
if (prefab != null)
{
// Spawn and activate
var clone = Instantiate(prefab);
clone.gameObject.SetActive(true);
// Register with FingerData
var fingerData = LeanFingerData.FindOrCreate(ref fingerDatas, finger);
fingerData.Line = clone;
fingerData.Age = 0.0f;
fingerData.Width = prefab.widthMultiplier;
}
}
}
// Update all FingerData
for (var i = fingerDatas.Count - 1; i >= 0; i--)
{
var fingerData = fingerDatas[i];
if (fingerData.Line != null)
{
UpdateLine(fingerData, fingerData.Finger, fingerData.Line);
if (fingerData.Age >= fadeTime)
{
Destroy(fingerData.Line.gameObject);
fingerDatas.RemoveAt(i);
}
}
else
{
fingerDatas.RemoveAt(i);
}
}
}
protected virtual void UpdateLine(FingerData fingerData, LeanFinger finger, LineRenderer line)
{
var color0 = startColor;
var color1 = endColor;
if (finger != null)
{
// Reserve one point for each snapshot
line.positionCount = finger.Snapshots.Count;
// Loop through all snapshots
for (var i = 0; i < finger.Snapshots.Count; i++)
{
var snapshot = finger.Snapshots[i];
// Get the world position of this snapshot
var worldPoint = ScreenDepth.Convert(snapshot.ScreenPosition, gameObject);
// Write position
line.SetPosition(i, worldPoint);
}
}
else
{
fingerData.Age += Time.deltaTime;
var alpha = Mathf.InverseLerp(fadeTime, 0.0f, fingerData.Age);
color0.a *= alpha;
color1.a *= alpha;
}
line.startColor = color0;
line.endColor = color1;
}
protected virtual void HandleFingerUp(LeanFinger finger)
{
var link = LeanFingerData.Find(fingerDatas, finger);
if (link != null)
{
link.Finger = null; // The line will gradually fade out in Update
}
}
}
}
#if UNITY_EDITOR
namespace Lean.Touch.Editor
{
using TARGET = LeanDragTrail;
[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(TARGET), true)]
public class LeanDragTrail_Editor : LeanEditor
{
protected override void OnInspector()
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
Draw("Use");
Draw("ScreenDepth");
Draw("prefab", "The line prefab that will be used to render the trails.");
Draw("maxTrails", "The maximum amount of active trails.\n\n-1 = Unlimited.");
Separator();
Draw("fadeTime", "How many seconds it takes for each trail to disappear after a finger is released.");
Draw("startColor", "The color of the trail start.");
Draw("endColor", "The color of the trail end.");
}
}
}
#endif