@Korsakovlev

Как сделать отслеживание врагов у игрока?

Вот две части скрипта и ошибка:
Код 1:
private List<GameObject> enemes = new List<GameObject>();

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Enemy")
        {
            enemes.Add(other.gameObject);
            transform.parent.gameObject.GetComponent<Player>().PlayerVision(enemes);
        }
    }

    public void OnTriggerExit2D(Collider2D other)
    {
        if (other.tag == "Enemy")
        {
            enemes.Remove(other.gameObject);
            if(enemes == null)
                transform.parent.gameObject.GetComponent<Player>().NoTarget();
            else if (enemes != null)
                transform.parent.gameObject.GetComponent<Player>().PlayerVision(enemes);
        }
    }
Код 2:
    private float Distance;
    private GameObject target;
    public void PlayerVision(List<GameObject> enemes)
    {
        target = enemes[0];
        Distance = Vector3.Distance(enemes[0].transform.position, transform.position);
        SeeEnemy = true;
        if (enemes.Count >= 2)
            for (int i = 1; i != enemes.Count; i++)
                if (Vector3.Distance(enemes[i].transform.position, transform.position) < Distance)
                {
                    Distance = Vector3.Distance(enemes[i].transform.position, transform.position);
                    target = enemes[i];
                }
    }
    public void NoTarget()
    {
        float movex = Input.GetAxis("Horizontal");
        SeeEnemy = false;
        if (movex > 0)
        {
            horizontalMove = false;
            Flip();
        }
        else if (movex < 0)
        {
            horizontalMove = true;
            Flip();
        }
    }

Ошибка:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <695d1cc93cca45069c528c15c9fdd749>:0)
Player.PlayerVision (System.Collections.Generic.List`1[T] enemes) (at Assets/Scripts/Live_Objects/Player.cs:178)
PlayerVision.OnTriggerExit2D (UnityEngine.Collider2D other) (at Assets/Scripts/Triggers/PlayerVision.cs:25)

Я не понимаю, почему он выдает ошибку, пустой список же ни с чем не взаимодействует, как я вижу, идет лишь проверка на пустой список. Суть еще в том, что игрок после встречи с врагом продолжает на него поворачиваться(фрагмент кода с поворотом в зависимости от переменной прикреплять не вижу смысла) и не переходит в нормальный режим(куда идет - туда и поворачивается), хотя до встречи все работает нормально, да и ошибка выдается здесь.
  • Вопрос задан
  • 57 просмотров
Решения вопроса 1
@romazhan
В функции `OnTriggerExit2D` вы пытаетесь удалить элемент из списка `enemes`, но сразу же обращаетесь к этому списку без проверки на пустоту. Следует добавить проверку на то, что список `eneme`s не пуст, перед обращением к элементам этого списка.

По поводу ошибки `ArgumentOutOfRangeException`: возникает она, когда вы пытаетесь обратиться к элементу списка по индексу, который выходит за пределы размера этого списка. Например, если у вас есть список из трех элементов, то допустимые индексы будут от 0 до 2. При обращении к элементу с индексом 3 будет возникать ошибка.

Чтобы исправить эту ошибку, нужно проверять, что список `enemes` не пуст и что индекс, по которому вы обращаетесь к элементу, находится в допустимом диапазоне. В функции `PlayerVision` нужно проверять, что список `enemes` не пуст перед тем, как обращаться к элементам этого списка. Например, так:
if (enemes.Count > 0) {
    target = enemes[0];
    Distance = Vector3.Distance(enemes[0].transform.position, transform.position);
    SeeEnemy = true;
    if (enemes.Count >= 2)
        for (int i = 1; i != enemes.Count; i++)
            if (Vector3.Distance(enemes[i].transform.position, transform.position) < Distance) {
                Distance = Vector3.Distance(enemes[i].transform.position, transform.position);
                target = enemes[i];
            }
}

В функции `OnTriggerExit2D` также стоит добавить проверку на то, что список `enemes` не пуст, перед обращением к элементам этого списка. Например, так:
if (other.tag == "Enemy")
{
    enemes.Remove(other.gameObject);
    if (enemes.Count == 0) {
        transform.parent.gameObject.GetComponent().NoTarget();
    } else {
        transform.parent.gameObject.GetComponent().PlayerVision(enemes);
    }
}

Проверьте также, что вы правильно указали тег "Enemy" у вражеских объектов, чтобы условие `if (other.tag == "Enemy")` выполнялось только при встрече с врагами.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы