MRTK Lever Interaction
#11175
-
Hi! Is there any way to do a lever interaction in an HMD device with hand interaction with the current MRTK manipulation scripts? |
Beta Was this translation helpful? Give feedback.
Answered by
Zee2
Dec 29, 2022
Replies: 1 comment
-
Yep! It probably will require writing a custom interactable. You can try this interactable out for starters; it pivots around the local 0,0,0 of the object, and is constrained to a particular axis. See the issue ticket here where lever-type interactions were discussed: #11186 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using Microsoft.MixedReality.Toolkit;
/// <summary>
/// Models a lever-like pivot interaction around a specified axis.
/// </summary>
public class PivotInteractable : MRTKBaseInteractable
{
// Will constrain pivoting to the specified axis.
// e.g., mode = X => only spin around X axis.
public enum ConstrainMode
{
Free,
X,
Y,
Z
}
[field: SerializeField, Tooltip("Which axis to constrain pivoting to. (e.g., Y results in only spinning around Y axis")]
public ConstrainMode AxisConstraintMode { get; set; } = ConstrainMode.Free;
[field: SerializeField, Tooltip("If set, the script manipulates this transform instead of the transform it's attached to.")]
public Transform CustomTargetTransform { get; set; } = null;
[field: SerializeField, Tooltip("The custom pivot point to use.")]
public Transform CustomPivot { get; set; } = null;
// Which pivot are we actually using?
private Transform pivot => CustomPivot != null ? CustomPivot : target;
// Which target are we actually using?
private Transform target => CustomTargetTransform != null ? CustomTargetTransform : transform;
// The vector from the pivot to the interaction point at the start of the interaction.
private Vector3 fromVec;
// The rotation of the target at the start of the interaction.
private Quaternion fromRot;
// The vector from the pivot to the interaction point at the start of the interaction.
private Vector3 pivotOffset;
protected override void Awake()
{
// We're not poke-able.
DisableInteractorType(typeof(IPokeInteractor));
}
protected override void OnSelectEntered(SelectEnterEventArgs args)
{
base.OnSelectEntered(args);
RecordFromVector();
}
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
{
base.ProcessInteractable(updatePhase);
if (updatePhase == XRInteractionUpdateOrder.UpdatePhase.Dynamic && isSelected)
{
Vector3 toVec = ProjectToConstraintPlane(interactorsSelecting[0].GetAttachTransform(this).position - pivot.position);
// If we've rotated far enough, let's reset our fromVec to avoid
// wrap-around-the-sphere error.
if (Vector3.Angle(fromVec, toVec) > 45)
{
RecordFromVector();
}
Quaternion rot = Quaternion.FromToRotation(fromVec, toVec);
// If pivot == transform, then this pivot offset math is no-op.
target.position = Vector3.Lerp(target.position, rot * (pivotOffset) + pivot.position, 0.5f);
// Simply apply the rot to the fromRot. We'll periodically reset
// the fromRot to avoid wrapping error.
target.rotation = Quaternion.Slerp(target.rotation, rot * fromRot, 0.5f);
}
}
private void RecordFromVector()
{
fromVec = ProjectToConstraintPlane(interactorsSelecting[0].GetAttachTransform(this).position - pivot.position);
fromRot = target.rotation;
pivotOffset = target.position - pivot.position;
}
private Vector3 ProjectToConstraintPlane(Vector3 vec)
{
switch (AxisConstraintMode)
{
case ConstrainMode.Free: return vec;
case ConstrainMode.X: return new Vector3(0, vec.y, vec.z);
case ConstrainMode.Y: return new Vector3(vec.x, 0, vec.z);
case ConstrainMode.Z: return new Vector3(vec.x, vec.y, 0);
default: return vec;
}
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
Zee2
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yep! It probably will require writing a custom interactable. You can try this interactable out for starters; it pivots around the local 0,0,0 of the object, and is constrained to a particular axis. See the issue ticket here where lever-type interactions were discussed: #11186