Spawn System в Unity, Уничтожая Spwans - PullRequest
0 голосов
/ 23 июня 2018

Я создаю систему вызова для своей игры, которая порождает врагов в случайных позициях, но Unity говорит мне, что я не проверяю, уничтожен ли уже объект. Я пытался решить это с некоторыми другими темами здесь, но я не мог сделать это. Вот мой код:

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

public class EnemySpawn : MonoBehaviour {

    public GameObject Enemy2Spawn;
    public float maxWidth;
    public float minWidth;
    public float rateSpwan;
    private float currentRSpawn = 2.0f;
    public int maxInimigo;
    public int Inimigos = 0;

    void Start()
    {
        transform.position = new Vector3(0, 6.03f, 0);
    }

    // Update is called once per frame
    void Update()
    {
        if (currentRSpawn > Time.time & Inimigos<=maxInimigo)
        {
            transform.position = new Vector3(Random.Range(minWidth, maxWidth), transform.position.y, transform.position.z);
            Instantiate(Enemy2Spawn);
            currentRSpawn = currentRSpawn + rateSpwan;
            Inimigos++;
        }

        if (Enemy2Spawn. == null)
        {
            Destroy(this.gameObject);
        }
    }
}

Я получаю ошибку:

"Объект типа 'GameObject' уже уничтожен, но вы все еще пытаетесь получить к нему доступ. Ваш сценарий должен либо проверить, является ли он нулевым, либо вы не должны уничтожать объект"

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

В функции Update вы проверяете, является ли GameObject нулевым, что означает, что он не существует, тогда вы используете Destroy() для уничтожения того объекта, который не существует ,Вместо этого вы захотите проверить, существует ли объект в операторе if, который порождает врагов.Добавьте это к выражению if, вот так, и все будет хорошо.

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

public class EnemySpawn : MonoBehaviour {

    public GameObject Enemy2Spawn;
    public float maxWidth;
    public float minWidth;
    public float rateSpwan;
    private float currentRSpawn = 2.0f;
    public int maxInimigo;
    public int Inimigos = 0;

    void Start()
    {
        transform.position = new Vector3(0, 6.03f, 0);
    }

    // Update is called once per frame
    void Update()
    {
        if (currentRSpawn > Time.time && Inimigos <= maxInimigo && Enemy2Spawn == null)
        {
            transform.position = new Vector3(Random.Range(minWidth, maxWidth), transform.position.y, transform.position.z);
            Instantiate(Enemy2Spawn);
            currentRSpawn = currentRSpawn + rateSpwan;
            Inimigos++;
        }
    }
}
0 голосов
/ 24 июня 2018

Что ж, в этом сценарии есть несколько вещей:

до этого : для ошибки, если вы установите Enemy2Spawn для объекта на сцене, и он будет уничтожен, тогда значение будет нулевым, тогда, когда он снова попытается создать экземпляр, что приводит к ошибке (может поставьте условие "Enemy2Spawn != null" в первом операторе if как исправление)

"transform.position = new Vector3(Random.Range(minWidth, maxWidth), transform.position.y, transform.position.z);" Эта строка изменяет объект, прикрепленный к сценарию, его точная позиция, которая не повлияет на позицию врага, которого вы собираетесь вызвать.

"Instantiate (Enemy2Spawn);" делает клон значения переменной. Клон наследует все значения оригинала, поэтому позиция будет соответствовать позиции оригинала.

Если вы не установили значение "Enemy2Spawn", оно не станет нулевым, если только другой скрипт не изменит значение и не станет префабом. Таким образом, «if (Enemy2Spawn == null)» при условии, что значение установлено, больше не изменяется, где и задается в качестве префаба, в этом случае утверждение никогда не будет истинным. Если утверждение когда-либо стало истинным, строка внутри "Destroy(this.gameObject);" уничтожает объект, к которому прикреплен скрипт, поэтому мне кажется это контрпродуктивным (уничтожить спавнер), но если это является мерой предотвращения ошибки, она должна быть в начале или активировать функцию, или если установить его с помощью другого сценария, просто уничтожьте сценарий, вместо того, чтобы установить для переменной значение null (в чем я действительно сомневаюсь).

Вот измененный скрипт, который должен исправить указанные мной проблемы и удовлетворить ваши потребности

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

public class EnemySpawn : MonoBehaviour {

    public GameObject Enemy2Spawn;
    public float maxWidth;
    public float minWidth;
    public float rateSpwan;
    private float currentRSpawn = 2.0f;
    public int maxInimigo;
    public int Inimigos = 0;

    void Start()
    {
        transform.position = new Vector3(0, 6.03f, 0);
    }

    // Update is called once per frame
    void Update()
    {
        if (currentRSpawn > Time.time & Inimigos<=maxInimigo)
        {
            Instantiate(Enemy2Spawn, new Vector3(Random.Range(minWidth, maxWidth), transform.position.y, transform.position.z), Quaternion.identity);
            currentRSpawn = currentRSpawn + rateSpwan;
            Inimigos++;
        }
    }
}

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

Кроме того, API сценариев предлагает вызвать Destroy, как показано ниже, если используется JS / unityscript

* +1025 * UnityEngine.Object.Destroy (this.gameObject);

Надеюсь, это поможет, если нет, то потребуется больше информации

...