Как заставить врага остановиться и начать движение в игре Tower Defense?

#c# #unity3d #triggers #tags #boolean

#c# #unity3d #триггеры #Теги #логическое

Вопрос:

Я создаю игру Tower Defense (следуя учебным пособиям Brackeys), и я хочу сделать так, чтобы, когда враги натыкались на препятствие или на вражеский фронт, они останавливались. Когда препятствие или вражеский фронт уничтожены, я хочу, чтобы они снова двигались вперед.

Я использую транспорт на основе узлов для этих врагов из руководства Brackeys. До сих пор это было очень полезно, и я нахожусь в точке, где я хочу добавить дополнительные вещи в игру.

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

Вот весь код перемещения врага:

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

[RequireComponent(typeof(Enemy))]
public class EnemyMovement : MonoBehaviour
{
    private Transform target;
    private int wavepointIndex = 0;

    EnemyTurret eTurret;

    private Enemy enemy;

    public bool canMove = true;


    //private CapsuleCollider _cc;
    

    private void Start()
    {
        enemy = GetComponent<Enemy>();

        target = WaypointScript.points[0];
    }

    private void OnTriggerEnter(Collider col)
    {
        if (col.CompareTag("Obstacle") || col.CompareTag("Enemy"))
        {
            canMove = false;

            Debug.Log("Stop");
        }
    }

    private void OnTriggerStay(Collider col)
    {
        if (col.CompareTag("Obstacle") || col.CompareTag("Enemy"))
        {
            if (col.GetComponent<Enemy>().health <= 0)
            {
                Movement();
                Debug.Log("Start Moving!");
            }            
        }
    }

    void Movement()
    {
        canMove = true;
    }

    private void Update()
    {
        if (canMove == true)
        {
            Vector3 dir = target.position - transform.position;
            transform.Translate(dir.normalized * enemy.speed * Time.deltaTime, Space.World);

            if (Vector3.Distance(transform.position, target.position) <= 0.4f)
            {
                GetNextWayPoint();
            }

            enemy.speed = enemy.startSpeed;
        }        
    }

    void GetNextWayPoint() //Sets the new waypoint to the enemy, however when it finishes it's cycle of waypoints, the enemy is destroyed.
    {
        if (wavepointIndex >= WaypointScript.points.Length - 1)
        {
            EndPath();
            return;
        }

        wavepointIndex  ;
        target = WaypointScript.points[wavepointIndex];
    }

    void EndPath()
    {
        canMove = false;

        //PlayerStats.Health--;
        //Destroy(gameObject);
    } ```
  

Комментарии:

1. может ли быть так, что вы уничтожаете вражеский коллайдер, как только здоровье врагов достигает 0, и поэтому код во втором условном операторе в OnTriggerStay не выполняется?

2. @Sam как отключить его? чтобы он мог остановиться в другой раз, может быть, с небольшой задержкой, чтобы между врагами снова был разрыв?

3. Скорее всего, вы уничтожаете врага, у которого было 0 здоровья, прежде чем текущий успеет снова начать движение. Однако код не завершен, все еще отсутствует некоторый код врага и препятствия. Что происходит с врагом, когда его здоровье достигает 0?

4. но да, вы можете попробовать это. Извините, я думал, вы не поняли мой вопрос

5. Быстрым решением было бы добавить короткую задержку перед уничтожением врага. docs.unity3d.com/ScriptReference/Object . Destroy.html здесь вы можете видеть, что вы можете добавить задержку в сам метод уничтожения.

Ответ №1:

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

Может ли быть так, что вы уничтожаете вражеский коллайдер, как только здоровье врагов достигает 0, и поэтому код во втором условном операторе в OnTriggerStay не выполняется?

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

Комментарии:

1. Что ж, в таком случае вам действительно нужно предоставить больше информации в своем вопросе. Добавьте весь код, необходимый для формирования полной картины, и тогда кто-нибудь сможет помочь

Ответ №2:

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

Вы также можете попробовать использовать OnTriggerExit() следующим образом:

 private void OnTriggerExit(Collider col)
    {
        if (col.CompareTag("Obstacle") || col.CompareTag("Enemy"))
        {
            Movement();
            Debug.Log("Start Moving!");           
        }
    }
  

Комментарии:

1. Я не уверен, что вы имеете в виду над кодом. Я также попробовал код, и он, к сожалению, не сработал.

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