简体   繁体   中英

Unintentionally destroying BoxCollider in Unity

I have a scene in Unity 2018.2.8f1, based off the AvatarGrab sample scene (this is in Assets/Oculus/SampleFramework/Usage, with the "Oculus Integration" package), where the user is supposed to be able to create, move, and delete objects in the scene. My problem is that after using Instantiate to create an object at the position of one of the hands, and then using Destroy to remove it, the user is not able to grab any other objects in the scene. Here is a minimal script that is attached to the scene:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Creator : MonoBehaviour {

    public GameObject leftHandAnchor;
    public GameObject rightHandAnchor;
    public GameObject ballPrefab;

void Update () {

    if (OVRInput.GetDown(OVRInput.RawButton.B)) {
        if (rightHandAnchor != null) {
            AddBall(rightHandAnchor);
        }
    }
    if (OVRInput.GetDown(OVRInput.RawButton.Y)) {
        if (leftHandAnchor != null) {
            AddBall(leftHandAnchor);
        }
    }
    if (OVRInput.GetDown(OVRInput.RawButton.A)) {
        if (rightHandAnchor != null) {
            RemoveBall(rightHandAnchor);
        }
    }
    if (OVRInput.GetDown(OVRInput.RawButton.X)) {
        if (leftHandAnchor != null) {
            RemoveBall(leftHandAnchor);
        }
    }
}

void AddBall (GameObject anchor) {
        GameObject clone = (GameObject)Instantiate(ballPrefab, anchor.transform.position, anchor.transform.rotation);
}

void RemoveBall (GameObject anchor) {
    RaycastHit[] hits = Physics.SphereCastAll(anchor.transform.position, 0.03f, anchor.transform.forward, 0f);
    foreach (RaycastHit ball in hits){
        if (ball.transform.gameObject.tag == "BALL") {
            Destroy(ball.transform.gameObject);
        }
    }
}
}

The actual script is much longer, and is accessible here .

The leftHandAnchor prefab is hand_left from the LocalAvatarWithGrab part of the mentioned scene, and rightHandAnchor is hand_right . The ballPrefab is the default GameObject -> 3D Object -> Sphere, with Box Collider , Rigidbody (gravity off, kinematic on), and OVRGrabbable components added.

So the user creates the balls with B or Y , and is able to move them around by grabbing with the index triggers and letting go. Then, say, A is pressed on the right hand controller when its near a ball to remove (and it does get destroyed). But then, if the user tries to use the index trigger (on the right hand) to move another ball, I get the following error in the console:

在此输入图像描述

The left hand index trigger still works to move any object, but as soon as X on the right hand controller is used to delete an object, no other objects can be grabbed, just like with the right hand.

My guesses for the cause of the problem are that either:

  1. SphereCastAll is picking up the collider of the hands and deleting it, or
  2. the ball prefab is inheriting the collider from the anchor, and destroying the ball is destroying the hand as well.

To fix this, I have tried the following:

  • Add a BALL tag to the ball prefab, only destroy if SphereCastAll picks up an object with that tag.
  • Check if BoxCollider and gameObject are not null before destroying the ball.
  • Pass a vector to RemoveBall instead of the hand's GameObject , then do SphereCastAll near that vector.

None of these have fixed the problem. My current solution is to destroy the MeshRenderer of the ball and turn on gravity so that the ball drops to the bottom of the scene. This is fine for now, but with every ball more objects are added (can expect it to get to ~10 000 objects), and the scene gets quite slow, so I would like to be able to cleanly destroy the balls. So my question is:

How do I destroy a GameObject without destroying the hand that is destroying it?

You have already tried it with tags but this might still work try to give your spherecast a layer:

LayerMask checkThis = indexOfLayersToCheck;  

RaycastHit[] hits = Physics.SphereCastAll(anchor.transform.position, 0.03f, anchor.transform.forward, 0f, checkThis);

Is it the hands box collider thats missing? if yes that would be really weird meaning it's not listening to the tag unless the hand has the same tag? Are the spawned objects completely destroyed(Nothing is left behind inside the inspector) when the spherecast does it's job?

And also try destroying it like this

if (ball.transform.gameObject.tag == "BALL") {
     Destroy(ball.collider.gameObject);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM