Created
November 1, 2021 09:49
-
-
Save rubit0/3d267e394751a12b58c0ed8f70d0ac23 to your computer and use it in GitHub Desktop.
MRTK style grab interactable for Unity's XRTK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.XR.Interaction.Toolkit; | |
using UnityEngine.XR.Interaction.Toolkit.AR; | |
[RequireComponent(typeof(ARSelectionInteractable))] | |
public class ARGrabInteractable : ARBaseGestureInteractable | |
{ | |
private const float PositionSpeed = 12f; | |
private const float DiffThreshold = 0.0001f; | |
private Vector3 _targetLocalPosition; | |
private Transform _instanceTransform; | |
private bool _isActive; | |
private float distanceToScreen; | |
protected override void Awake() | |
{ | |
base.Awake(); | |
_instanceTransform = transform; | |
} | |
/// <inheritdoc /> | |
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase) | |
{ | |
base.ProcessInteractable(updatePhase); | |
if (_isActive && | |
updatePhase == XRInteractionUpdateOrder.UpdatePhase.Dynamic) | |
{ | |
UpdatePosition(); | |
} | |
} | |
/// <inheritdoc /> | |
protected override bool CanStartManipulationForGesture(DragGesture gesture) | |
{ | |
// If the gesture isn't targeting this item, don't start manipulating. | |
return gesture.targetObject != null && gesture.targetObject == gameObject; | |
} | |
/// <inheritdoc /> | |
protected override void OnStartManipulation(DragGesture gesture) | |
{ | |
distanceToScreen = arSessionOrigin.camera.WorldToScreenPoint(_instanceTransform.position).z; | |
} | |
/// <inheritdoc /> | |
protected override void OnContinueManipulation(DragGesture gesture) | |
{ | |
_isActive = true; | |
var screenPosition = new Vector3(gesture.position.x, gesture.position.y, distanceToScreen); | |
_targetLocalPosition = arSessionOrigin.camera.ScreenToWorldPoint(screenPosition); | |
} | |
/// <inheritdoc /> | |
protected override void OnEndManipulation(DragGesture gesture) | |
{ | |
_isActive = false; | |
} | |
private void UpdatePosition() | |
{ | |
var oldLocalPosition = _instanceTransform.position; | |
var newLocalPosition = Vector3.Lerp( | |
oldLocalPosition, _targetLocalPosition, Time.deltaTime * PositionSpeed); | |
var diffLength = (_targetLocalPosition - newLocalPosition).magnitude; | |
if (diffLength < DiffThreshold) | |
{ | |
newLocalPosition = _targetLocalPosition; | |
_isActive = false; | |
} | |
_instanceTransform.position = newLocalPosition; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment