rabidus-test/Assets/Dreamteck/Splines/Components/SplineProjector.cs

253 lines
6.9 KiB
C#
Raw Permalink Normal View History

2023-07-24 16:38:13 +03:00
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using UnityEngine.Serialization;
namespace Dreamteck.Splines
{
[ExecuteInEditMode]
[AddComponentMenu("Dreamteck/Splines/Users/Spline Projector")]
public class SplineProjector : SplineTracer
{
public enum Mode {Accurate, Cached}
public Mode mode
{
get { return _mode; }
set
{
if(value != _mode)
{
_mode = value;
Rebuild();
}
}
}
public bool autoProject
{
get { return _autoProject; }
set
{
if(value != _autoProject)
{
_autoProject = value;
if (_autoProject) Rebuild();
}
}
}
public int subdivide
{
get { return _subdivide; }
set
{
if (value != _subdivide)
{
_subdivide = value;
if (_mode == Mode.Accurate) Rebuild();
}
}
}
public Transform projectTarget
{
get {
if (_projectTarget == null) return transform;
return _projectTarget;
}
set
{
if (value != _projectTarget)
{
_projectTarget = value;
Rebuild();
}
}
}
public GameObject targetObject
{
get
{
if (_targetObject == null)
{
if (applyTarget != null) //Temporary check to migrate SplineProjectors that use target
{
_targetObject = applyTarget.gameObject;
applyTarget = null;
return _targetObject;
}
}
return _targetObject;
}
set
{
if (value != _targetObject)
{
_targetObject = value;
RefreshTargets();
Rebuild();
}
}
}
[SerializeField]
[HideInInspector]
private Mode _mode = Mode.Cached;
[SerializeField]
[HideInInspector]
private bool _autoProject = true;
[SerializeField]
[HideInInspector]
[Range(3, 8)]
private int _subdivide = 4;
[SerializeField]
[HideInInspector]
private Transform _projectTarget;
[SerializeField]
[HideInInspector]
private Transform applyTarget = null;
[SerializeField]
[HideInInspector]
private GameObject _targetObject;
[SerializeField]
[HideInInspector]
public Vector2 _offset;
[SerializeField]
[HideInInspector]
public Vector3 _rotationOffset = Vector3.zero;
public event SplineReachHandler onEndReached;
public event SplineReachHandler onBeginningReached;
[SerializeField]
[HideInInspector]
Vector3 lastPosition = Vector3.zero;
protected override void Reset()
{
base.Reset();
_projectTarget = transform;
}
protected override Transform GetTransform()
{
if (targetObject == null) return null;
return targetObject.transform;
}
protected override Rigidbody GetRigidbody()
{
if (targetObject == null) return null;
return targetObject.GetComponent<Rigidbody>();
}
protected override Rigidbody2D GetRigidbody2D()
{
if (targetObject == null) return null;
return targetObject.GetComponent<Rigidbody2D>();
}
protected override void LateRun()
{
base.LateRun();
if (autoProject)
{
if (projectTarget && lastPosition != projectTarget.position)
{
lastPosition = projectTarget.position;
CalculateProjection();
}
}
}
protected override void PostBuild()
{
base.PostBuild();
CalculateProjection();
}
protected override void OnSplineChanged()
{
if (spline != null)
{
if (_mode == Mode.Accurate)
{
spline.Project(_projectTarget.position, ref _result, clipFrom, clipTo, SplineComputer.EvaluateMode.Calculate, subdivide);
}
else
{
spline.Project(_projectTarget.position, ref _result, clipFrom, clipTo);
}
_result.percent = ClipPercent(_result.percent);
}
}
private void Project()
{
if (_mode == Mode.Accurate && spline != null)
{
spline.Project(_projectTarget.position, ref _result, clipFrom, clipTo, SplineComputer.EvaluateMode.Calculate, subdivide);
_result.percent = ClipPercent(_result.percent);
}
else
{
Project(_projectTarget.position, ref _result);
}
}
public void CalculateProjection()
{
if (_projectTarget == null) return;
double lastPercent = _result.percent;
Project();
if (onBeginningReached != null && _result.percent <= clipFrom)
{
if (!Mathf.Approximately((float)lastPercent, (float)_result.percent))
{
onBeginningReached();
if (samplesAreLooped)
{
CheckTriggers(lastPercent, 0.0);
CheckNodes(lastPercent, 0.0);
lastPercent = 1.0;
}
}
}
else if (onEndReached != null && _result.percent >= clipTo)
{
if (!Mathf.Approximately((float)lastPercent, (float)_result.percent))
{
onEndReached();
if (samplesAreLooped)
{
CheckTriggers(lastPercent, 1.0);
CheckNodes(lastPercent, 1.0);
lastPercent = 0.0;
}
}
}
CheckTriggers(lastPercent, _result.percent);
CheckNodes(lastPercent, _result.percent);
if (targetObject != null)
{
ApplyMotion();
}
InvokeTriggers();
InvokeNodes();
lastPosition = projectTarget.position;
}
}
}