个人技术总结——Unity2D简单敌人AI实现

222000311潘昕 学生 2023-06-07 22:52:37

目录

  • 技术概述
  • 技术详述
  • 范围内随机漫游/巡逻
  • 视野内追击玩家
  • 发起攻击
  • 使用中遇到的问题
  • 总结
  • 参考文献

技术概述

unity2D中实现简单的敌人AI,包括范围内自动巡逻/随机漫游、追击玩家、发动攻击

技术详述

范围内随机漫游/巡逻

以Bat为例,作为横板视角游戏的飞行单位,它的活动范围是一个面,所以同样可以应用于俯视视角游戏中。

首先为角色对象(EnemyBat)挂上Box Collider 2D(勾选isTrigger)和脚本,为了实现随机漫游,我们需要三个坐标:MovePos(代表bat,位置随便放)、LeftDownPosRightUpPosLeftDownPosRightUpPos分别定义了移动范围的左下角和右上角。

img

下面这段代码位于update中,首先让bat朝着movePos的位置移动,接着判断bat与movePos的距离,当二者重合时,bat会在原地等待waitTime秒的时间,时间到了之后,重新随机设置movePos位置(实现在后文),重置waitTime。这样bat就朝着下一个位置移动,如此反复

transform.position = Vector2.MoveTowards(transform.position, movePos.position, speed * Time.deltaTime);
            if (Vector2.Distance(transform.position, movePos.position) < 0.1f)
            {
                if (waitTime <= 0)
                {
                    movePos.position = GetRandomPos();
                    waitTime = startWaitTime;
                }
                else
                {
                    waitTime -= Time.deltaTime;
                }
            }

在指定范围内随机设置movePos位置

 Vector2 GetRandomPos()
    {
        Vector2 rndPos = new Vector2(Random.Range(leftDownPos.position.x, rightUpPos.position.x),
            Random.Range(leftDownPos.position.y, rightUpPos.position.y));
        return rndPos;
    }

对于横板视角游戏的地面单位,他们活动一般是左右往复巡逻,同样可以用两个pos划出范围,然后在到边界时实现转身即可

这段代码位于update,moveSpots[]存放着左右两个Pos,当达到某一Pos时,判断是左右边界,翻转角色。此处我为了省事直接用下标判断,0是右1是左。

 transform.position = 
            Vector2.MoveTowards(transform.position, moveSpots[i].position, speed * Time.deltaTime);

        if (Vector2.Distance(transform.position, moveSpots[i].position) < 0.1f)
        {
            if (waitTime <= 0)
            {
                if (i == 0)
                {
                    transform.eulerAngles = new Vector3(0, -180, 0);
                    i = 1;
                }
                else
                {
                    transform.eulerAngles = new Vector3(0, 0, 0);
                    i = 0;
                }

                waitTime = wait;
            }
            else
            {
                waitTime -= Time.deltaTime;
            }

视野内追击玩家

在游戏对象下添加一个子对象sight,包含一个盒型触发器,也就是图中外围的绿框。当玩家进入绿框时,开启追击

img

在sight上挂着一个脚本,用于检测触发器的触发,通过修改参数通知父对象脚本更改行为模式

void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.CompareTag("Player") && other.GetType().ToString() == "UnityEngine.CapsuleCollider2D")
        {
            EnemyBat.isInField = true;
        }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.CompareTag("Player") && other.GetType().ToString() == "UnityEngine.CapsuleCollider2D")
        {
            EnemyBat.isInField = false;
        }
    }

同样EnemyBat上挂载的脚本,在update中要做相应的判断

 if(!isInField)
        {
     //随机漫游
            transform.position = Vector2.MoveTowards(transform.position, movePos.position, speed * Time.deltaTime);

            if (Vector2.Distance(transform.position, movePos.position) < 0.1f)
            {
                if (waitTime <= 0)
                {
                    movePos.position = GetRandomPos();
                    waitTime = startWaitTime;
                }
                else
                {
                    waitTime -= Time.deltaTime;
                }
            }
        }
        else
        {
            //追击玩家
            transform.position = Vector2.MoveTowards(transform.position,
                                                       playerTransform.position,
                                                       speed * Time.deltaTime);
        }

发起攻击

上述敌人的攻击方式是自身与玩家接触,而有些敌人是通过武器或是技能攻击玩家。这时就需要在合适的时机调用这些攻击相关函数,我此处用了一个触发器判断,实现类似sight,触发时即发动攻击。

使用中遇到的问题
  • 老是打不到人

    这个绿色方框就是攻击触发范围,是略小于攻击范围的,这样可提高击中目标的概率(否则刚到攻击范围就挥刀,攻击前摇时间够玩家拉开距离了)

img

  • 碰到攻击范围就扣血,还是两倍

    这种实现方法要求父节点(也就是角色对应的gameobject)没有挂载Rigidbody 2D,否则碰到子物体(攻击范围)将分别触发父、子节点的OnTriggerEnter方法。否则结果就是:玩家碰到攻击范围的框,受到了触碰怪物身体的两倍伤害。

img

这个问题涉及的知识点非常细,印象深刻

总结

在这次的项目过程中,除了基本的场景搭建,我还学到了比如制作粒子特效,伤害浮动显示,实现玩家武器,攻击判定等等,敌人AI这部份相对来说比较有意思,就拿出来讲了
以上仅仅实现了敌人的简单AI,主要为读者提供一个实现思路,还需要自行扩展

参考文献

Unity 手册

...全文
634 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

686

社区成员

发帖
与我相关
我的任务
社区描述
2023年福州大学软件工程实践课程W班的教学社区
软件工程团队开发软件构建 高校 福建省·福州市
社区管理员
  • FZU_SE_teacherW
  • aboutazhang
  • 郭渊伟
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧