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

256 lines
7.2 KiB
C#
Raw Permalink Normal View History

2023-07-24 16:38:13 +03:00
using UnityEngine;
using System.Collections;
using System;
namespace Dreamteck.Splines
{
[AddComponentMenu("Dreamteck/Splines/Users/Spline Positioner")]
[ExecuteInEditMode]
public class SplinePositioner : SplineTracer
{
public enum Mode { Percent, Distance }
public GameObject targetObject
{
get
{
if (_targetObject == null) return gameObject;
return _targetObject;
}
set
{
if (value != _targetObject)
{
_targetObject = value;
RefreshTargets();
Rebuild();
}
}
}
public SplineTracer followTarget
{
get { return _followTarget; }
set
{
if(value != _followTarget)
{
if(_followTarget != null)
{
_followTarget.onMotionApplied -= OnFollowTargetMotionApplied;
}
if(value == this)
{
Debug.Log("You should not be assigning a self-reference to the followTarget field.");
return;
}
_followTarget = value;
if(_followTarget != null)
{
_followTarget.onMotionApplied += OnFollowTargetMotionApplied;
OnFollowTargetMotionApplied();
}
}
}
}
public float followTargetDistance
{
get { return _followTargetDistance; }
set
{
if(value != _followTargetDistance)
{
_followTargetDistance = value;
if(followTarget != null)
{
OnFollowTargetMotionApplied();
}
}
}
}
public bool followLoop
{
get { return _followLoop; }
set
{
if (value != _followLoop)
{
_followLoop = value;
if (followTarget != null)
{
OnFollowTargetMotionApplied();
}
}
}
}
public Spline.Direction followTargetDirection
{
get { return _followTargetDirection; }
set
{
if (value != _followTargetDirection)
{
_followTargetDirection = value;
if (followTarget != null)
{
OnFollowTargetMotionApplied();
}
}
}
}
public double position
{
get
{
return _result.percent;
}
set
{
if (value != _position)
{
_position = (float)value;
if (mode == Mode.Distance)
{
SetDistance(_position, true, true);
}
else
{
SetPercent(value, true, true);
}
}
}
}
public Mode mode
{
get { return _mode; }
set
{
if (value != _mode)
{
_mode = value;
Rebuild();
}
}
}
[SerializeField]
[HideInInspector]
private GameObject _targetObject;
[SerializeField]
[HideInInspector]
private SplineTracer _followTarget;
[SerializeField]
[HideInInspector]
private float _followTargetDistance;
[SerializeField]
[HideInInspector]
private bool _followLoop;
[SerializeField]
[HideInInspector]
private Spline.Direction _followTargetDirection = Spline.Direction.Backward;
[SerializeField]
[HideInInspector]
private float _position = 0f;
[SerializeField]
[HideInInspector]
private Mode _mode = Mode.Percent;
private float _lastPosition = 0f;
private void OnFollowTargetMotionApplied()
{
float moved;
double percent = Travel(followTarget.result.percent, _followTargetDistance, _followTargetDirection, out moved);
if (_followLoop)
{
if (_followTargetDistance - moved > 0.000001f)
{
if (percent <= 0.000001)
{
percent = Travel(1.0, _followTargetDistance - moved, _followTargetDirection, out moved);
}
else if (percent >= 0.999999)
{
percent = Travel(0.0, _followTargetDistance - moved, _followTargetDirection, out moved);
}
}
}
SetPercent(percent, true);
}
protected override void Awake()
{
base.Awake();
if(_followTarget != null)
{
_followTarget.onMotionApplied += OnFollowTargetMotionApplied;
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if (_followTarget != null)
{
_followTarget.onMotionApplied -= OnFollowTargetMotionApplied;
}
}
protected override void OnDidApplyAnimationProperties()
{
if (_lastPosition != _position)
{
_lastPosition = _position;
if (mode == Mode.Distance)
{
SetDistance(_position, true);
}
else
{
SetPercent(_position, true);
}
}
base.OnDidApplyAnimationProperties();
}
protected override Transform GetTransform()
{
return targetObject.transform;
}
protected override Rigidbody GetRigidbody()
{
return targetObject.GetComponent<Rigidbody>();
}
protected override Rigidbody2D GetRigidbody2D()
{
return targetObject.GetComponent<Rigidbody2D>();
}
protected override void PostBuild()
{
base.PostBuild();
if (mode == Mode.Distance) SetDistance((float)_position, true);
else SetPercent(_position, true);
}
public override void SetPercent(double percent, bool checkTriggers = false, bool handleJuncitons = false)
{
base.SetPercent(percent, checkTriggers, handleJuncitons);
_position = (float)percent;
}
public override void SetDistance(float distance, bool checkTriggers = false, bool handleJuncitons = false)
{
base.SetDistance(distance, checkTriggers, handleJuncitons);
_position = distance;
}
}
}