将Spline移出Plugin,以调整SplineRenderer的OnWillCameraRender
This commit is contained in:
366
Assets/Dreamteck/Splines/Components/SplineTracer.cs
Normal file
366
Assets/Dreamteck/Splines/Components/SplineTracer.cs
Normal file
@@ -0,0 +1,366 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
public class SplineTracer : SplineUser
|
||||
{
|
||||
public class NodeConnection
|
||||
{
|
||||
public Node node;
|
||||
public int point = 0;
|
||||
|
||||
public NodeConnection(Node node, int point)
|
||||
{
|
||||
this.node = node;
|
||||
this.point = point;
|
||||
}
|
||||
}
|
||||
|
||||
public enum PhysicsMode { Transform, Rigidbody, Rigidbody2D }
|
||||
public PhysicsMode physicsMode
|
||||
{
|
||||
get { return _physicsMode; }
|
||||
set
|
||||
{
|
||||
_physicsMode = value;
|
||||
RefreshTargets();
|
||||
}
|
||||
}
|
||||
|
||||
public TransformModule motion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_motion == null) _motion = new TransformModule();
|
||||
return _motion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the unmodified result from the evaluation
|
||||
/// </summary>
|
||||
public SplineSample result
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
|
||||
public bool dontLerpDirection
|
||||
{
|
||||
get { return _dontLerpDirection; }
|
||||
set
|
||||
{
|
||||
if (value != _dontLerpDirection)
|
||||
{
|
||||
_dontLerpDirection = value;
|
||||
ApplyMotion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Spline.Direction direction
|
||||
{
|
||||
get { return _direction; }
|
||||
set
|
||||
{
|
||||
if (value != _direction)
|
||||
{
|
||||
_direction = value;
|
||||
ApplyMotion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HideInInspector]
|
||||
public bool applyDirectionRotation = true;
|
||||
[HideInInspector]
|
||||
public bool useTriggers = false;
|
||||
[HideInInspector]
|
||||
public int triggerGroup = 0;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Spline.Direction _direction = Spline.Direction.Forward;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected bool _dontLerpDirection = false;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected PhysicsMode _physicsMode = PhysicsMode.Transform;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected TransformModule _motion = null;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Rigidbody targetRigidbody = null;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Rigidbody2D targetRigidbody2D = null;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Transform targetTransform = null;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected SplineSample _result = new SplineSample();
|
||||
|
||||
public delegate void JunctionHandler(List<NodeConnection> passed);
|
||||
|
||||
public event JunctionHandler onNode;
|
||||
public event EmptySplineHandler onMotionApplied;
|
||||
|
||||
private SplineTrigger[] triggerInvokeQueue = new SplineTrigger[0];
|
||||
private List<NodeConnection> nodeConnectionQueue = new List<NodeConnection>();
|
||||
private int addTriggerIndex = 0;
|
||||
|
||||
private const double MIN_DELTA = 0.000001;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override void EditorAwake()
|
||||
{
|
||||
base.EditorAwake();
|
||||
RefreshTargets();
|
||||
ApplyMotion();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
RefreshTargets();
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SetPercent(double percent, bool checkTriggers = false, bool handleJunctions = false)
|
||||
{
|
||||
if (sampleCount == 0) return;
|
||||
double lastPercent = _result.percent;
|
||||
Evaluate(percent, ref _result);
|
||||
ApplyMotion();
|
||||
if (checkTriggers)
|
||||
{
|
||||
CheckTriggers(lastPercent, percent);
|
||||
InvokeTriggers();
|
||||
}
|
||||
if (handleJunctions)
|
||||
{
|
||||
CheckNodes(lastPercent, percent);
|
||||
}
|
||||
}
|
||||
|
||||
public double GetPercent()
|
||||
{
|
||||
return _result.percent;
|
||||
}
|
||||
|
||||
public virtual void SetDistance(float distance, bool checkTriggers = false, bool handleJunctions = false)
|
||||
{
|
||||
double lastPercent = _result.percent;
|
||||
Evaluate(Travel(0.0, distance, Spline.Direction.Forward), ref _result);
|
||||
ApplyMotion();
|
||||
if (checkTriggers)
|
||||
{
|
||||
CheckTriggers(lastPercent, _result.percent);
|
||||
InvokeTriggers();
|
||||
}
|
||||
if (handleJunctions)
|
||||
{
|
||||
CheckNodes(lastPercent, _result.percent);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Rigidbody GetRigidbody()
|
||||
{
|
||||
return GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
protected virtual Rigidbody2D GetRigidbody2D()
|
||||
{
|
||||
return GetComponent<Rigidbody2D>();
|
||||
}
|
||||
|
||||
protected virtual Transform GetTransform()
|
||||
{
|
||||
return transform;
|
||||
}
|
||||
|
||||
protected void ApplyMotion()
|
||||
{
|
||||
if (sampleCount == 0) return;
|
||||
if (_dontLerpDirection)
|
||||
{
|
||||
double unclippedPercent = UnclipPercent(_result.percent);
|
||||
int index;
|
||||
double lerp;
|
||||
spline.GetSamplingValues(unclippedPercent, out index, out lerp);
|
||||
_result.forward = spline[index].forward;
|
||||
_result.up = spline[index].up;
|
||||
}
|
||||
|
||||
motion.targetUser = this;
|
||||
motion.splineResult = _result;
|
||||
if (applyDirectionRotation) motion.direction = _direction;
|
||||
else motion.direction = Spline.Direction.Forward;
|
||||
|
||||
switch (_physicsMode)
|
||||
{
|
||||
case PhysicsMode.Transform:
|
||||
if (targetTransform == null) RefreshTargets();
|
||||
if (targetTransform == null) return;
|
||||
motion.ApplyTransform(targetTransform);
|
||||
if (onMotionApplied != null) onMotionApplied();
|
||||
break;
|
||||
case PhysicsMode.Rigidbody:
|
||||
if (targetRigidbody == null)
|
||||
{
|
||||
RefreshTargets();
|
||||
if (targetRigidbody == null) throw new MissingComponentException("There is no Rigidbody attached to " + name + " but the Physics mode is set to use one.");
|
||||
}
|
||||
motion.ApplyRigidbody(targetRigidbody);
|
||||
if (onMotionApplied != null) onMotionApplied();
|
||||
break;
|
||||
case PhysicsMode.Rigidbody2D:
|
||||
if (targetRigidbody2D == null)
|
||||
{
|
||||
RefreshTargets();
|
||||
if (targetRigidbody2D == null) throw new MissingComponentException("There is no Rigidbody2D attached to " + name + " but the Physics mode is set to use one.");
|
||||
}
|
||||
motion.ApplyRigidbody2D(targetRigidbody2D);
|
||||
if (onMotionApplied != null) onMotionApplied();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CheckNodes(double from, double to)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) return;
|
||||
#endif
|
||||
if (onNode == null) return;
|
||||
if (from == to) return;
|
||||
UnclipPercent(ref from);
|
||||
UnclipPercent(ref to);
|
||||
Spline.FormatFromTo(ref from, ref to, true);
|
||||
int fromPoint, toPoint;
|
||||
fromPoint = spline.PercentToPointIndex(from, _direction);
|
||||
toPoint = spline.PercentToPointIndex(to, _direction);
|
||||
|
||||
if (fromPoint != toPoint)
|
||||
{
|
||||
if (_direction == Spline.Direction.Forward)
|
||||
{
|
||||
for (int i = fromPoint + 1; i <= toPoint; i++)
|
||||
{
|
||||
NodeConnection junction = GetJunction(i);
|
||||
if (junction != null) nodeConnectionQueue.Add(junction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = toPoint - 1; i >= fromPoint; i--)
|
||||
{
|
||||
NodeConnection junction = GetJunction(i);
|
||||
if (junction != null) nodeConnectionQueue.Add(junction);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (from < MIN_DELTA && to > from)
|
||||
{
|
||||
NodeConnection junction = GetJunction(0);
|
||||
if (junction != null) nodeConnectionQueue.Add(junction);
|
||||
}
|
||||
else if (to > 1.0 - MIN_DELTA && from < to)
|
||||
{
|
||||
int pointCount = spline.pointCount - 1;
|
||||
if (spline.isClosed)
|
||||
{
|
||||
pointCount = spline.pointCount;
|
||||
}
|
||||
NodeConnection junction = GetJunction(pointCount);
|
||||
if (junction != null) nodeConnectionQueue.Add(junction);
|
||||
}
|
||||
}
|
||||
|
||||
protected void InvokeNodes()
|
||||
{
|
||||
if(nodeConnectionQueue.Count > 0)
|
||||
{
|
||||
onNode(nodeConnectionQueue);
|
||||
nodeConnectionQueue.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected void CheckTriggers(double from, double to)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) return;
|
||||
#endif
|
||||
if (!useTriggers) return;
|
||||
if (from == to) return;
|
||||
UnclipPercent(ref from);
|
||||
UnclipPercent(ref to);
|
||||
if (triggerGroup < 0 || triggerGroup >= spline.triggerGroups.Length) return;
|
||||
for (int i = 0; i < spline.triggerGroups[triggerGroup].triggers.Length; i++)
|
||||
{
|
||||
if (spline.triggerGroups[triggerGroup].triggers[i] == null) continue;
|
||||
if (spline.triggerGroups[triggerGroup].triggers[i].Check(from, to)) AddTriggerToQueue(spline.triggerGroups[triggerGroup].triggers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
NodeConnection GetJunction(int pointIndex)
|
||||
{
|
||||
Node node = spline.GetNode(pointIndex);
|
||||
if (node == null) return null;
|
||||
return new NodeConnection(node, pointIndex);
|
||||
}
|
||||
|
||||
protected void InvokeTriggers()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) return;
|
||||
#endif
|
||||
for (int i = 0; i < addTriggerIndex; i++)
|
||||
{
|
||||
if (triggerInvokeQueue[i] != null)
|
||||
{
|
||||
triggerInvokeQueue[i].Invoke(this);
|
||||
}
|
||||
}
|
||||
addTriggerIndex = 0;
|
||||
}
|
||||
|
||||
protected void RefreshTargets()
|
||||
{
|
||||
switch (_physicsMode)
|
||||
{
|
||||
case PhysicsMode.Transform:
|
||||
targetTransform = GetTransform();
|
||||
break;
|
||||
case PhysicsMode.Rigidbody:
|
||||
targetRigidbody = GetRigidbody();
|
||||
break;
|
||||
case PhysicsMode.Rigidbody2D:
|
||||
targetRigidbody2D = GetRigidbody2D();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void AddTriggerToQueue(SplineTrigger trigger)
|
||||
{
|
||||
if (addTriggerIndex >= triggerInvokeQueue.Length)
|
||||
{
|
||||
SplineTrigger[] newQueue = new SplineTrigger[triggerInvokeQueue.Length + spline.triggerGroups[triggerGroup].triggers.Length];
|
||||
triggerInvokeQueue.CopyTo(newQueue, 0);
|
||||
triggerInvokeQueue = newQueue;
|
||||
}
|
||||
triggerInvokeQueue[addTriggerIndex] = trigger;
|
||||
addTriggerIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user