124 lines
4.2 KiB
C#
124 lines
4.2 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using Microsoft.MixedReality.Toolkit.Utilities;
|
|
using Unity.Profiling;
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.Input
|
|
{
|
|
[AddComponentMenu("Scripts/MRTK/SDK/SpherePointerVisual")]
|
|
public class SpherePointerVisual : MonoBehaviour
|
|
{
|
|
public Transform TetherEndPoint => tetherEndPoint;
|
|
|
|
public bool TetherVisualsEnabled { get; private set; }
|
|
|
|
[Tooltip("The pointer these visuals decorate")]
|
|
private SpherePointer pointer;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Tether will not be shown unless it is at least this long")]
|
|
private float minTetherLength = 0.03f;
|
|
|
|
[SerializeField]
|
|
private Transform visualsRoot = null;
|
|
|
|
[SerializeField]
|
|
private Transform tetherEndPoint = null;
|
|
|
|
/// Assumption: Tether line is a child of the visuals!
|
|
[SerializeField]
|
|
private BaseMixedRealityLineDataProvider tetherLine = null;
|
|
|
|
public void OnEnable()
|
|
{
|
|
CheckInitialization();
|
|
}
|
|
|
|
public void OnDestroy()
|
|
{
|
|
if (visualsRoot != null)
|
|
{
|
|
Destroy(visualsRoot.gameObject);
|
|
}
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
// put it at root of scene
|
|
MixedRealityPlayspace.AddChild(visualsRoot.transform);
|
|
visualsRoot.gameObject.name = $"{gameObject.name}_NearTetherVisualsRoot";
|
|
}
|
|
|
|
private void CheckInitialization()
|
|
{
|
|
if (pointer == null)
|
|
{
|
|
pointer = GetComponent<SpherePointer>();
|
|
}
|
|
|
|
if (pointer == null)
|
|
{
|
|
Debug.LogError($"No SpherePointer found on {gameObject.name}.");
|
|
}
|
|
|
|
CheckAsset(visualsRoot, "Visuals Root");
|
|
CheckAsset(tetherEndPoint, "Tether End Point");
|
|
CheckAsset(tetherLine, "Tether Line");
|
|
}
|
|
|
|
private void CheckAsset(object asset, string fieldname)
|
|
{
|
|
if (asset == null)
|
|
{
|
|
Debug.LogError($"No {fieldname} specified on {gameObject.name}.SpherePointerVisual. Did you forget to set the {fieldname}?");
|
|
}
|
|
}
|
|
|
|
private static readonly ProfilerMarker UpdatePerfMarker = new ProfilerMarker("[MRTK] SpherePointerVisual.Update");
|
|
|
|
public void Update()
|
|
{
|
|
using (UpdatePerfMarker.Auto())
|
|
{
|
|
TetherVisualsEnabled = false;
|
|
if (pointer.IsFocusLocked && pointer.IsTargetPositionLockedOnFocusLock && pointer.Result != null)
|
|
{
|
|
NearInteractionGrabbable grabbedObject = GetGrabbedObject();
|
|
if (grabbedObject != null && grabbedObject.ShowTetherWhenManipulating)
|
|
{
|
|
Vector3 graspPosition;
|
|
pointer.TryGetNearGraspPoint(out graspPosition);
|
|
tetherLine.FirstPoint = graspPosition;
|
|
Vector3 endPoint = pointer.Result.Details.Object.transform.TransformPoint(pointer.Result.Details.PointLocalSpace);
|
|
tetherLine.LastPoint = endPoint;
|
|
TetherVisualsEnabled = Vector3.Distance(tetherLine.FirstPoint, tetherLine.LastPoint) > minTetherLength;
|
|
tetherLine.enabled = TetherVisualsEnabled;
|
|
tetherEndPoint.gameObject.SetActive(TetherVisualsEnabled);
|
|
tetherEndPoint.position = endPoint;
|
|
}
|
|
}
|
|
|
|
visualsRoot.gameObject.SetActive(TetherVisualsEnabled);
|
|
}
|
|
}
|
|
|
|
private static readonly ProfilerMarker GetGrabbedObjectPerfMarker = new ProfilerMarker("[MRTK] SpherePointer.GetGrabbedObject");
|
|
|
|
private NearInteractionGrabbable GetGrabbedObject()
|
|
{
|
|
using (GetGrabbedObjectPerfMarker.Auto())
|
|
{
|
|
if (pointer.Result?.Details.Object != null)
|
|
{
|
|
return pointer.Result.Details.Object.GetComponent<NearInteractionGrabbable>();
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |