323 lines
12 KiB
C#
323 lines
12 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using Microsoft.MixedReality.Toolkit.Utilities;
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.UI
|
|
{
|
|
/// <summary>
|
|
/// Connects a ToolTip to a target
|
|
/// Maintains that connection even if the target moves
|
|
/// </summary>
|
|
[ExecuteAlways]
|
|
[AddComponentMenu("Scripts/MRTK/SDK/ToolTipConnector")]
|
|
public class ToolTipConnector : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
[Tooltip("The GameObject to which the tooltip is connected")]
|
|
private GameObject target;
|
|
|
|
/// <summary>
|
|
/// The GameObject to which the tooltip is connected
|
|
/// </summary>
|
|
public GameObject Target
|
|
{
|
|
get { return target; }
|
|
set { target = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
private ToolTip toolTip;
|
|
|
|
[SerializeField]
|
|
[Tooltip("The follow style of the tooltip connector")]
|
|
private ConnectorFollowType connectorFollowType = ConnectorFollowType.AnchorOnly;
|
|
|
|
/// <summary>
|
|
/// The follow style of the tooltip connector
|
|
/// </summary>
|
|
public ConnectorFollowType ConnectorFollowingType
|
|
{
|
|
get { return connectorFollowType; }
|
|
set { connectorFollowType = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
[Tooltip("Is the connector pivot set manually or automatically?")]
|
|
private ConnectorPivotMode pivotMode = ConnectorPivotMode.Manual;
|
|
|
|
/// <summary>
|
|
/// Is the connector pivot set manually or automatically?
|
|
/// </summary>
|
|
public ConnectorPivotMode PivotMode
|
|
{
|
|
get { return pivotMode; }
|
|
set { pivotMode = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
[Tooltip("The direction of the connector")]
|
|
private ConnectorPivotDirection pivotDirection = ConnectorPivotDirection.North;
|
|
|
|
/// <summary>
|
|
/// The direction of the connector
|
|
/// </summary>
|
|
public ConnectorPivotDirection PivotDirection
|
|
{
|
|
get { return pivotDirection; }
|
|
set { pivotDirection = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
[Tooltip("orientation style for connector")]
|
|
private ConnectorOrientType pivotDirectionOrient = ConnectorOrientType.OrientToObject;
|
|
|
|
/// <summary>
|
|
/// Orientation style for connector
|
|
/// </summary>
|
|
public ConnectorOrientType PivotDirectionOrient
|
|
{
|
|
get { return pivotDirectionOrient; }
|
|
set { pivotDirectionOrient = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
[Tooltip("The direction of the manual pivot.")]
|
|
private Vector3 manualPivotDirection = Vector3.up;
|
|
|
|
/// <summary>
|
|
/// The direction of the manual pivot.
|
|
/// </summary>
|
|
public Vector3 ManualPivotDirection
|
|
{
|
|
get { return manualPivotDirection; }
|
|
set { manualPivotDirection = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
private Vector3 manualPivotLocalPosition = Vector3.up;
|
|
|
|
/// <summary>
|
|
/// getter/setter for local pivot position
|
|
/// </summary>
|
|
public Vector3 ManualPivotLocalPosition
|
|
{
|
|
get { return manualPivotLocalPosition; }
|
|
set { manualPivotLocalPosition = value; }
|
|
}
|
|
|
|
[SerializeField]
|
|
[Range(0f, 2f)]
|
|
[Tooltip("Set Distance from object that Tooltip pivots around.")]
|
|
private float pivotDistance = 0.25f;
|
|
|
|
/// <summary>
|
|
/// Set Distance from object that Tooltip pivots around.
|
|
/// </summary>
|
|
public float PivotDistance
|
|
{
|
|
get { return pivotDistance; }
|
|
set { pivotDistance = Mathf.Min(2.0f, Mathf.Max(0, value)); }
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
toolTip = gameObject.GetComponent<ToolTip>();
|
|
if (toolTip == null)
|
|
{
|
|
Debug.LogWarning("This component only works with a ToolTip.");
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
UpdatePosition();
|
|
}
|
|
|
|
private void UpdatePosition()
|
|
{
|
|
if (target == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (connectorFollowType)
|
|
{
|
|
case ConnectorFollowType.AnchorOnly:
|
|
default:
|
|
// Set the position of the anchor to the target's position
|
|
// And do nothing else
|
|
toolTip.Anchor.transform.position = target.transform.position;
|
|
break;
|
|
|
|
case ConnectorFollowType.Position:
|
|
// Move the entire tooltip transform while maintaining the anchor position offset
|
|
toolTip.transform.position = target.transform.position;
|
|
switch (PivotMode)
|
|
{
|
|
case ConnectorPivotMode.Automatic:
|
|
Transform relativeTo = null;
|
|
switch (PivotDirectionOrient)
|
|
{
|
|
case ConnectorOrientType.OrientToCamera:
|
|
relativeTo = CameraCache.Main.transform;
|
|
break;
|
|
|
|
case ConnectorOrientType.OrientToObject:
|
|
relativeTo = target.transform;
|
|
break;
|
|
}
|
|
|
|
toolTip.PivotPosition = target.transform.position + GetDirectionFromPivotDirection(
|
|
PivotDirection,
|
|
ManualPivotDirection,
|
|
relativeTo) * PivotDistance;
|
|
break;
|
|
|
|
case ConnectorPivotMode.LocalPosition:
|
|
toolTip.PivotPosition = target.transform.position + target.transform.TransformPoint(manualPivotLocalPosition);
|
|
break;
|
|
|
|
case ConnectorPivotMode.Manual:
|
|
// Do nothing
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case ConnectorFollowType.PositionAndYRotation:
|
|
// Set the transform of the entire tool tip
|
|
// Set the pivot relative to target/camera
|
|
toolTip.transform.position = target.transform.position;
|
|
Vector3 eulerAngles = target.transform.eulerAngles;
|
|
eulerAngles.x = 0f;
|
|
eulerAngles.z = 0f;
|
|
toolTip.transform.eulerAngles = eulerAngles;
|
|
|
|
switch (PivotMode)
|
|
{
|
|
case ConnectorPivotMode.Automatic:
|
|
Transform relativeTo = null;
|
|
switch (PivotDirectionOrient)
|
|
{
|
|
case ConnectorOrientType.OrientToCamera:
|
|
relativeTo = CameraCache.Main.transform;
|
|
break;
|
|
|
|
case ConnectorOrientType.OrientToObject:
|
|
relativeTo = target.transform;
|
|
break;
|
|
}
|
|
Vector3 localPosition = GetDirectionFromPivotDirection(PivotDirection, ManualPivotDirection, relativeTo) * PivotDistance;
|
|
toolTip.PivotPosition = target.transform.position + localPosition;
|
|
break;
|
|
|
|
case ConnectorPivotMode.LocalPosition:
|
|
toolTip.PivotPosition = target.transform.position + target.transform.TransformPoint(manualPivotLocalPosition);
|
|
break;
|
|
|
|
case ConnectorPivotMode.Manual:
|
|
// Do nothing
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case ConnectorFollowType.PositionAndXYRotation:
|
|
// Set the transform of the entire tool tip
|
|
// Set the pivot relative to target/camera
|
|
toolTip.transform.position = target.transform.position;
|
|
toolTip.transform.rotation = target.transform.rotation;
|
|
switch (PivotMode)
|
|
{
|
|
case ConnectorPivotMode.Automatic:
|
|
Transform relativeTo = null;
|
|
switch (PivotDirectionOrient)
|
|
{
|
|
case ConnectorOrientType.OrientToCamera:
|
|
relativeTo = CameraCache.Main.transform;
|
|
break;
|
|
|
|
case ConnectorOrientType.OrientToObject:
|
|
relativeTo = target.transform;
|
|
break;
|
|
}
|
|
toolTip.PivotPosition = target.transform.position + GetDirectionFromPivotDirection(
|
|
PivotDirection,
|
|
ManualPivotDirection,
|
|
relativeTo) * PivotDistance;
|
|
break;
|
|
|
|
case ConnectorPivotMode.LocalPosition:
|
|
toolTip.PivotPosition = target.transform.position + target.transform.TransformPoint(manualPivotLocalPosition);
|
|
break;
|
|
|
|
case ConnectorPivotMode.Manual:
|
|
// Do nothing
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
UpdatePosition();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Computes the director of the connector
|
|
/// </summary>
|
|
/// <param name="pivotDirection">enum describing director of connector pivot</param>
|
|
/// <param name="manualPivotDirection">is the pivot set manually</param>
|
|
/// <param name="relativeTo">Transform that describes the frame of reference of the pivot</param>
|
|
/// <returns>a vector describing the pivot direction in world space</returns>
|
|
public static Vector3 GetDirectionFromPivotDirection(ConnectorPivotDirection pivotDirection, Vector3 manualPivotDirection, Transform relativeTo)
|
|
{
|
|
Vector3 dir = Vector3.zero;
|
|
|
|
switch (pivotDirection)
|
|
{
|
|
case ConnectorPivotDirection.North:
|
|
dir = Vector3.up;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.Northeast:
|
|
dir = Vector3.Lerp(Vector3.up, Vector3.right, 0.5f).normalized;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.East:
|
|
dir = Vector3.right;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.Southeast:
|
|
dir = Vector3.Lerp(Vector3.down, Vector3.right, 0.5f).normalized;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.South:
|
|
dir = Vector3.down;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.Southwest:
|
|
dir = Vector3.Lerp(Vector3.down, Vector3.left, 0.5f).normalized;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.West:
|
|
dir = Vector3.left;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.Northwest:
|
|
dir = Vector3.Lerp(Vector3.up, Vector3.left, 0.5f).normalized;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.InFront:
|
|
dir = Vector3.forward;
|
|
break;
|
|
|
|
case ConnectorPivotDirection.Manual:
|
|
dir = manualPivotDirection.normalized;
|
|
break;
|
|
}
|
|
|
|
return relativeTo.TransformDirection(dir);
|
|
}
|
|
}
|
|
} |