unity 扇形范围检测目标

简介: 本文介绍了两种实现扇形范围检测的方法。第一种方法通过计算目标点与技能释放者之间的距离和夹角,判断目标是否在指定的扇形范围内。代码主要利用了`Vector3.Distance`和`Vector3.Dot`进行距离和角度的计算。第二种方法则使用摄像机射线检测,分为两个脚本:一个挂载在摄像机上,负责发射多条射线并检测碰撞对象;另一个挂载在目标物体上,处理被发现后的逻辑。摄像机脚本通过`Physics.Raycast`检测敌人或障碍物,并调用目标物体的响应函数。该方法适用于更复杂的场景,如视野检测和敌人发现机制。

两种方法实现
第一种
代码如下:

private float ScopeDistance = 2f;//扇形距离
    private float ScopeJiaodu = 120;//扇形的角度
    //传入目标点位置 判断在不在扇形范围内 
    private void ScopeIsAnimal(Vector3 vector)
    {       
        float distance = Vector3.Distance(transform.position, vector);//距离
        Vector3 norVec = transform.rotation * Vector3.forward * 5;//此处*5只是为了画线更清楚,可以不要
        Vector3 temVec = vector - transform.position;
        Debug.DrawLine(transform.position, norVec, Color.red);//画出技能释放者面对的方向向量
        float jiajiao = Mathf.Acos(Vector3.Dot(norVec.normalized, temVec.normalized)) * Mathf.Rad2Deg;//计算两个向量间的夹角
        if (distance < ScopeDistance)
        {
            if (jiajiao <= ScopeJiaodu * 0.5f)
            {

                Debug.Log("在扇形范围内");
            }
        }
    }

第二种:

需要两个脚本一个挂载摄像机一个挂载物体
摄像机脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraRay : MonoBehaviour
{
    private float viewRadius = 8.0f;      // 代表视野最远的距离
    private float viewAngleStep = 30;     // 射线数量,越大就越密集,效果更好但硬件耗费越大。
    void DrawFieldOfView()
    {
        // 获得最左边那条射线的向量,相对正前方,角度是-45
        Vector3 forward_left = Quaternion.Euler(0, -45, 0) * transform.forward * viewRadius;
        // 依次处理每一条射线
        for (int i = 0; i <= viewAngleStep; i++)
        {
            // 每条射线都在forward_left的基础上偏转一点,最后一个正好偏转90度到视线最右侧
            Vector3 v = Quaternion.Euler(0, (90.0f / viewAngleStep) * i, 0) * forward_left; ;

            // 创建射线
            Ray ray = new Ray(transform.position, v);
            RaycastHit hitt = new RaycastHit();
            // 射线只与两种层碰撞,注意名字和你添加的layer一致,其他层忽略
            int mask = LayerMask.GetMask("Obstacle", "Enemy");
            Physics.Raycast(ray, out hitt, viewRadius, mask);

            // Player位置加v,就是射线终点pos
            Vector3 pos = transform.position + v;
            if (hitt.transform != null)
            {
                // 如果碰撞到什么东西,射线终点就变为碰撞的点了
                pos = hitt.point;
            }
            // 从玩家位置到pos画线段,只会在编辑器里看到
            Debug.DrawLine(transform.position, pos, Color.red); ;

            // 如果真的碰撞到敌人,进一步处理
            if (hitt.transform != null && hitt.transform.gameObject.layer == LayerMask.NameToLayer("Enemy"))
            {
                OnEnemySpotted(hitt.transform.gameObject);
            }
        }
    }
    void OnEnemySpotted(GameObject enemy)
    {
        enemy.GetComponent<Enemy>().spottedFrame = Time.frameCount;
    }

    public Vector3 ColliderV3;
    // Update is called once per frame
    void Update()
    {
        DrawFieldOfView();

    }
}

物体脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    MeshRenderer meshRenderer;
    // 代表被发现时的帧数(这里用帧数代表时间)
    public int spottedFrame = -100;
    void Start()
    {
        meshRenderer = GetComponent<MeshRenderer>();
    }
    void Update()
    {
        // 通过设置 spottedFrame,就可以实现隐藏或显现
        if (spottedFrame >= Time.frameCount - 10)
        {
            meshRenderer.enabled = true;
        }
        else
        {
            meshRenderer.enabled = false;
        }
    }
}

最后加上层级测试一下即可

相关文章
|
Linux
【PyAutoGUI操作指南】05 屏幕截图与图像定位:截图+定位单个目标+定位全部目标+灰度匹配+像素匹配+获取屏幕截图中像素的RGB颜色
【PyAutoGUI操作指南】05 屏幕截图与图像定位:截图+定位单个目标+定位全部目标+灰度匹配+像素匹配+获取屏幕截图中像素的RGB颜色
1178 0
|
定位技术 C# Windows
C#编程学习(05):使用webbroswer控件显示地图并标注点位坐标
C#编程学习(05):使用webbroswer控件显示地图并标注点位坐标
|
编解码 前端开发 PHP
悬浮坐标解决方案:如何在图片获取xy鼠标位置和增加标注信息
悬浮坐标解决方案:如何在图片获取xy鼠标位置和增加标注信息
195 0
|
数据可视化 算法 安全
自动检测图像中的圆形目标并可视化检测到的圆
说明如何自动检测图像中的圆或圆形目标并可视化检测到的圆。
218 0
使用边界跟踪方法标识图像中的圆形目标
使用边界跟踪方法,根据对象的圆度对其进行分类。
106 0
|
编译器 API 图形学
【unity细节】基于unity子对象(如相机)为什么无法进行z轴的拖拽移动和z轴自动归位的问题
【unity细节】基于unity子对象(如相机)为什么无法进行z轴的拖拽移动和z轴自动归位的问题
171 0
|
数据可视化 vr&ar C#
Unity学习3,如何显示与隐藏平面检测
首先搭建好基本环境,在AR Session Origin下添加一个AR Plane Manager对象,并添加一个预制体AR Default Plane到AR Plane Manager对象的Plane Prefab属性下(这一部分在Unity配置Android开发环境下有介绍不再记录)Unity配置Android开发环境与第一个Demo
314 0
Unity学习3,如何显示与隐藏平面检测