205 lines
5.8 KiB
C#
205 lines
5.8 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.UI.HandCoach
|
|
{
|
|
/// <summary>
|
|
/// This class provides functionality to rotate the hand hint around a pivot point over time.
|
|
/// </summary>
|
|
public class RotateAroundPoint : MonoBehaviour
|
|
{
|
|
[Tooltip("Parent object centered at rotation center.")]
|
|
[SerializeField]
|
|
private Transform centeredParent = null;
|
|
|
|
/// <summary>
|
|
/// Parent object centered at rotation center.
|
|
/// </summary>
|
|
public Transform CenteredParent
|
|
{
|
|
get
|
|
{
|
|
return centeredParent;
|
|
}
|
|
set
|
|
{
|
|
centeredParent = value;
|
|
}
|
|
}
|
|
|
|
[Tooltip("Hand hint parent to rotate inverse to centeredParent to keep hand orientation the same.")]
|
|
[SerializeField]
|
|
private Transform inverseParent = null;
|
|
|
|
/// <summary>
|
|
/// Hand hint parent to rotate inverse to centeredParent to keep hand orientation the same.
|
|
/// </summary>
|
|
public Transform InverseParent
|
|
{
|
|
get
|
|
{
|
|
return inverseParent;
|
|
}
|
|
set
|
|
{
|
|
inverseParent = value;
|
|
}
|
|
}
|
|
|
|
[Tooltip("Point to start movement at.")]
|
|
[SerializeField]
|
|
private Transform pivotPosition = null;
|
|
|
|
/// <summary>
|
|
/// Point to start movement at.
|
|
/// </summary>
|
|
public Transform PivotPosition
|
|
{
|
|
get
|
|
{
|
|
return pivotPosition;
|
|
}
|
|
set
|
|
{
|
|
pivotPosition = value;
|
|
}
|
|
}
|
|
|
|
[Tooltip("Duration of rotation around the CenteredParent in seconds.")]
|
|
[SerializeField]
|
|
private float duration = 1.38f;
|
|
|
|
/// <summary>
|
|
/// Duration of rotation around the CenteredParent in seconds.
|
|
/// </summary>
|
|
public float Duration
|
|
{
|
|
get
|
|
{
|
|
return duration;
|
|
}
|
|
set
|
|
{
|
|
duration = value;
|
|
}
|
|
}
|
|
|
|
[Tooltip("Lerp curve that controls the animation rotation over time.")]
|
|
[SerializeField]
|
|
private AnimationCurve animationCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
|
|
|
/// <summary>
|
|
/// Lerp curve that controls the animation rotation over time.
|
|
/// </summary>
|
|
public AnimationCurve AnimationCurve
|
|
{
|
|
get
|
|
{
|
|
return animationCurve;
|
|
}
|
|
set
|
|
{
|
|
animationCurve = value;
|
|
}
|
|
}
|
|
|
|
[Tooltip("How many degrees to rotate along each axis.")]
|
|
[SerializeField]
|
|
private Vector3 rotationVector = new Vector3(0f, 90f, 0f);
|
|
|
|
/// <summary>
|
|
/// How many degrees to rotate along each axis.
|
|
/// </summary>
|
|
public Vector3 RotationVector
|
|
{
|
|
get
|
|
{
|
|
return rotationVector;
|
|
}
|
|
set
|
|
{
|
|
rotationVector = value;
|
|
}
|
|
}
|
|
|
|
private Vector3 centeredParentRotate;
|
|
|
|
private Vector3 hintPosition;
|
|
|
|
// used to allow position changing in LateUpdate() and position correction in RotateHintSequence()
|
|
private bool updatePosition = true;
|
|
|
|
// since this script can attach to an object with an animator, we need to update position in LateUpdate
|
|
public void LateUpdate()
|
|
{
|
|
// set inverseParent position based on DeterminePivot()
|
|
if (updatePosition)
|
|
{
|
|
InverseParent.localPosition = hintPosition;
|
|
}
|
|
|
|
// set centeredParent rotation based on RotateToTarget()
|
|
CenteredParent.localEulerAngles = centeredParentRotate;
|
|
|
|
// set inverseParent rotation based on RotateToTarget() and parent object
|
|
InverseParent.localEulerAngles = -centeredParentRotate;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start the rotation sequence.
|
|
/// </summary>
|
|
public void RotateToTarget()
|
|
{
|
|
StartCoroutine(RotateHintSequence());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset position to the PivotPosition.
|
|
/// </summary>
|
|
public IEnumerator ResetAndDeterminePivot()
|
|
{
|
|
// reset rotation and wait a frame to ensure the centeredParent is set in LateUpdate
|
|
centeredParentRotate = new Vector3(0f, 0f, 0f);
|
|
yield return null;
|
|
|
|
int index = 0;
|
|
|
|
updatePosition = true;
|
|
StartCoroutine(TrackPositionSequence(index));
|
|
}
|
|
|
|
// tracks the pivot determined above
|
|
private IEnumerator TrackPositionSequence(int index)
|
|
{
|
|
while (updatePosition)
|
|
{
|
|
hintPosition = PivotPosition.localPosition;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
// lerp from current position to target position
|
|
private IEnumerator RotateHintSequence()
|
|
{
|
|
updatePosition = false;
|
|
Vector3 centeredOrigin = CenteredParent.localEulerAngles;
|
|
Vector3 targetOrigin = centeredOrigin + RotationVector;
|
|
|
|
float t = 0;
|
|
while (t <= Duration)
|
|
{
|
|
centeredParentRotate = Vector3.Lerp(centeredOrigin, targetOrigin, AnimationCurve.Evaluate(t / duration));
|
|
t += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
|
|
// after we reach the target, we still want to be stabilized
|
|
while (!updatePosition)
|
|
{
|
|
centeredParentRotate = targetOrigin;
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
}
|