126 lines
3.5 KiB
C#
126 lines
3.5 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.Utilities
|
|
{
|
|
/// <summary>
|
|
/// Synchronizes the follower's transform position with the point along the line.
|
|
/// </summary>
|
|
[ExecuteAlways]
|
|
[AddComponentMenu("Scripts/MRTK/Core/LineFollower")]
|
|
public class LineFollower : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
[Tooltip("The transform that will follow the point along the line.")]
|
|
private Transform follower;
|
|
|
|
[SerializeField]
|
|
[Tooltip("The transform rotation will be included from the line.")]
|
|
private bool includeRotation = false;
|
|
|
|
[SerializeField]
|
|
[Tooltip("The transform scale will be included based of the Scale Over Length.")]
|
|
private bool includeScale = false;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Animation curve used for scale over the normalized length.")]
|
|
private AnimationCurve scaleOverLength = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
|
|
|
|
/// <summary>
|
|
/// The transform that will follow the point along the line.
|
|
/// </summary>
|
|
public Transform Follower
|
|
{
|
|
get
|
|
{
|
|
if (follower == null)
|
|
{
|
|
follower = transform;
|
|
}
|
|
|
|
return follower;
|
|
}
|
|
set
|
|
{
|
|
follower = value == null ? transform : value;
|
|
}
|
|
}
|
|
|
|
[Range(0f, 1f)]
|
|
[SerializeField]
|
|
[Tooltip("Gets a point along the line at the specified normalized length.")]
|
|
private float normalizedLength = 0f;
|
|
|
|
/// <summary>
|
|
/// Gets a point along the line at the specified normalized length.
|
|
/// </summary>
|
|
public float NormalizedLength
|
|
{
|
|
get { return normalizedLength; }
|
|
set
|
|
{
|
|
if (value < 0f)
|
|
{
|
|
normalizedLength = 0f;
|
|
}
|
|
else if (value > 1f)
|
|
{
|
|
normalizedLength = 1f;
|
|
}
|
|
else
|
|
{
|
|
normalizedLength = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
[SerializeField]
|
|
[HideInInspector]
|
|
private BaseMixedRealityLineDataProvider source = null;
|
|
|
|
#region MonoBehaviour Implementation
|
|
|
|
private void OnEnable() => EnsureSetup();
|
|
|
|
private void Update()
|
|
{
|
|
if (source == null || follower == null) { return; }
|
|
|
|
Vector3 linePoint = source.GetPoint(normalizedLength);
|
|
follower.position = linePoint;
|
|
|
|
if (includeRotation)
|
|
{
|
|
Quaternion lineRotation = source.GetRotation(normalizedLength);
|
|
follower.rotation = lineRotation;
|
|
}
|
|
|
|
if (includeScale)
|
|
{
|
|
follower.localScale = Vector3.one * scaleOverLength.Evaluate(normalizedLength);
|
|
}
|
|
}
|
|
|
|
#endregion MonoBehaviour Implementation
|
|
|
|
private void EnsureSetup()
|
|
{
|
|
if (follower == null)
|
|
{
|
|
follower = transform;
|
|
}
|
|
|
|
if (source == null)
|
|
{
|
|
source = GetComponent<BaseMixedRealityLineDataProvider>();
|
|
}
|
|
|
|
if (source == null)
|
|
{
|
|
Debug.LogError($"Missing a Mixed Reality Line Data Provider for Line Follower on {gameObject.name}");
|
|
}
|
|
}
|
|
}
|
|
} |