forked from cgvr/DeltaVR
89 lines
2.6 KiB
C#
89 lines
2.6 KiB
C#
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.XR.Interaction.Toolkit;
|
|
|
|
public class TwoHandScaleGrabInteractable : XRGrabInteractable
|
|
{
|
|
[Header("Two-Hand Scaling")]
|
|
public float minScale = 0.1f;
|
|
public float maxScale = 5f;
|
|
public float scaleLerpSpeed = 0f;
|
|
|
|
private Transform scalingTransform;
|
|
private float initialHandsDistance;
|
|
private Vector3 initialScale;
|
|
private bool twoHandsGrabbing;
|
|
|
|
void Start()
|
|
{
|
|
selectMode = InteractableSelectMode.Multiple;
|
|
useDynamicAttach = true;
|
|
reinitializeDynamicAttachEverySingleGrab = false;
|
|
|
|
scalingTransform = transform.GetChild(0);
|
|
}
|
|
|
|
protected override void OnSelectEntered(SelectEnterEventArgs args)
|
|
{
|
|
base.OnSelectEntered(args);
|
|
UpdateTwoHandState();
|
|
}
|
|
|
|
protected override void OnSelectExited(SelectExitEventArgs args)
|
|
{
|
|
Debug.Log("current local scale: " + transform.localScale);
|
|
base.OnSelectExited(args);
|
|
UpdateTwoHandState();
|
|
}
|
|
|
|
void UpdateTwoHandState()
|
|
{
|
|
if (interactorsSelecting.Count >= 2)
|
|
{
|
|
var a = interactorsSelecting[0];
|
|
var b = interactorsSelecting[1];
|
|
|
|
var pA = a.GetAttachTransform(this).position;
|
|
var pB = b.GetAttachTransform(this).position;
|
|
|
|
initialHandsDistance = Vector3.Distance(pA, pB);
|
|
initialScale = scalingTransform.localScale;
|
|
twoHandsGrabbing = initialHandsDistance > 0.0001f;
|
|
}
|
|
else
|
|
{
|
|
twoHandsGrabbing = false;
|
|
}
|
|
}
|
|
|
|
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
|
|
{
|
|
base.ProcessInteractable(updatePhase);
|
|
|
|
if (!twoHandsGrabbing || interactorsSelecting.Count < 2 || initialHandsDistance <= 0.0001f)
|
|
return;
|
|
var a = interactorsSelecting[0];
|
|
var b = interactorsSelecting[1];
|
|
|
|
var pA = a.GetAttachTransform(this).position;
|
|
var pB = b.GetAttachTransform(this).position;
|
|
|
|
float current = Vector3.Distance(pA, pB);
|
|
if (current <= 0.0001f)
|
|
return;
|
|
|
|
float ratio = current / initialHandsDistance;
|
|
Debug.Log("distance ratio: " + ratio);
|
|
|
|
Vector3 desired = initialScale * ratio;
|
|
float uniform = Mathf.Clamp(desired.x, minScale, maxScale);
|
|
desired = new Vector3(uniform, uniform, uniform);
|
|
|
|
if (scaleLerpSpeed > 0f)
|
|
desired = Vector3.Lerp(transform.localScale, desired, Time.deltaTime * scaleLerpSpeed);
|
|
|
|
scalingTransform.localScale = desired;
|
|
}
|
|
}
|