使用碰撞在生成后销毁预制对象

Destroying Prefabs Object After Spawn Using collision

我目前有一些从预制件中生成的对象,我正试图仅销毁该预制件中生成的一个项目。我在网上搜索,发现了很多不同的例子,但我无法让其中任何一个发挥作用。我尝试设置 Instantiate 的一个实例并销毁该实例,但我无法让它工作。如果重要的话,spawn/collision 脚本会附加到主摄像头。与我的游戏工作中的其他项目发生碰撞,并且预制件确实有一个设置为 isTrigger 的盒子碰撞器。再一次,我知道有很多例子可以解释这个等等,但我无法让它工作,也许我不明白我实际上应该做什么。

生成器代码:

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

public class bloodVialSpawner : MonoBehaviour
{
    public GameObject vialOfBlood;
    private GameObject vialss;
    private int hunger =10;
    public int numOfVials;
    public int minSpawnRange, maxSpawnRange;
    public int minSpawnRange2, maxSpawnRange2;
    // Start is called before the first frame update
    float timeSpawns = 2;
    List<GameObject> vialsInstantiated = new List<GameObject>();
    void Start()
    {
        StartCoroutine(becomeHungry());
        InvokeRepeating("SpawnVials", timeSpawns, timeSpawns);
    }
    private void Update()
    {
        if (hunger == -1)
        {
            Debug.Log("sigh");
        }
    }
    void SpawnVials()
    {
        for (int i = 0; i < numOfVials; i++)
        {
            vialsInstantiated.Add(Instantiate(vialOfBlood, SpawnPosition(), Quaternion.identity) as GameObject);
        }
    }
    Vector3 SpawnPosition()
    {
        int x, y, z;
        y = 59;
        x= UnityEngine.Random.Range(minSpawnRange, maxSpawnRange);
        z = UnityEngine.Random.Range(minSpawnRange2, maxSpawnRange2);
        return new Vector3(x, y, z);
    }

    IEnumerator becomeHungry()
    {
        while (true)
        {
            hunger -= 1;
            yield return new WaitForSeconds(1);
            Debug.Log(hunger);
        }
    }
}

Spawner 脚本在主摄像机上。使用的Player是Unity提供的First Person Player。

销毁生成对象的代码:

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

public class destroyVial : MonoBehaviour
{
    void OnTriggerEnter(Collider col)
    {
        if (col.gameObject.tag == "vials")
        {
            Destroy(col.gameObject);
            Debug.Log("yell");
        }
    }
}

销毁代码在预制件上。注意预制件不在层次结构中,因为它不应该在层次结构中。

OnTriggerEnter 需要在附加到与之碰撞的对象或小瓶本身的脚本上。它不能在主相机上,因为永远不会调用 OnTriggerEnter。

首先,

我看到你在 for 循环中生成东西并且每次都覆盖 vialss 变量:

for (int i = 0; i < numOfVials; i++)
{
   vialss = Instantiate(vialOfBlood, 
                        SpawnPosition(),
                        Quaternion.identity) as GameObject;
}

然后,在碰撞时,您正在摧毁 vialss,在本例中,这将是最新生成的对象。如果你在 1 次碰撞后与任何东西发生碰撞,vialss 将已经被删除并可能抛出异常。也许这在你的游戏中很好,但逻辑看起来有点缺陷。

另外,我假设你想摧毁你正在碰撞的物体?这样的东西行不通吗?

void OnTriggerEnter(Collider col)
{
    if (col.gameObject.tag == "vials")
    {
        Destroy(col.gameObject); // <== Remove colliding object
        Debug.Log("yell");
    }
}

如果您出于某些不相关的原因需要所有生成的小瓶的列表,也许您想将其转换为列表:

List<GameObject> spawnedVials = new List<GameObject>();

void SpawnVials()
{
    for (int i = 0; i < numOfVials; i++)
    {
        var vial = Instantiate<GameObject>(vialOfBlood,
                                         SpawnPosition(),
                                         Quaternion.identity)
        spawnedVials.Add(vial);
    }
}

最后,

确保碰撞检测正常工作。您是说脚本已附加到您的相机上。请确保您的相机上有对撞机。但是你是说其他对撞机正在工作,所以我猜你已经控制住了它。

我猜你的问题出在我最初描述的有缺陷的逻辑上。

我建议您将脚本保留为一项工作,您应该将该脚本拆分为 Spawn 脚本和 Collider 脚本。并创建一个空的 GameObject,其唯一目的是生成预制件。 您的代码中还有一些错误:

    void OnTriggerEnter(Collider col)
    {
        if (col.gameObject.tag == "vials")
        {
            Destroy(col.gameObject); // Destroy the gameObject you're colliding with
            Debug.Log("yell");
        }
    }

此外,变量 vialss 没有达到您的预期,vialss 仅引用最后一个实例化的小瓶,因此最好将所有小瓶保存在列表中:

    List<GameObject> vialsInstantiated = new List<GameObject>();

然后:

    void SpawnVials()
    {
        for (int i = 0; i < numOfVials; i++)
        {
            vialsInstantiated.Add(Instantiate(vialOfBlood, SpawnPosition(), Quaternion.identity) as GameObject);
        }
    }