“眼睁睁看它穿墙而过!“:连续碰撞检测的“全程盯防“之道
引子:小李的"穿墙惯犯"
上回说到,小李把 Update、FixedUpdate、LateUpdate 三兄弟的分工捋得清清楚楚。这天,他兴致勃勃地给射击游戏做子弹,结果一测试,又撞上一桩让他抓耳挠腮的怪事:
"老师傅,又见鬼了!我给游戏做了子弹——慢慢飞的时候,打墙上’啪’一下,好好的;可我把子弹速度一调快,想做个’狙击枪高速弹’,结果——
**子弹’嗖’地一下,直接从墙里穿过去了!眼睁睁看着它穿墙而过**,墙跟纸糊的一样,压根没挡住!**
**更邪门的是:同一堵墙、同一颗子弹,慢速就撞得住、快速就穿得过!我反复检查,墙有碰撞器、子弹也有碰撞器,配置一模一样啊!
**还有个玩家反馈:‘我这游戏里,角色跳得慢就好好落地,一旦从高处快速坠落,'噗’一下就掉出地板、掉进虚空了!’
**老师傅,这就怪了——为啥’慢’就撞得住、'快’就穿得过?难道速度一快,碰撞检测就失灵了?这到底是啥毛病?"
老师傅一听,捻须笑道:
“你这毛病,江湖上有个专门的名号,叫’隧穿(Tunneling)'——高速物体,像挖了条隧道似的,'唰’一下从墙里钻过去了!你别急着怪墙、怪子弹,它们都没错。根子在于你游戏默认用的那套’碰撞检测’的法子——它是’一帧拍一张照’的’离散’法子,速度一快,它就’看漏了’!今天,我就教你那道专治高速穿墙的解药——‘连续碰撞检测’,一套’全程盯防、绝不看漏’的功夫!”
第一章:先懂病根——“离散检测”:一帧拍一张照,快了就"看漏"
老师傅说,要治这病,先得懂默认那套检测法子是怎么"看漏"的。它叫"离散碰撞检测",工作方式,就像一个人"一帧睁一次眼、拍一张照",两次睁眼的间隙,全是"盲区"!
┌────────────────────────────────────────────────┐ │ 📸 病根:离散检测——"一帧拍一张照",间隙全是盲区! │ │ │ │ 默认的检测方式:每一帧,在物体【当前所在的位置】, │ │ "拍一张照",检查这一刻"有没有和别的东西重叠"。 │ │ │ │ 🐢 慢速子弹(每帧只挪一点点): │ │ 第1帧📸 第2帧📸 第3帧📸 │ │ 子弹○ ──→ 子弹○ ─→ [墙███] │ │ ↑第3帧拍照: │ │ "子弹和墙重叠了!"→撞上!✅│ │ → 每帧挪得少,总有一帧"正好拍到"重叠,撞得住! │ │ │ │ 🚀 高速子弹(每帧挪一大截): │ │ 第1帧📸 第2帧📸 │ │ 子弹○ ─────[墙███]─────→ 子弹○ │ │ ↑墙前 ↑墙后! │ │ 第1帧拍照:子弹在墙前,没重叠 │ │ 第2帧拍照:子弹已在墙后,也没重叠! │ │ → 关键:子弹"穿过墙"这一瞬,发生在 │ │ 两次拍照的【间隙】里,没被任何一张照片拍到! │ │ → 检测器一脸懵:"我两张照片都没见它俩重叠呀?" │ │ → 于是"看漏了",子弹大摇大摆穿墙而过! 😱 │ │ │ │ → 病根:检测只看"一个个孤立的瞬间点", │ │ 快到"一帧就跨过整堵墙",就从盲区溜走了! 🎯 │ └────────────────────────────────────────────────┘💡病根·离散检测:Unity 默认的碰撞检测叫"离散(Discrete)"——它的工作方式,是每一帧,只在物体"当前所在的这个位置",拍一张快照,检查这一瞬间"有没有和别的东西重叠"。
🎯为什么"慢"就撞得住:慢速子弹每帧只挪一点点,所以在它靠近墙的过程中,总有那么一帧,正好把它"拍"在和墙重叠的位置上——于是检测器发现了重叠,判定撞上,稳稳当当。
😱为什么"快"就穿过去:高速子弹每帧挪一大截——
- 第 1 帧拍照:子弹还在墙前,没重叠;
- 第 2 帧拍照:子弹已经蹿到墙后去了,也没重叠!
- 而子弹真正"穿过墙"的那一瞬间,恰恰发生在两次拍照的"间隙"里,没被任何一张照片捕捉到!
于是检测器一脸茫然:“我这两张照片,都没见它俩重叠啊?”——就这么**“看漏了”**,子弹大摇大摆地穿墙而过。
🎯一句话点破:离散检测的软肋,是它只盯着"一个个孤立的瞬间点",却看不见"两点之间的过程"。物体一旦快到"一帧就跨过整堵墙",就从这检测的盲区里溜走了。
小李恍然:
“原来如此!默认的’离散检测’是每帧只在物体当前位置’拍一张照’查重叠!慢速子弹每帧挪一点点、总有一帧正好拍到和墙重叠、就撞住;高速子弹每帧挪一大截——第1帧还在墙前、第2帧已到墙后,穿墙那一瞬发生在两次拍照的间隙里、没被任何照片拍到,就’看漏’穿过去了!病根是它只看孤立的瞬间点、看不见两点之间的过程!那……这’解药’又是怎么补上这盲区的?”
第二章:核心解药——“连续检测”:不看"点",看"整条运动轨迹"
老师傅说,解药就是那道功夫——“连续碰撞检测(Continuous)”。它的思路极妙:既然物体是从A点飞到B点的,那我就不只看A点和B点这两张"快照",而是把"A到B这一整条飞行轨迹"都扫描一遍,看沿途撞没撞到东西!
┌────────────────────────────────────────────────┐ │ 🔦 解药:连续检测——扫描"整条运动轨迹",绝不看漏! │ │ │ │ 离散检测(看"点"): │ │ 只查"这一帧的位置"这一个孤立的点 │ │ → 两点间的过程是盲区! │ │ │ │ 连续检测(看"路径"): │ │ 不只看起点终点,更把"从上一帧位置 │ │ 到这一帧位置"之间【走过的整条路径】, │ │ 像用探照灯一样,【全程扫描】一遍! │ │ │ │ 🚀 同样一颗高速子弹: │ │ 上一帧○───────[墙███]───────→○这一帧 │ │ └──── 扫描这整条路径 ────┘ │ │ 🔦沿途一路扫:"路上碰到啥没?" │ │ → "咦!路径正好穿过了墙!" │ │ → 立刻判定:在【碰到墙的那一点】 │ │ 就该停下、就该命中! ✅ │ │ │ │ ┌──────────────────────────────────┐ │ │ │ 离散:眨眼快照,只看落脚的"点" │ │ │ │ 连续:全程追踪,扫遍走过的"路" │ │ │ └──────────────────────────────────┘ │ │ │ │ 开启方式:把高速物体的Rigidbody, │ │ 碰撞检测模式从Discrete改成【Continuous】 │ │ │ │ → 不再只盯"落脚的瞬间",而是追踪"走过的 │ │ 全程"——再快的物体,也逃不过沿途的盯防! 🎯 │ └────────────────────────────────────────────────┘💡核心解药·连续检测:
Continuous(连续碰撞检测)的思路极其巧妙——它不再只查"这一帧的落脚点"这一个孤立的位置,而是把物体**"从上一帧的位置,到这一帧的位置"之间走过的那一整条路径,像用探照灯一样,全程扫描一遍**,看沿途有没有撞到东西。
🎯它如何治穿墙:还是那颗高速子弹——虽然它"上一帧在墙前、这一帧在墙后",两个落脚点都没和墙重叠,但连续检测会扫描这两点之间的整条飞行路径,一扫就发现:"咦!这条路径正好穿过了墙!"于是立刻判定:子弹应该在碰到墙的那一点停下、命中——穿墙的Bug,当场根治!
🎯一图看懂区别:
- 离散:像"眨眼拍快照",只看你落脚的那个"点";
- 连续:像"探照灯全程追踪",扫遍你走过的整条"路"。
🔧怎么开启:把高速物体的 Rigidbody,其"碰撞检测模式(Collision Detection)"从默认的
Discrete改成Continuous(或更强的Continuous Dynamic)即可。
💡精髓所在:连续检测的智慧,是从"只盯落脚的瞬间点",升级成了"追踪走过的全过程"——如此,再快的物体,也逃不过它对沿途每一寸路径的盯防。
小李眼睛一亮:
“妙啊!连续检测不只看起点终点两个孤立的点,而是把’从上一帧到这一帧走过的整条路径’像探照灯一样全程扫一遍!高速子弹虽然两个落脚点都没和墙重叠,但一扫路径就发现’正好穿过了墙’,立刻在碰墙那点判定命中——穿墙当场根治!离散是眨眼快照只看落脚的点、连续是探照灯全程扫遍走过的路!把Rigidbody改成Continuous就行!那……这么厉害,为啥不给所有物体都开上连续检测、一劳永逸呢?”
第三章:关键权衡——为啥不"全开"?好钢要用在刀刃上
老师傅赞许地点头——这正问到了最关键的"分寸"!连续检测虽好,却比离散"费力气"得多!所以绝不能无脑全开,得"该用才用、好钢用在刀刃上"!
┌────────────────────────────────────────────────┐ │ ⚖️ 权衡:连续检测更"费力",绝不能无脑全开! │ │ │ │ 连续检测的代价: │ │ 离散只查"一个点"→ 轻松、省力 │ │ 连续要扫"一整条路径"→ 计算量大得多、费性能! │ │ │ │ ❌ 无脑全开(给所有物体都开连续): │ │ 满屏几百个物体都在"全程扫描路径" │ │ → 性能被大量消耗、游戏卡顿掉帧! 😱 │ │ (好比给每件小事都派最贵的专家全程盯防, │ │ 纯属浪费!) │ │ │ │ ✅ 该用才用·好钢用在刀刃上: │ │ │ │ 需要连续检测的(高速!易穿墙!): │ │ · 子弹、炮弹、飞镖 → 开 Continuous! │ │ · 高速坠落/冲刺的角色 │ │ → 这些"快到会看漏"的,才值得费这力气! │ │ │ │ 用默认离散就够的(慢速/大部分物体): │ │ · 走路的角色、滚动的箱子、缓慢的平台 │ │ → 反正慢、不会穿,离散又快又够用! │ │ │ │ → 精髓:分清"哪些快到需要盯防、哪些慢到无需", │ │ 把宝贵的性能,精准花在真正需要的地方! 🎯 │ └────────────────────────────────────────────────┘💡关键权衡·不能全开:连续检测虽好,却有代价——离散只查"一个点",轻松省力;连续要扫描"一整条路径",计算量大得多、更费性能。天下没有免费的午餐,这份"全程盯防"的稳妥,是用"更高的性能开销"换来的。
😱无脑全开的后果:如果不加分辨,给场景里所有物体都开上连续检测——满屏几百个物体,个个都在"全程扫描路径",性能就会被大量吞噬,游戏卡顿掉帧。这好比"给每一件鸡毛蒜皮的小事,都派最昂贵的专家全程盯防",纯属浪费。
✅正解·好钢用在刀刃上:聪明的做法是分清主次、按需分配——
- 需要开连续的(那些"快到会被看漏"的):子弹、炮弹、飞镖、高速坠落或冲刺的角色 → 它们值得费这份力气;
- 用默认离散就够的(慢速的、大部分物体):走路的角色、滚动的箱子、缓慢的平台 → 反正慢、不会穿墙,离散又快又够用,何必浪费?
🎯精髓所在:分清"哪些快到需要盯防、哪些慢到无需盯防",把宝贵的性能,精准地花在真正需要的地方——这份"该用才用、好钢用在刀刃上"的分寸,才是高手的做法。
小李彻底通透:
“全懂了!连续检测虽好但更费性能——离散查一个点轻松、连续扫一整条路径费力!无脑全开会让满屏物体都全程扫描、卡顿掉帧,好比给每件小事都派最贵专家全程盯防、纯属浪费!正解是好钢用在刀刃上:高速易穿墙的(子弹炮弹、高速坠落的角色)才开连续、值得费这力气;慢速的大部分物体(走路角色、滚箱子)用默认离散又快又够用!分清哪些快到需盯防、哪些慢到无需,把宝贵性能精准花在真正需要处!这道连续碰撞检测我彻底摸透了!”
第四章:终极总结——连续碰撞检测的完整图谱
小李把这场"治穿墙"的领悟,浓缩成一张表:
┌────────────────┬──────────────────────────────────┐ │ 连续碰撞检测 │ 要点 │ ├────────────────┼──────────────────────────────────┤ │ 病症 │ 隧穿:高速物体穿墙而过 │ │ 病根 │ 离散检测只拍"孤立瞬间",漏掉过程 │ │ 为何慢的撞得住 │ 慢→总有一帧正好拍到重叠 │ │ 为何快的穿过去 │ 快→穿墙发生在两次拍照的间隙里 │ │ 解药 │ 连续检测:扫描"整条运动轨迹" │ │ 离散vs连续 │ 离散看"点"、连续看"路" │ │ 开启方式 │ Rigidbody→Collision→Continuous │ │ 关键权衡 │ 连续费性能,不能无脑全开 │ │ 分寸 │ 好钢用刀刃:高速的才开、慢的用默认 │ │ 一句话 │ 别只看孤立的落脚点、要盯住走过的 │ │ │ 全过程;而盯防要用在真正快处! │ └────────────────┴──────────────────────────────────┘小李摸着这张表,悟出了"连续碰撞检测"的"题眼":
"我总算把这’穿墙’的病治明白了——
**原来那漏检的病根,竟是只顾’一帧一帧地抓拍孤立的瞬间’,却看不见’瞬间与瞬间之间那段真实走过的过程’;而解药,便是把目光从’孤立的落脚点’,挪到’完整的运动轨迹’上——越是快速前进的东西,越容易在盯防的间隙里出岔子,越需要盯住它’走过的全程’;可这份严密的盯防又代价不菲,故而更要分清轻重、好钢用在刀刃上**!**
**而它给我最深的启示是:看人、看事,若只靠’偶尔抽查几个孤立的瞬间快照’,极易漏掉那些发生在’快速变化的间隙’里的真相;真正可靠的洞察,是盯住’连续的过程与轨迹’,而非孤立的几个点。而越是高速前进、剧烈变化的人与事,越藏着容易被’看漏’的隐患,越值得投入这份连续的关注——同时也别忘了,这份关注是有成本的,当用在真正快速、真正要紧之处。"
尾声:一道"全程盯防"的功夫,亦是人生的智慧
小李这场对"连续碰撞检测"的领悟,从"眼睁睁看子弹穿墙"的怪事出发,摸透了那道治穿墙的功夫——离散检测漏在"只拍孤立瞬间",连续检测胜在"追踪完整轨迹",而这份盯防又要"好钢用在刀刃上"。
但当我们合上书,会发现这道"全程盯防"的功夫背后,竟也舒展着几分耐人寻味的人生哲理。
第一,别只看"孤立的快照",要盯住"连续的过程"——真相往往藏在瞬间与瞬间的间隙里。
这道功夫最根本的洞察,是——离散检测的漏检,恰恰在于它"只抓拍孤立的瞬间点,却看不见瞬间之间那段真实走过的过程";而连续检测的可靠,正在于它盯住了"完整的运动轨迹"。这何尝不是一记对认知的深刻点拨?我们看人、看事、下判断,太容易依赖"几张孤立的快照"——凭某人某一刻的一句话、一个表现、一次偶然的抽查,就急着给他"盖棺定论"。可这种"抽查式"的判断,恰如那漏检的离散检测:它极易漏掉那些发生在"快照与快照之间"的真相——那个当众彬彬有礼的人,或许恰在你没看见的间隙里刻薄待人;那个偶尔表现平平的人,或许正在你没留意的过程中默默精进。真正可靠的洞察,从不满足于几个孤立的瞬间点,而是耐心地追踪"连续的过程与轨迹":看一个人,不看他偶尔的高光或失手,而看他一贯的言行轨迹;评一件事,不看某个孤立的结果快照,而看它完整的来龙去脉。因为真相与本质,往往就藏在那些"被抽查漏掉的过程"里。盯住连续的轨迹、而非孤立的快照,才不至于被瞬间的假象所蒙蔽——这是看透人事最朴素、也最可靠的功夫。
第二,越是"高速前进、剧烈变化",越藏着容易被看漏的隐患——快进时更要密切盯防。
那"慢的撞得住、快的穿过去"的现象,藏着一个耐人寻味的规律——物体越是高速,越容易在检测的间隙里"溜走出岔子";越快,越需要连续的盯防。这道破了一个关于"变化与风险"的深刻真理:人生里,那些"高速前进、急剧变化"的阶段,恰恰是最容易在不知不觉间"出岔子"的高危时刻。一段关系升温太快,往往在热烈的间隙里埋下了没看清的隐患;一项事业扩张太猛,常常在狂奔的盲区里积累了没察觉的漏洞;一个人顺风顺水、志得意满地高速前进时,也最容易在得意的间隙里,漏看了脚下正在逼近的"那堵墙"。就像慢速的子弹撞得住、高速的却穿墙而过——慢行时,凡事看得清、来得及;可一旦进入高速,那些平时轻易能察觉的风险,就极可能从"盯防的间隙"里悄悄溜过、酿成大祸。真正清醒的人懂得:越是顺利、越是快速前进的时候,越不能松懈盯防,反而要投入更密切、更连续的关注,盯紧自己"高速走过的每一寸轨迹"。快,从不意味着可以放松警惕;恰恰相反,越快,越要睁大眼睛。
第三,严密的盯防代价不菲,要"好钢用在刀刃上"——把宝贵的关注,精准投给真正要紧处。
那"不能无脑全开、该用才用"的权衡,藏着一份难得的清醒——连续检测虽好却费性能,故而绝不给所有物体全开,而是分清主次、只把它用在"高速易穿墙"的关键物体上。这道破了一个关于"精力分配"的处世智慧:我们能投入的"深度关注与精力",如同那宝贵的性能,是极其有限的,绝不可能对每一件事都投入"全程盯防"式的极致关注。那种"事无巨细、样样都想紧盯到底"的人,看似认真负责,实则把有限的精力平摊在了一堆无关紧要的小事上——如同给每个慢速物体都开连续检测,白白耗尽性能、最终在真正要紧处反而无力兼顾(卡顿掉帧)。真正高效的人懂得:先分清"哪些是快到会出大岔子、必须密切盯防的要紧事(如子弹),哪些是慢而无害、大可放心用最省力方式对待的寻常事(如滚动的箱子)";然后把最深、最连续的关注,精准地投给前者,对后者则从容放手、不必事事紧盯。好钢用在刀刃上,该盯紧的绝不松懈、该放手的绝不浪费精力——这份"分清轻重、精准投入"的分寸,才能让有限的关注发挥最大的价值。什么都想紧盯的人,终将什么都盯不好。
下次,当你只凭几张孤立的快照就急着给人下定论,或在顺风顺水、高速前进时放松了警惕,又或事无巨细样样都想紧盯到底时,请记得这道"全程盯防"的智慧——
像那 **追踪轨迹的"连续检测"**那样,别只看孤立的落脚点,要盯住连续的过程与轨迹,真相往往藏在被抽查漏掉的间隙里;像那 **高速物体的"隧穿警示"**那样,越是高速前进、剧烈变化,越藏着容易被看漏的隐患,快进时更要密切盯防;更像那 **好钢用在刀刃上的"性能权衡"**那样,把有限而宝贵的深度关注,精准地投给真正快速、真正要紧之处,该盯紧的绝不松懈、该放手的绝不浪费。于是,你成了那个看得透过程、警惕得住高速、又分得清轻重的通达之人。
“Unity 的连续碰撞检测”,就是这门关于"盯住连续过程而非孤立快照、高速前进更需密切盯防、好钢用在刀刃上"的、朴素而深刻的智慧。
它告诉我们:别只看孤立的快照、要盯住连续的过程,真相藏在瞬间的间隙里;越是高速前进剧烈变化、越藏着容易被看漏的隐患,快进时更要密切盯防;严密的盯防代价不菲、要好钢用在刀刃上,把宝贵关注精准投给真正要紧处。它像一句朴素的箴言,提醒着我们——
别只凭几张孤立的"快照"就给人给事盖棺定论,学会盯住"连续的过程与轨迹",因为最要紧的真相,往往就藏在那些被抽查漏掉的间隙里;
别在顺风顺水、高速前进时放松了警惕,越是快速变化的时刻越藏着容易被看漏的隐患,越要投入密切而连续的盯防、盯紧自己走过的每一寸轨迹;
别事无巨细、样样都想紧盯到底,懂得有限的深度关注是宝贵的、要好钢用在刀刃上,把它精准投给真正快速、真正要紧的地方,该盯紧的绝不松懈、该放手的绝不浪费——
一个懂得"盯住过程、警惕高速、精准投入"的人,
才能像那周密的连续碰撞检测,
不被孤立的快照蒙蔽,
在高速前进时也盯得住脚下的墙,
把宝贵的关注精准花在刀刃上,
于是识人者不被瞬间的假象所惑,
进取者不在狂奔中埋下隐患,
谋事者不在琐碎里耗尽心力,
活成一个既看得透过程、
又警惕得住高速、
更分得清轻重的,
清醒而通达之人。
这,就是藏在"Unity 连续碰撞检测"那道"全程盯防"的功夫背后,最深、也最美的浪漫。
