• 【Unity】找到目标的三种方式(范围内检测敌人)


    在游戏项目中,经常需要检测物体是否进入范围。这篇文章就来分享一下我了解到和用到的三种方式的实现以及他们的优缺点。

    案例场景

    英雄检测进入攻击范围的敌人。

    代码地址

    仓库地址

    Unity 实现检测范围内目标的三种方式

    距离检测

    核心思路:

    ● 检测敌人与英雄两点之间的距离,如果距离低于攻击范围,则认为进入攻击范围。

    代码实现:
        /*距离*/
        public int range = 2;
    
        /*检测到的对象*/
        private List<GameObject> detect ;
        
        void Update()
        {
            detect = new List<GameObject>();
            var monsterList = CreateMonster.Instance.MonsterList;
            foreach (var monster in monsterList)
            {
                if (Vector2.Distance(gameObject.transform.position,monster.transform.position)< range)
                {
                    detect.Add(monster);
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    效果:

    请添加图片描述

    优点:

    ● 容易实现,只需要判断两点之间距离既可以。
    ● 轻量级更容易自定义,比如你可以对不同类型的敌人实行不同的检测范围,空中的5格,陆地的7格等。
    ● 不依赖物理引擎,更简单完成功能。

    注意点:

    ● 因为要遍历判断与敌人的距离,如果敌人太多,每次遍历会消耗太多时间。
    ● 计算距离不应该每一帧都执行,需要配合定时器,每段时间计算一次即可。
    ● 距离没有可视化,需要自己实现

    碰撞器检测

    核心思路:

    ● 利用刚体和碰撞器的检测事件,检测进入范围的敌人。

    代码实现:
     /*检测到的对象*/
        private List<GameObject> detect = new List<GameObject>();
        
        private void OnTriggerEnter2D(Collider2D col)
        {
            if (col.CompareTag("Monster"))
            {
                detect.Add(col.gameObject);
            }
        }
    
        private void OnTriggerExit2D(Collider2D other)
        {
            if (other.CompareTag("Monster"))
            {
                detect.Remove(other.gameObject);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    效果:

    在这里插入图片描述在这里插入图片描述
    请添加图片描述

    优点:

    ● 容易实现,只需要使用引擎的碰撞器和刚体。
    ● 交互友好,可以直观看到检测范围,有利于调整范围。
    ● 基于事件触发,并不是每帧都检测,效率更高。

    缺点:

    ● 需要碰撞器和刚体

    辅助线检测

    核心思路:

    ● 利用 xxx 划出检测范围。
    ● 检测进入范围的对象,通过图层过滤筛选出敌人。

    代码实现:
     /*检测范围*/
        public int range = 2;
    
        [Header("检测图层")]
        [SerializeField]
        public LayerMask layerMask;
    
        /*检测到的对象*/
        private List<GameObject> detect ;
        
        void Update()
        {
            detect = new List<GameObject>();
            var objColliders = Physics2D.OverlapCircleAll(transform.position,range,layerMask);
            foreach (var monster in objColliders)
            {
                    detect.Add(monster.gameObject);
            }
        }
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    效果:

    请添加图片描述

    优点:

    ● 利用引起检测进入范围内的敌人,免了主动计算敌人距离的工作。

    缺点:

    ● 检测敌人不应该每一帧都执行,需要配合定时器,每段时间计算一次即可。
    ● 距离没有可视化,需要自己实现

  • 相关阅读:
    虚拟化+Docker基本管理
    java毕业设计我爱短视频管理系统mybatis+源码+调试部署+系统+数据库+lw
    Android 顶部标签栏及内容列表的设计与实现
    【OpenCV】车辆识别 目标检测 级联分类器 C++ 案例实现
    &4 express框架
    Swift 是 C++ 的最佳继任者
    在 Linux 程序中使用 breakpad
    Java核心编程(18)
    【OJ比赛日历】快周末了,不来一场比赛吗? #11.11-11.17 #12场
    python+vue+elementui固定资产管理系统django mysql
  • 原文地址:https://blog.csdn.net/GG_and_DD/article/details/126614461