简体   繁体   English

无意中破坏了Unity中的BoxCollider

[英]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. 我在Unity 2018.2.8f1中有一个基于AvatarGrab示例场景的场景(这是在Assets / Oculus / SampleFramework / Usage中,使用“Oculus Integration”包),用户应该能够创建,移动,并删除场景中的对象。 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. 我的问题是,在使用Instantiate在其中一个手的位置创建一个对象,然后使用Destroy删除它之后,用户无法抓取场景中的任何其他对象。 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 . leftHandAnchor预制的hand_leftLocalAvatarWithGrab所提到的场景的一部分,而rightHandAnchorhand_right The ballPrefab is the default GameObject -> 3D Object -> Sphere, with Box Collider , Rigidbody (gravity off, kinematic on), and OVRGrabbable components added. ballPrefab是默认的ballPrefab - > 3D Object - > Sphere,其中包含Box ColliderRigidbody (重力关闭,运动启动)和OVRGrabbable组件。

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. 因此,用户使用BY创建球,并且能够通过抓取索引触发器并放开来移动它们。 Then, say, A is pressed on the right hand controller when its near a ball to remove (and it does get destroyed). 然后,比如说,当A靠近一个球去除时, A被压在右侧控制器上(并且它会被摧毁)。 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. 左手索引触发器仍可用于移动任何对象,但只要右手控制器上的X用于删除对象,就不会像右手那样抓住其他对象。

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 SphereCastAll正在拿起手的SphereCastAll并将其删除,或者
  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. BALL标签添加到球预制件中,只有在SphereCastAll选择带有该标签的对象时才会销毁。
  • Check if BoxCollider and gameObject are not null before destroying the ball. 在销毁球之前检查BoxCollidergameObject是否为null
  • Pass a vector to RemoveBall instead of the hand's GameObject , then do SphereCastAll near that vector. 通过载体来RemoveBall ,而不是手的GameObject ,然后做SphereCastAll该矢量附近。

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. 我目前的解决方案是摧毁球的MeshRenderer并打开重力,使球MeshRenderer场景的底部。 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. 现在这很好,但是每个球都会添加更多的物体(可以期望它达到~10 000个物体),并且场景变得非常慢,所以我希望能够干净地摧毁球。 So my question is: 所以我的问题是:

How do I destroy a GameObject without destroying the hand that is destroying it? 如何在不破坏正在摧毁它的手GameObject情况下销毁GameObject

You have already tried it with tags but this might still work try to give your spherecast a layer: 您已经尝试过使用标签,但这可能仍然可以尝试为您的spherecast提供一个图层:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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