[Godot] 通过AABB包围盒和射线法检测碰撞
前言最近需要做鼠标选择单位的功能所以给大家分享一下我是如何实现的简单来说是在鼠标点击后通过我写的获取单位点集的方法先通过AABB包围盒进行粗筛然后再通过射线法进行精确判定最后根据Y轴的大小得到选中的单位下面我给大家分享一下我的实现逻辑效果展示代码实现鼠标点击这里本来没有什么好说的但是给大家分享一个普遍可能会遇到的问题就是鼠标点击UI因为比如我直接用的Input.IsActionJustPressed()方法做点击这回导致当我们点击UI的时候也会去做点击单位解决办法如下://当点击UI时直接返回if(gameManager.GetViewport().GuiGetHoveredControl()!null){return;}这样我们只需要注意把不会遮挡的UI比如占满全屏的Control节点的的Mouse-Filter设置为Ignore就好AABB包围盒介绍AABB(Axis-Aligned Bounding Box)的全称是轴对齐包围盒。简单来说,就是找一个最小的矩形,能把你的多边形完全框住,我们先用他进行粗筛否则如果每次都要对所有单位做精确的多边形判定,CPU会直接原地爆炸包围盒计算首先注意我们要提前设置好单位的点集因为之后的射线法判断所以需要按顺序设置这里我用的是List存的点集用Rect2存的AABB包围盒接下来我们需要计算包围盒注意计算好的包围盒需要跟着单位作为常量publicRect2CalulateAABB(ListpointSet){floatminXpointSet[0].X;floatmaxXpointSet[0].X;floatminYpointSet[0].Y;floatmaxYpointSet[0].Y;for(inti0;ipointSet.Count;i){Vector2ppointSet[i];if(p.XminX)minXp.X;elseif(p.XmaxX)maxXp.X;if(p.YminY)minYp.Y;elseif(p.YmaxY)maxYp.Y;}returnnewRect2(newVector2(minX,minY),newVector2(maxX-minX,maxY-minY));}这里的逻辑就是:不断更新四个边界值,最后用左下角坐标和宽高构造出矩形因为我们是用的Rect2所以注意用的两个点分别是position和size使用AABB进行粗筛// 先通过AABB包围盒粗筛foreach(varunitinunitPointSet){if(unit.AABB.HasPoint(mousePos-unit.nowPos)){// 通过射线法判断是否在多边形内if(IsPointInPolygon(mousePos-unit.nowPos,unit.pointSet))tmpUnit.Add(unit);}}这里有个细节:mousePos - unit.nowPos是把鼠标坐标转换到单位的局部坐标系。因为我们存储的点集都是相对于单位中心(0,0)的,所以需要先做这个转换射线法精确判定通过了AABB粗筛之后,就要进入真正的重头戏了:判断点是否在多边形内部射线法的核心思想想象你站在某个位置,往右边射出一根无限长的射线。这根射线会和多边形的边界相交。如果交点数量是奇数,说明你在多边形内部;如果是偶数(包括0),说明你在外部我们可以把它想象成翻墙的过程:你在外面,翻过1道墙,就进去了(奇数)再翻1道墙,就出来了(偶数)再翻1道墙,又进去了(奇数)所以,统计撞击次数的奇偶性,就能判断最终位置是在内还是外代码实现//射线法连接点(顺序)判断碰撞为奇数在多边形内privateboolIsPointInPolygon(Vector2mouse,ListpointSet){boolinsidefalse;for(inti0,jpointSet.Count-1;ipointSet.Count;ji){if((pointSet[i].Ymouse.Y)!(pointSet[j].Ymouse.Y)mouse.X(pointSet[j].X-pointSet[i].X)*(mouse.Y-pointSet[i].Y)/(pointSet[j].Y-pointSet[i].Y)pointSet[i].X)inside!inside;}returninside;}这段代码非常精简,接下来我给大家拆开讲解一下1) 双指针首先看循环头部:for (int i 0, j pointSet.Count - 1; i pointSet.Count; j i)这里为什么要用两个指针,而不是直接用(i 1) % pointSet.Count?原因如下:性能考虑: 模除运算在底层涉及除法,比简单的赋值和自增要慢。在需要对成百上千个单位进行实时判定的游戏中,这种细微差别会累积成可观的性能开销逻辑清晰:j i这种指针尾随的写法是图形学算法的标准写法,一开始就处理封口边,循环体内部非常纯净2) 坐标计算高度判断(pointSet[i].Ymouse.Y)!(pointSet[j].Ymouse.Y)这一行是在判断:这条边的两个端点,一个在鼠标上方,一个在鼠标下方如果两个点都在鼠标上方,或者都在下方,那这条边根本不会和水平射线相交,直接跳过就行计算交点X坐标这是整个算法最核心的数学部分:mouse.X(pointSet[j].X-pointSet[i].X)*(mouse.Y-pointSet[i].Y)/(pointSet[j].Y-pointSet[i].Y)pointSet[i].X我们把它看作**“相似三角形”或者“线性插值比例”**就很容易理解了 先算垂直进度比例(mouse.Y - p1.Y) / (p2.Y - p1.Y)。这就是算出当前鼠标的高度占这条线段总高度的百分之几 。应用到水平方向因为点在同一条斜线上你垂直方向爬了 50%水平方向也一定移动了总宽度的 50% 。所以用线段总宽度 (p2.X - p1.X) 乘以这个比例算出 X 轴上的偏移量。坐标还原最后加上起点的 p1.X就是地图上的真实绝对坐标了 。对应的数学公式表现为hitXΔX×mouseOffsetΔYXstarthitX \Delta X \times \frac{\text{mouseOffset}}{\Delta Y} X_{\text{start}}hitXΔX×ΔYmouseOffset​Xstart​完整判断代码//注意我这里返回的是我单位的唯一Id-1就是空大家根据自己的需要修改publiclongCalculateChooseUnit(Vector2mousePos,List(longid,ListVector2pointSet,Rect2 AABB,Vector2 nowPos)unitPointSet){List(pointSet,Rect2 AABB,Vector2 nowPos)tmpUnitnew();// 先通过AABB包围盒粗筛foreach(varunitinunitPointSet){if(unit.AABB.HasPoint(mousePos-unit.nowPos)){// 通过射线法判断是否在多边形内if(IsPointInPolygon(mousePos-unit.nowPos,unit.pointSet))tmpUnit.Add(unit);}}if(tmpUnit.Count0)return(-1);// 如果有多个单位重叠,选择Y坐标最大的(最下面的)varmaxYtmpUnit[0];for(inti1;itmpUnit.Count;i){if(tmpUnit[i].nowPos.YmaxY.nowPos.Y)maxYtmpUnit[i];}return(maxY.id);}结尾以上就是我实现鼠标选择检测碰撞的思路。AABB粗筛保证性能,射线法保证准确性,两者结合能处理各种复杂形状感谢大家观看

相关新闻

2026最新版 Anaconda 下载与安装全流程详解(超详细图文教程)

2026最新版 Anaconda 下载与安装全流程详解(超详细图文教程)

一、下载 首先,我们需要获取Anaconda的安装包。官方地址:Advance AI with Open Source | Anaconda 更新之后需要注册了,可以使用邮箱注册一下,如果不想注册的,我下面会放一个百度网盘的安装包地址:https:…

2026/7/2 23:48:40 阅读更多 →
基于Django的洗衣服务平台设计与实现

基于Django的洗衣服务平台设计与实现

前言着互联网技术的飞速发展,传统洗衣服务行业正逐步向线上转型。本文详细阐述了一个基于 Django 框架构建的洗衣服务平台的设计与实现过程。通过对洗衣服务业务流程的深入分析,确定了平台的功能需求和非功能需求。在此基础上,进行了系统的总…

2026/7/5 22:46:33 阅读更多 →
Java Web 在线家具商城设计与实现pf系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

Java Web 在线家具商城设计与实现pf系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

💡实话实说:C有自己的项目库存,不需要找别人拿货再加价。摘要 随着互联网技术的快速发展和电子商务的普及,线上购物已成为消费者购买家具的重要渠道。传统家具销售模式受限于地域、时间和展示空间,难以满足消费者多样化…

2026/7/5 10:37:02 阅读更多 →

最新新闻

基于LLM的智能测试框架testzeus-hercules:从Gherkin到自动化执行

基于LLM的智能测试框架testzeus-hercules:从Gherkin到自动化执行

1. 项目概述:当LLM成为你的全能测试工程师 如果你和我一样,在软件测试领域摸爬滚打了十几年,从Selenium的脚本维护地狱,到Pytest的框架封装,再到面对现代Web应用频繁的UI变更、复杂的业务逻辑和跨平台需求,…

2026/7/6 9:38:45 阅读更多 →
Python+Playwright自动化测试环境搭建:跨平台配置与工程化实践

Python+Playwright自动化测试环境搭建:跨平台配置与工程化实践

1. 项目概述:为什么是Python与Playwright? 最近几年,自动化测试领域可以说是“卷”得飞起。从早期的QTP、Selenium,到后来的Cypress、Puppeteer,工具层出不穷。但如果你问我,现在要上手一个兼顾Web、移动端…

2026/7/6 9:38:45 阅读更多 →
微信小程序反编译工具原理与实战:从.wxapkg解包到源码学习

微信小程序反编译工具原理与实战:从.wxapkg解包到源码学习

1. 项目概述:为什么我们需要一个“解构”小程序的工具? 如果你是一名前端开发者,或者对微信小程序的运行机制感到好奇,那么你一定遇到过这样的困境:看到一个设计精良、交互流畅的小程序,想学习它的实现思路…

2026/7/6 9:36:41 阅读更多 →
反序列化漏洞深度解析:从原理到实战攻防与内存马防御

反序列化漏洞深度解析:从原理到实战攻防与内存马防御

1. 项目概述:从一次真实的“内存马”攻击说起 去年,我参与了一次针对某大型企业Web应用的应急响应。攻击者并没有直接爆破密码或上传木马,而是通过一个看似无害的、用于传递用户会话状态的接口,发送了一段精心构造的数据。服务器在…

2026/7/6 9:36:41 阅读更多 →
文件上传漏洞攻防实战:从原理到CISP-PTE考点全解析

文件上传漏洞攻防实战:从原理到CISP-PTE考点全解析

1. 项目概述:从一次文件上传漏洞的实战复盘说起最近在复盘CISP-PTE认证的备考过程,发现文件上传这个考点几乎是每次渗透测试的“必考题”,也是很多安全从业者从理论走向实战的第一个突破口。很多人觉得文件上传漏洞不就是传个木马吗&#xff…

2026/7/6 9:34:39 阅读更多 →
AppScan 扫描结果分析:5步法高效验证与处理100+个潜在漏洞

AppScan 扫描结果分析:5步法高效验证与处理100+个潜在漏洞

AppScan扫描结果深度解析:从漏洞验证到修复落地的全流程指南当安全扫描工具弹出"发现100潜在漏洞"的警示时,开发团队的第一反应往往是头皮发麻。我曾见证过某金融项目团队面对AppScan生成的287页报告时的崩溃场景——安全工程师通宵标记出的&q…

2026/7/6 9:32:36 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻