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; } }