Уничтожение объектов Prefabs после Spawn с помощью столкновения - PullRequest
2 голосов
/ 18 марта 2019

В настоящее время у меня есть некоторые объекты, появляющиеся из префаба, и я пытаюсь уничтожить только один из порожденных элементов этого префаба.Я искал в Интернете, и я нашел тонны разных примеров, но я не смог заставить ни один из них работать.Я попытался создать экземпляр Instantiate и уничтожить его, но я не могу заставить его работать.Сценарий появления / столкновения прикрепляется к основной камере, если это имеет значение.Столкновение с другими предметами в моей игровой работе и сборном имеет коллайдер коробки, установленный на isTrigger.Опять же, я знаю, что есть множество примеров, объясняющих это и т. Д., Но я не могу заставить его работать, и, возможно, я не понимаю, что я на самом деле должен делать.

Код Spawner:

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 находится на основной камере.Используемый игрок является игроком первого лица, предоставляемым Unity.

Код для уничтожения порожденного объекта:

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

Код уничтожения находится на префабе.Обратите внимание, что префаб не находится в иерархии, как это должно быть.

Ответы [ 3 ]

3 голосов
/ 18 марта 2019

Во-первых,

Я вижу, что вы порождаете вещи в цикле 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);
    }
}

Наконец,

убедитесь, что обнаружение столкновений работает.Вы говорите, что скрипт прикреплен к вашей камере.пожалуйста, убедитесь, что у вас есть коллайдер на камеру.Но вы говорите, что другие коллайдеры работают, так что, я думаю, у вас все под контролем.

Я предполагаю, что ваша проблема заключается в некорректной логике, которую я первоначально описал.

1 голос
/ 18 марта 2019

OnTriggerEnter должен быть в сценарии, прикрепленном к объекту, с которым он сталкивается, или к самому флакону.Он не может быть на основной камере, так как OnTriggerEnter никогда не будет вызван.

0 голосов
/ 18 марта 2019

Я бы порекомендовал вам сохранить скрипты на одном задании, вы должны разбить этот скрипт на скрипт 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);
        }
    }
...