// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using UnityEngine; namespace Microsoft.MixedReality.Toolkit.Utilities { /// /// Synchronizes the follower's transform position with the point along the line. /// [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)); /// /// The transform that will follow the point along the line. /// 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; /// /// Gets a point along the line at the specified normalized length. /// 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(); } if (source == null) { Debug.LogError($"Missing a Mixed Reality Line Data Provider for Line Follower on {gameObject.name}"); } } } }