做XR开发系列的项目,避不开碰撞检测这一环。不管你是做VR里的手势抓取,还是AR里的物体摆放,碰撞检测都像空气一样无处不在,但真正把它吃透的人,其实不多。这次我用一个特别小的案例——“当小球遇到收集物”来把碰撞检测这件事彻底掰开揉碎,从原理讲到踩坑,从方案选型讲到性能调优。这个小场景很适合XR开发入门练手,也很适合那些在Unity里写了不少交互逻辑、却总被碰撞问题折磨的朋友当作一次系统复盘。
这个案例本身很简单:场景里有一颗小球,周围散落着若干收集物,小球碰到收集物,收集物消失并加分。听起来是不是特别简单?但就是这个“简单”里藏着很多开发者容易忽略的细节——为什么有时碰撞不触发?为什么球直接穿过去了?XR里手柄手部应该如何参与碰撞?这些问题的答案,都能在这套小项目里找到。这篇文章我就完整记录一下我的实现过程,从环境准备到代码分析,再到问题排查,尽量做到你看完能直接照着复现。
1. 先把碰撞检测这件事想清楚
1.1 碰撞检测在XR世界里到底是什么角色
在Unity里说“碰撞检测”,其实绝大多数时候说的是两件事:一是物理引擎对两个物体是否接触的判定,二是碰撞发生后你要执行的游戏逻辑。前者靠的是Collider(碰撞体)和Rigidbody(刚体),后者靠的则是像OnTriggerEnter、OnCollisionEnter这类事件回调。
XR场景里这一环尤其重要,原因很简单:AR和VR里玩家会用手去“摸”东西、用眼睛去“看”准星,如果你的碰撞体位置不对、层级过滤搞错了,会出现特别出戏的体验——明明手都穿过苹果了,苹果却纹丝不动,这种违和感会瞬间把沉浸感毁掉。
打个比方,Collider就像快递箱外面的尺寸数据,告诉系统“我占多大地方”;Rigidbody则像箱子里的货物属性,告诉系统“我多重、能不能被推动、是不是会飘”。没有尺寸数据的箱子,快递分拣根本不知道该把它送哪;没有货物属性的箱子,就算占了位置也不会出现在分拣流程里。所以碰撞检测的第一步,不是写代码,而是确保物体上挂对了这些基础组件。
很多人喜欢一上来就闷头写脚本,结果发现碰撞永远不触发,回头一查,好家伙,两个物体上都没有Rigidbody。这种现象在XR开发者里实在太常见了,尤其是从纯美术、策划转过来的朋友,撞几次墙之后才真正理解物理引擎的工作方式。
1.2 为什么拿“小球+收集物”开刀
之前带项目的时候,我经常用这个案例作为XR开发的第一个实战练习,原因有三个。
第一,小球是规则几何体里最简单的一种,Sphere Collider 的包围逻辑最直观,不会像MESH Collider那样出现“怎么又穿模了”的排查地狱。用小球做碰撞实验,可以把变量控制到最少,出问题时一眼就能定位是物理参数的问题,还是脚本逻辑的问题。
第二,收集物这个玩法在XR里太常见了,项目里叫法五花八门:金币、能量块、数据碎片、记忆碎片。但底层的交互模式是一样的——玩家靠近,触发事件,物品质变或消失。我把这个小玩法吃透,以后做起各类收集任务、补充弹药、拾取装备,代码骨架基本可以直接复用。
第三,这个小案例能自然引出碰撞检测里的两个分支:触发器方案和物理碰撞方案。小球碰收集物,你既可以让收集物变成可穿透的“触发器”,用OnTriggerEnter处理收集;也可以让它保持物理碰撞,用OnCollisionEnter判断“被撞到”然后响应。两者各有合适的应用场景,用这个案例来对比演示,刚刚好。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 项目准备与环境搭建
2.1 工具选型与版本选择
这次我用的是Unity 2021.3 LTS,搭配内置的XR Interaction Toolkit,相关版本是2.3.x。之所以选Unity而不是其他引擎,一是团队现有积累基本都在Unity生态,二是碰撞检测相关的物理接口在XR开发里足够成熟,网上踩坑资料也多。如果你用Unreal Engine,思路完全一致,只是节点名称和配置入口不同,比如碰撞通道Collision Channel的设置位置有些差异,但底层道理是相通的。
用Unity的话,记得在Package Manager里安装XR Plugin Management,同时根据你的目标设备安装对应的插件,比如Oculus XR Plugin、OpenXR Plugin或者AR Foundation。这一步别跳过,否则后面打包到真机时会发现很多现成
