【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);
            }
        }
    }
效果:

请添加图片描述

优点:

● 容易实现,只需要判断两点之间距离既可以。
● 轻量级更容易自定义,比如你可以对不同类型的敌人实行不同的检测范围,空中的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);
        }
    }
效果:

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

优点:

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

缺点:

● 需要碰撞器和刚体

辅助线检测

核心思路:

● 利用 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);
        }
    }
    
效果:

请添加图片描述

优点:

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

缺点:

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

  • 15
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity中,可以使用代码实现敌人在一定范围内随机巡逻的功能。具体步骤如下: 1. 在Unity中创建一个空对象,并将其命名为“Enemy”。在该对象上添加一个Capsule Collider组件,用于检测敌人与其他物体的碰撞。 2. 在“Enemy”对象上添加一个Rigidbody组件,用于实现敌人的物理运动。 3. 在“Enemy”对象上添加一个脚本组件,用于实现敌人的巡逻行为。在脚本中,可以通过以下代码实现敌人在一定范围内随机巡逻的功能: ```csharp using UnityEngine; using System.Collections; public class EnemyPatrol : MonoBehaviour { public float moveSpeed = 2f; // 敌人的移动速度 public float patrolRange = 10f; // 敌人的巡逻范围 private Vector3 minPos; // 巡逻范围的最小坐标 private Vector3 maxPos; // 巡逻范围的最大坐标 private Vector3 targetPos; // 当前巡逻的目标位置 void Start() { minPos = transform.position - new Vector3(patrolRange, 0, patrolRange); maxPos = transform.position + new Vector3(patrolRange, 0, patrolRange); targetPos = GetRandomPos(); } void Update() { transform.position = Vector3.MoveTowards(transform.position, targetPos, moveSpeed * Time.deltaTime); if (Vector3.Distance(transform.position, targetPos) < 0.1f) { targetPos = GetRandomPos(); } } Vector3 GetRandomPos() { float posX = Random.Range(minPos.x, maxPos.x); float posZ = Random.Range(minPos.z, maxPos.z); return new Vector3(posX, transform.position.y, posZ); } } ``` 在上述代码中,我们首先定义了敌人的移动速度和巡逻范围。然后在Start函数中,计算出巡逻范围的最小坐标和最大坐标,并将当前巡逻的目标位置设置为一个随机位置。在Update函数中,我们通过Vector3.MoveTowards函数来驱动敌人目标位置移动,直到到达目标位置。一旦到达目标位置后,我们再随机选取一个新的目标位置,并继续巡逻。 需要注意的是,上述代码中仅实现了敌人的巡逻行为,如果需要实现敌人向玩家追击的功能,可以通过在Update函数中添加额外的判断逻辑来实现。例如,可以通过检测敌人与玩家之间的距离,当距离小于一定值时,敌人就开始向玩家追击。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值