首页 > 解决方案 > Destroying Prefabs Object After Spawn Using collision

问题描述

I currently have some objects spawning from a prefab and am attempting to destroy only one of the spawned items of that prefab. I was searching online and I found tons of different examples but I have been unable to get any of them to work. I tried setting up an instance of the Instantiate and destroying that instance but I am unable to get it to work. The spawn/collision script is attached to the main camera if that matters. Collision with other items in my game work and the prefab does have a box collider set to isTrigger. Again, I know there are plenty of examples explaining this etc, but I can't get it to work and maybe I am not understanding what I actually should be doing.

Spawner code:

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

enter image description here

Spawner Script is on the Main Camera. Player used is the First Person Player Unity provides.

Code for destroying spawned object:

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

enter image description here

Destroy code is on prefab. Note prefab is not in hierarchy as it should not be.

标签: unity3dobjectinstantiationobject-destruction

解决方案


Firstly,

I see that you're spawning things in a for-loop and overwriting the vialss variable every time:

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

And then, on collision, you're Destroying vialss, which in this case will be the latest spawned object. And if you collide with anything after 1 collision, vialss will already be deleted and probably throw an exception. Maybe that's fine in your game, but the logic looks a bit flawed.

Also, I'm assuming you want to destroy the object you're colliding with? Does something like this not work?

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

If you, for some unrelated reason, need a list of all your spawned vials, maybe you'd like to convert that to a list instead:

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

Finally,

make sure that the collision detection is working. You're saying that the script is attached to your camera. please make sure you have a Collider on the camera. But you're saying that other colliders are working, so I'm guessing you have this under control.

I'd guess your issue lies in the flawed logic I initially described.


推荐阅读