1
0
forked from cgvr/DeltaVR

shape scanner supports multiple object scanning, always destroys colliding objects on config completion

This commit is contained in:
2026-03-01 11:30:33 +02:00
parent dfdb47b94a
commit 95e67b9870
14 changed files with 90 additions and 97 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
[Serializable]
@@ -29,26 +30,25 @@ public class ShapeScanner : MonoBehaviour
public Transform rayParent;
public TextMeshProUGUI currentConfigurationDisplay;
public TextMeshProUGUI correctPercentageDisplay;
public XRInteractionManager interactionManager;
public Material requiredAndActive;
public Material requiredAndPassive;
public Material notRequiredAndActive;
public Material notRequiredAndPassive;
private List<GameObject> existingRays;
private List<ShapeScannerRay> existingRays;
private float raySpawnDistanceX;
private float raySpawnDistanceZ;
private int currentConfiguration;
private int rayCount;
private int correctRayStates;
private GameObject currentlyScannableObject;
// Start is called before the first frame update
void Start()
{
existingRays = new List<GameObject>();
existingRays = new List<ShapeScannerRay>();
raySpawnDistanceX = raySpawnCorner2.localPosition.x - raySpawnCorner1.localPosition.x;
raySpawnDistanceZ = raySpawnCorner2.localPosition.z - raySpawnCorner1.localPosition.z;
@@ -62,34 +62,15 @@ public class ShapeScanner : MonoBehaviour
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == rayPrefab.scannableTag)
{
currentlyScannableObject = other.gameObject;
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == rayPrefab.scannableTag)
{
currentlyScannableObject = null;
}
}
private void InitializeConfiguration()
{
// Delete all existing rays first
foreach (GameObject ray in existingRays)
// Delete all colliding objects and then all existing rays
DestroyCollidingObjects();
foreach (ShapeScannerRay ray in existingRays)
{
Destroy(ray);
}
if (currentlyScannableObject != null)
{
currentlyScannableObject.transform.position = Vector3.zero;
Destroy(currentlyScannableObject);
Destroy(ray.gameObject);
}
existingRays.Clear();
ShapeScannerConfiguration configuration = configurations[currentConfiguration];
int rayRowCount = configuration.rows.Count;
@@ -103,7 +84,7 @@ public class ShapeScanner : MonoBehaviour
Vector3 rayPos = new Vector3(rayPosX, 0, rayPosZ);
ShapeScannerRay ray = Instantiate(rayPrefab, rayParent);
ray.transform.localPosition = rayPos;
existingRays.Add(ray.gameObject);
existingRays.Add(ray);
bool rayCollisionRequired = configuration.rows[i].cells[j];
if (rayCollisionRequired)
@@ -122,6 +103,31 @@ public class ShapeScanner : MonoBehaviour
UpdateDisplay(calculateCorrectPercentage());
}
private void DestroyCollidingObjects()
{
HashSet<GameObject> allCollidingObjects = new HashSet<GameObject>();
foreach (ShapeScannerRay ray in existingRays)
{
allCollidingObjects.UnionWith(ray.GetCollidingObjects());
}
foreach (GameObject collidingObject in allCollidingObjects)
{
// Release player holding it
var grab = collidingObject.GetComponent<XRGrabInteractable>();
if (grab != null && grab.isSelected)
{
var interactor = grab.firstInteractorSelecting; // the hand/controller currently holding it
if (interactor != null)
{
// Transfer ownership: tell the manager to stop the selection
interactionManager.SelectExit(interactor, grab);
}
}
collidingObject.transform.position = Vector3.zero;
Destroy(collidingObject);
}
}
private float calculateCorrectPercentage()
{
return Mathf.RoundToInt((float)correctRayStates / rayCount * 100);