1:为什么需要避障 应用场景
在游戏和仿真场景中,多个角色同时移动时,避免彼此碰撞是保证真实感和交互性的关键。大家都遇到过走路时“撞车”或角色重叠的问题,对玩家体验和视觉效果非常不友好。这就是为什么我们需要避障算法
2:传统寻路的劣势
传统寻路主要关注从点A到点B找到一条路径(如A*算法),往往忽视动态环境下多角色间的实时避让问题:
路径静态:传统算法路径固定,不适应动态障碍和角色的即时变化。
无法解决“角色之间”的碰撞冲突:通常“人物”只是简单避开障碍物,而不考虑其他动态角色的运动路径和速度。
缺少协同避免机制:角色往往独立决策,导致“撞车”、“卡顿”或“僵持”现象频发。
效率和流畅度低:为避免碰撞,往往需要大量后处理或依赖简单的碰撞检测,导致性能瓶颈和不自然动作

3:关于RVO得介绍
RVO(Reciprocal Velocity Obstacles,互惠速度障碍)算法是一种用于多智能体实时避障的优化算法,通过引入互惠协作机制解决传统VO算法的抖动问题,广泛应用于游戏开发、机器人仿真和自动驾驶领域。
RVO算法核心原理
RVO算法由Jur van den Berg等人在2008年提出,是VO(Velocity Obstacles)算法的改进版本。其核心思想是让每个智能体承担一半的避让责任:
速度障碍(VO)算法是基于未来可能碰撞的速度预测来避免碰撞的一个经典方法
1、什么是速度障碍(Velocity Obstacles,VO)
VO定义了对于某个智能体A来说,哪些速度会导致与另一个智能体B未来发生碰撞。
表示为智能体B相对运动的圆锥形区域(在速度空间里),只要选用的速度矢量落入这个区域,就会碰撞。
仅靠VO,智能体只通过自己来规避碰撞,忽略了其他智能体也会移动,容易出现不对称行为(一个人停,一个人却不动),导致效率低和死锁。
简单来说,速度障碍就是告诉你:
“嘿!这个速度很危险,会撞人,得避开。”
但它没考虑别人其实也会躲开,大家就容易做出不协调的动作。
2、RVO改进:引入互惠性(Reciprocal)
“互惠”包含两层意思:
避碰责任由碰撞双方共同承担,速度调整动作是对称的。
目标速度会根据对方的运动状态进行预测并调整,形成一种双向对话式协商。
RVO将传统VO的速度障碍区域“平移”了一个位置,表示智能体A在选择新速度时,预期对方同样会调整一半的速度。
算法实现步骤
●环境感知:检测周围智能体与障碍物的位置、速度及半径。
●构建RVO集合:为每个邻近对象计算互惠速度障碍。
●速度选择:从可选速度集合(排除所有RVO并集)中选择最接近期望速度的值。
●位置更新:应用新速度移动智能体
●RVO算法原理
下面两篇文章对原理解释的挺好 分享一下 感谢作者的分享

<u>https://blog.csdn.net/lsccsl/article/details/119732620</u>
<u>https://indienova.com/indie-game-development/vo-rvo-orca/</u>
原理演示图(ai实现)
<u>https://html8.net/go/ade6a5/</u>
4:工程演示 unity应用
<u>https://github.com/snape/RVO2-CS</u> 原版本
RVO在使用的时候大体就是一个GameManager管理所有的Agent然后计算Agent的位置 Agent告诉模拟器需要移动的方向 最终的方向由模拟器自己调整
//RVO系统里的Simulator.Instance.setAgentPrefVelocity,它的核心作用是设置某个Agent的“期望速度”(Preferred Velocity),也就是你希望这个Agent按什么方向、什么速度移动
//setAgentPrefVelocity(int agentIndex, Vector2 velocity)
//agentIndex: 你要设置哪个Agent的期望速度(通常是你注册时返回的Agent索引)。
//velocity: 期望速度,二维向量,表示Agent想要沿这个方向以这个速度移动。
//案列
//Vector2 agentPos = Simulator.Instance.getAgentPosition(agentIndex);
//Vector2 goalPos = new Vector2(goalX, goalY);
//Vector2 desiredDir = (goalPos - agentPos).normalized;
//float maxSpeed = 1.5f; // 假设这个是Agent最大速度
//Vector2 prefVelocity = desiredDir * maxSpeed;
//Simulator.Instance.setAgentPrefVelocity(agentIndex, prefVelocity);
//这样,RVO算法会在考虑避让其他Agent和障碍的情况下,尽量让你的Agent向这个期望速度靠近,保证避让又往目标移动。
//简单说,setAgentPrefVelocity就像告诉RVO:“这是我想走的方向和速度,但要考虑周围,帮我调整实际路径”。

需要注意不要更改物体的位置 RVO计算出的位置是多少就用多少 不然会破坏避让
假如需要将物体静止 需要强制设置物体的位置 并且设置速度方向为0 等于告诉模拟器我就要在这个地方
if (isStatic && sid >= 0)
{
//静止的物体
// 强制回到固定位置,避免RVO移动
Simulator.Instance.setAgentPosition(sid, staticPosition);
transform.position = new Vector3(staticPosition.x(), transform.position.y, staticPosition.y());
Simulator.Instance.setAgentPrefVelocity(sid, new Vector2(0, 0));
return;
}
5:Unity版本得RVO**
1:项目首页 - RVO2:Optimal Reciprocal Collision Avoidance (C++) - GitCode
<u>https://gitcode.com/gh_mirrors/rv/RVO2/?utm_source=artical_gitcode&index=top&type=card&webUrl&isLogin=1</u>
2:snape/RVO2-3D: Optimal Reciprocal Collision Avoidance in Three Dimensions (C++)
<u>https://github.com/snape/RVO2-3D</u>
3:<u>https://github.com/sunsvip/UnityRVO2</u> 改良版本
- 增加Agent避障权重设置,如,把到达目标位置的Agent权重设置为0后, 它就不会被其它Agent挤走;
- RVO.Vector2改为Unity Vector2,以及RVO.Math优化,避免原版分母为0导致的异常
- 增加形状障碍物,BoxObstacle、 CircleObstacle、EdgeObstacle;
6:Unity NavMeshAgent避让**

主要是priority 值0-99 越低优先级越高 优先级越高别人就会主动避让 质量越高避让效果越好同样消耗更大
单位太多了还是不行 避让效果差 很容易锁死 卡住,需结合动态阻挡才有稍微比较好的效果

NavMeshAgent组件和Nav Mesh Obstacle是互斥得 放在同一个单位身上很难管理 改变网格后也不能及时生效,并且需要注意 开启阻挡得适合 上面不能有开启的agent单位 否则会造成agent瞬移