// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using UnityEngine; using UnityEngine.Serialization; namespace Microsoft.MixedReality.Toolkit.Utilities.Solvers { /// /// InBetween solver positions an object in-between two tracked transforms. /// [AddComponentMenu("Scripts/MRTK/SDK/InBetween")] public class InBetween : Solver { [SerializeField] [Tooltip("Distance along the center line the object will be located. 0.5 is halfway, 1.0 is at the first transform, 0.0 is at the second transform.")] [Range(0f, 1f)] private float partwayOffset = 0.5f; /// /// Distance along the center line the object will be located. 0.5 is halfway, 1.0 is at the first transform, 0.0 is at the second transform. /// public float PartwayOffset { get { return partwayOffset; } set { partwayOffset = Mathf.Clamp(value, 0.0f, 1.0f); } } [SerializeField] [Tooltip("Tracked object to calculate position and orientation for the second object. If you want to manually override and use a scene object, use the TransformTarget field.")] [HideInInspector] [FormerlySerializedAs("trackedObjectForSecondTransform")] private TrackedObjectType secondTrackedObjectType = TrackedObjectType.Head; /// /// Tracked object to calculate position and orientation for the second object. If you want to manually override and use a scene object, use the TransformTarget field. /// public TrackedObjectType SecondTrackedObjectType { get { return secondTrackedObjectType; } set { if (secondTrackedObjectType != value) { secondTrackedObjectType = value; UpdateSecondSolverHandler(); } } } /// /// Tracked object to calculate position and orientation for the second object. If you want to manually override and use a scene object, use the TransformTarget field. /// [Obsolete("Use SecondTrackedObjectType property instead")] public TrackedObjectType TrackedObjectForSecondTransform { get { return secondTrackedObjectType; } set { if (secondTrackedObjectType != value) { secondTrackedObjectType = value; UpdateSecondSolverHandler(); } } } [SerializeField] [Tooltip("This transform overrides any Tracked Object as the second point for the In Between.")] [HideInInspector] private Transform secondTransformOverride = null; /// /// This transform overrides any Tracked Object as the second point for the In Between /// public Transform SecondTransformOverride { get { return secondTransformOverride; } set { if (secondTransformOverride != value) { secondTransformOverride = value; UpdateSecondSolverHandler(); } } } private SolverHandler secondSolverHandler; protected void OnValidate() { UpdateSecondSolverHandler(); } protected override void Start() { base.Start(); // We need to get the secondSolverHandler ready before we tell them both to seek a tracked object. secondSolverHandler = gameObject.AddComponent(); secondSolverHandler.UpdateSolvers = false; UpdateSecondSolverHandler(); } /// public override void SolverUpdate() { if (SolverHandler != null && secondSolverHandler != null) { if (SolverHandler.TransformTarget != null && secondSolverHandler.TransformTarget != null) { AdjustPositionForOffset(SolverHandler.TransformTarget, secondSolverHandler.TransformTarget); } } } private void AdjustPositionForOffset(Transform targetTransform, Transform secondTransform) { if (targetTransform != null && secondTransform != null) { Vector3 centerline = targetTransform.position - secondTransform.position; GoalPosition = secondTransform.position + (centerline * partwayOffset); } } private void UpdateSecondSolverHandler() { if (secondSolverHandler != null) { secondSolverHandler.TrackedTargetType = secondTrackedObjectType; if (secondTrackedObjectType == TrackedObjectType.CustomOverride && secondTransformOverride != null) { secondSolverHandler.TransformOverride = secondTransformOverride; } } } } }