【问题标题】:How to make an enemy stop and start movement in a tower defence game?如何在塔防游戏中让敌人停止并开始移动?
【发布时间】:2020-11-16 17:44:09
【问题描述】:

我正在制作一款塔防游戏(根据 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);
    } ```

【问题讨论】:

  • 会不会是你在敌人生命值降到0时摧毁了对撞机,所以OnTriggerStay中第二个条件语句的代码没有被执行?
  • @Sam 禁用它?这样它就可以再次停下来,也许会有一点延迟,以便敌人之间再次出现间隙?
  • 你很可能在当前敌人有时间再次开始移动之前摧毁了生命值为 0 的敌人。虽然代码不完整,但仍然缺少一些敌人和障碍物代码。当敌人的生命值为 0 时会发生什么?
  • 但是,你可以试试。对不起,我以为你不明白我的问题
  • 一个快速的解决方法是在敌人被摧毁之前添加一个短暂的延迟。 docs.unity3d.com/ScriptReference/Object.Destroy.html这里可以看到可以在destroy方法本身添加延迟。

标签: c# unity3d triggers tags boolean


【解决方案1】:

我只是将我的 cmets 转换为答案,如果你解决了你的问题,你可以接受它。

会不会是你在敌人生命值达到 0 时摧毁了对撞机,所以 OnTriggerStay 中的第二个条件语句中的代码没有被执行?

一个快速的解决方法是在敌人被摧毁之前添加一个短暂的延迟。 Here 可以看到可以在destroy方法本身添加延迟。

【讨论】:

  • 那么在这种情况下,您确实必须在您的问题中提供更多信息。添加所有必要的代码以形成完整的图片,然后有人可以提供帮助
【解决方案2】:

敌人或障碍物可能在 OnTriggerStay() 函数检查其健康状况之前被摧毁。您可以尝试将敌人或障碍物存储在 GameObject 对象中,然后在 Update() 中启用移动,当对象因为它被破坏而返回 null 时。

您也可以像这样尝试使用 OnTriggerExit()

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

【讨论】:

  • 我不确定您在代码上方的意思。我也尝试了代码,不幸的是它没有工作。
  • 刚刚检查了上面的文字,因为我是个白痴,但这不起作用。我认为因为对撞机位于敌人的中心,每个敌人都会进入两个对撞机(infron 和 behind)。
猜你喜欢
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多