恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

游戏角色碰撞处理:从原理到实战

  • 首页
  • 资讯中心
  • /
  • 游戏角色碰撞处理:从原理到实战

相关资讯

虚拟显示器终极指南:用 parsec-vdd 免费给 Windows 凭空变出 16 块 4K@240Hz 屏幕 2026/8/20 15:48:24
9.1 项目背景与价值(第9章 产品全渠道营销工作流) 2026/8/20 15:48:24
BES 外部型号与内部编译型号对照表 2026/8/20 15:48:24

最新资讯

python的运筹学工业场景模拟第七十一篇:批量读取5组不同市场需求报表,批量转换为模型输入,方便批量对比多场景计算。
ChampSim hashed_perceptron 深度解析:现代感知机预测器的高效奥秘
为什么该抛弃PHP原生$_SESSION?storageless无存储会话的7大核心优势解读
电脑越用越卡?开源免费的 Win11Debloat 一键清理系统冗余,实测开机提速最高 54%
如何用Neural Amp Modeler训练专业级吉他音箱模拟模型
【单片机课设毕设项目】基于 51/STM32 单片机的自动手动双模式台灯装置设计 物联网环境下单片机智能感应台灯监控系统设计(011904)

今日推荐

类模板模板参数的全部使用场景
多态的理解,虚函数表的理解
C++ 类编译器自动生成的默认函数 | 拷贝构造函数 vs 拷贝赋值运算符(赋值构造)

本周热门

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码
【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码
隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

本月精选

如何用DamaiHelper实现演唱会门票的智能自动化抢购:完整技术解决方案指南
第4篇:59 倍性能差距的索引瓶颈定位——一次教科书级的全表扫描调优
终极歌词批量下载神器:5分钟解决离线音乐库歌词同步难题

游戏角色碰撞处理:从原理到实战

发布时间:2026/8/20 15:53:24
游戏角色碰撞处理:从原理到实战 做第三人称或第一人称游戏角色移动这块绕不开一个问题人撞到墙了怎么办最土的做法是撞到就停。但凡玩过几个游戏你就知道这手感有多差——斜着走向墙壁人直接钉在墙上不动了得手动把方向掰正才能继续贴着墙走。正常的做法是让角色沿着墙面滑过去你朝墙斜推摇杆人会顺着墙滑行这就是 Collide and Slide。这套东西早年是 Kasper Fauerby 那篇《Improved Collision Detection and Response》带火的现在基本是 kinematic 角色控制器的标配。Unity 自带的 CharacterController 内部干的也是类似的事只是它是黑盒很多时候我们需要自己实现一套能完全掌控的。一句话讲清楚原理角色这一帧想移动一个向量velocity。往这个方向扫一下如果撞到了一个平面把velocity拆成两部分一部分垂直于墙面这部分被墙挡住扔掉一部分平行于墙面这部分保留继续走。平行分量怎么算就一个投影slide velocity - Dot(velocity, normal) * normalDot(velocity, normal)是速度在法线方向上的投影长度减掉它剩下的就是贴着墙面的那份运动量。就这么简单。为什么要递归问题在于你把速度投影到墙面之后接着滑滑着滑着可能又撞到另一面墙——最典型的就是墙角。这时候得再投影一次。所以整个流程写成递归很自然撞一次投影一次往下递归处理剩余的运动量。递归得有个头不然在死角里会转圈。一般限制 3 到 5 次就够了撞满了就停下剩下那点运动量丢掉。玩家基本感知不到。[SerializeField]privateintmaxBounces5;[SerializeField]privatefloatskinWidth0.015f;[SerializeField]privateLayerMaskcollisionMask;privateVector3CollideAndSlide(Vector3vel,Vector3pos,intdepth){if(depthmaxBounces)returnVector3.zero;floatdistvel.magnitudeskinWidth;// 用胶囊沿运动方向扫p1/p2 是胶囊两个球心if(Physics.CapsuleCast(p1,p2,radius,vel.normalized,outRaycastHithit,dist,collisionMask)){// 先贴到碰撞点前面一点留出 skinWidth 别贴死Vector3snapToSurfacevel.normalized*(hit.distance-skinWidth);Vector3leftovervel-snapToSurface;if(snapToSurface.magnitudeskinWidth)snapToSurfaceVector3.zero;// 剩余运动量投影到墙面leftover-Vector3.Dot(leftover,hit.normal)*hit.normal;returnsnapToSurfaceCollideAndSlide(leftover,possnapToSurface,depth1);}returnvel;}skinWidth 是必须的刚上手的人经常漏掉 skinWidth然后遇到角色贴墙抖动的问题查半天。原因是浮点精度。如果你每次都把角色精确贴到碰撞面上距离 0下一帧检测可能因为误差判定成已经嵌进墙里或者刚好卡在触发与不触发的边界反复横跳表现出来就是人贴着墙一直抖。skinWidth 的作用是让角色永远和墙留一条头发丝的缝隙检测的时候把这个缝隙算进去。值不用大0.01 到 0.02 之间就行太大玩家会觉得人和墙之间有明显空隙。水平和垂直得分开算这是实战里最容易踩的坑。如果你把水平移动和重力揉成一个向量一起做 Collide and Slide斜坡上会出各种鬼问题。举个例子人站在斜坡上重力向量朝下。如果和水平速度一起投影到坡面水平速度会被坡面的法线影响结果就是你在坡上走得莫名其妙——上坡走不动下坡莫名加速。正确做法是拆成两趟publicvoidMove(Vector3moveInput){Vector3postransform.position;// 第一趟水平移动Vector3horizontalVelnewVector3(moveInput.x,0,moveInput.z);posCollideAndSlide(horizontalVel,pos,0);// 第二趟重力Vector3gravityVelVector3.down*gravity*Time.deltaTime;posCollideAndSlide(gravityVel,pos,0);transform.positionpos;}水平那趟负责处理墙和斜坡上的行走垂直那趟单独处理下坠和落地。两者互不干扰斜坡手感一下子就对了。斜坡当地面还是当墙还有个绕不过去的判断一个碰到的面到底是能走上去的斜坡还是走不上去的陡墙靠法线和竖直方向的夹角来分。角度小于最大可行走坡度当地面处理人能走上去超过了当成墙人在上面往下滑。floatangleVector3.Angle(Vector3.up,hit.normal);boolisWalkableanglemaxSlopeAngle;处理地面和墙的投影方式还得区别对待。走上坡的时候你希望人保持水平速度的大小往上爬而不是被坡面投影掉一截否则越陡走得越慢很别扭。这块细节比较多不同游戏的手感取向也不一样展开能再写一篇。什么时候用它Collide and Slide 是个 kinematic 方案意思是你自己算位置、自己设 transform不走刚体物理。它比接一整套 Rigidbody 轻,而且手感完全捏在自己手里——这对角色移动特别重要玩家对操作手感的敏感度远高于物理真实度。绝大多数需要精确控制角色的游戏都是这么做的Rigidbody 那套更适合可以被推来推去的场景物体。缺点是台阶、动态平台、被其他物体挤压这些边缘情况都得自己补代码量不小。但换来的是完全可控值。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号