From 33a40c987a3edcbec902e782ef2f239f343cc5a5 Mon Sep 17 00:00:00 2001 From: henrisel Date: Tue, 13 Jan 2026 19:22:44 +0200 Subject: [PATCH] generated objects are grabbable and scalable --- .../_PROJECT/Scenes/DeltaBuilding_base.unity | 4 +- .../ShapeDetectionMinigameController.cs | 14 +-- .../TwoHandsScaleGrabInteractable.cs | 88 +++++++++++++++++++ .../TwoHandsScaleGrabInteractable.cs.meta | 11 +++ 4 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs create mode 100644 Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs.meta diff --git a/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity b/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity index afc95f90..1997accd 100644 --- a/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity +++ b/Assets/_PROJECT/Scenes/DeltaBuilding_base.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:208f796d8de287c16edc262f5b446ee0f5e9b1bc7477929a45de8dce52192e81 -size 67859705 +oid sha256:9c77e82a1e194d016fc4cde74c15b48b7b9b5a54d8f1dcfce4b155b7c342fd41 +size 67860614 diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs index 2bac25c4..06602b25 100644 --- a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/ShapeDetectionMinigameController.cs @@ -67,17 +67,19 @@ public class ShapeDetectionMinigameController : MonoBehaviour private void InitializeSpawnedObject(GameObject spawnedObject) { - Rigidbody rigidbody = spawnedObject.AddComponent(); + GameObject spawnedObjectParent = new GameObject("SpawnedModelParent"); + spawnedObjectParent.transform.parent = modelSpawnPoint; + spawnedObjectParent.transform.position = modelSpawnPoint.transform.position; + Rigidbody rigidbody = spawnedObjectParent.AddComponent(); rigidbody.isKinematic = true; //spawnedObject.AddComponent(); //spawnedObject.AddComponent(); - spawnedObject.transform.parent = modelSpawnPoint; - spawnedObject.transform.position = modelSpawnPoint.position; + + spawnedObject.transform.parent = spawnedObjectParent.transform; + spawnedObject.transform.position = spawnedObjectParent.transform.position; spawnedObject.tag = shapeScannerTag; - spawnedObject.SetActive(true); - - spawnedObject.AddComponent(); + spawnedObjectParent.AddComponent(); } } diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs new file mode 100644 index 00000000..c0e0ca69 --- /dev/null +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs @@ -0,0 +1,88 @@ + +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; + } +} diff --git a/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs.meta b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs.meta new file mode 100644 index 00000000..b209ef8e --- /dev/null +++ b/Assets/_PROJECT/Scripts/ModeGeneration/ShapeDetection/TwoHandsScaleGrabInteractable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22c2ea15df0386746b1b1bc7b58bced7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: