敌人AI 在特定距离停止敌人

你好,我试图让敌人在玩家面前停止,使用 if(Vector2.Distance(transform.position, player.position) > minDistance)

但这并没有按我预期的那样工作。敌人应该在一定范围内开始跟随玩家,然后在他面前停止。这在使用 if(Vector2.Distance(transform.position, player.position) <= range) 时运行良好

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Enemy : MonoBehaviour{    public int Health;    public Transform player;    public float range;    public float speed;    public Animator anim;    public Transform goblinRange;    public float attackRangeGoblin;    public LayerMask whatIsPlayer;    public int damage;    private float timeBtwAttack;    public float startTimeBtwAttack;    // Update is called once per frame    void Update()    {        if (Vector2.Distance(transform.position, player.position) <= range)                  {            anim.SetBool("GWalking", true);            transform.position = Vector2.MoveTowards(transform.position, player.position, speed *   Time.deltaTime);            Collider2D[] playerToDamage = Physics2D.OverlapCircleAll(goblinRange.position,   attackRangeGoblin, whatIsPlayer);            for (int i = 0; i < playerToDamage.Length; i++)            {                playerToDamage[i].GetComponent<PlayerMovement>().TakeDamage(damage);                           }         }        else        {            Idle();        }     }     private void FixedUpdate()    {        if (Health <= 0)        {            Destroy(gameObject);        }    }    private void Idle()    {        anim.SetBool("GWalking", false);            }    public void TakeDamage(int Damage)    {        Health -= Damage;        Debug.Log("Damage Taken");    }    private void OnDrawGizmosSelected()    {        Gizmos.color = Color.red;        Gizmos.DrawWireSphere(goblinRange.position, attackRangeGoblin);    }    private void Attack()    {        anim.SetTrigger("goblinAttack");            }     }

所以我需要敌人在玩家面前停止并开始攻击动画,但我不知道如何在不删除 “<= range” 的情况下将 if(Vector2.Distance(transform.position, player.position) > minDistance) 实现到我的代码中。任何帮助都将不胜感激。


回答:

rangeminDistance 的检查并不是互斥的(“一个或另一个”)。它们可以同时存在并共存:

//避免冗余,少写一些代码,并使其更易读var distance = Vector2.Distance(transform.position, player.position);//如果在范围内..if (distance <= range) {    //如果不在最小距离内..    if(!(distance <= minDistance)) {        //移动    }    //如果在最小距离内(包括移动后,上面)..    if (distance <= minDistance) {        //攻击    }}//如果不在范围内..else {    //空闲}

代码中还有其他几个问题:

  1. 你应该遵循命名约定:

    • 如果你的变量和参数将使用驼峰命名法,那么 Health 应该改为 healthGWalking 应该改为 gWalkingDamage 应该改为 damage
  2. 名称应该具有描述性:

    为了节省几个字符的输入而牺牲你或其他人(例如我们)解读代码的难度是不值得的。

    • 避免歧义。anim 可以指的是 animatoranimation。使用 animator 更合适。
    • 避免使用缩写。在 GWalking 中,G 代表什么?— Goblin。我知道。问题是:我通过推断其他代码得知的;不是通过名称本身。使用 goblinWalking 更合适。
    • 避免使用类似缩写的简写,如 Btw 代替 Between。它们不好,原因与 ‘G’ 相同。
  3. 保持一致性:

    • 对相似的东西使用相同的命名结构。决定一个方案,并遵循它。不要在一个地方使用 GWalking,在另一个地方使用 goblinAttack。如果 “subjectAction” 是结构,使用 goblinWalkinggoblinAttack 等。
    • 在名称中使用相同的结构顺序。如果你的主题将放在开头,如 goblinRange,那么不要在其他地方放在末尾,如 attackRangeGoblin。使用 goblinAttackRange 更合适。
    • 如果类是 “Enemy”,那么 “Goblin” 相关的东西不应该出现在这里。所有哥布林 可能 是敌人,但并非所有敌人都是哥布林。你的类可能是所有敌人的通用类,或者是哥布林的特定类;不能两者兼有。将其命名为 Goblin;或者从其元素中移除 “goblin” 相关的东西。
  4. 为变量命名它们是什么,而不是它们做什么:

    • whatIsPlayer 改为 playerLayerMask
  5. 在命名时要有资源性(即:“描述性并不意味着冗长!”):

    • timeBtwAttacks 改为 attackInterval
  6. 尝试将相关的东西分组。

修复后,它应该看起来像这样:

//外部(?)依赖public Transform player;public LayerMask playerLayerMask; //来自:whatIsPlayer//内部依赖public Animator animator; //来自:anim//设置public int health; //来自:Healthpublic float range;public float speed;public int damage;public float attackInterval; //来自:timeBtwAttack//哥布林相关的东西(可能多余/不必要)public Transform goblin; //来自:goblinRangepublic float goblinAttackRange; //来自:attackRangeGoblin//在答案中使用,从问题中推断public float minDistance; //可能是 'goblinAttackRange' 的意思。

其他修复:

  • FixedUpdate 用于物理相关的东西。if (health <= 0) { Destroy(gameObject); } 应该在 Update 中(加上 return),如果要遵循当前结构。如果不是,那么它应该对健康变化做出反应,因此应该在 TakeDamage 中。
  • 在代码中保持一致性。不要在一个地方使用 anim.SetBool("GWalking", true),然后在另一个地方使用 Idle()。两者都应该是方法(Idle() Walk()),或者两者都应该是 SetBool 调用。
  • Transform goblin 是一个单独的变换吗?如果不是,只需像在 Vector2.Distance 中那样使用 transform 即可。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注