Steering Behavior 是什么?
简单介绍Steering Behavior,了解它的核心内容是什么
Steering Behavior
中文标准译法:转向行为 / 制导行为
多用于游戏AI、群体仿真、自动驾驶、机器人路径规划领域。
1. 核心定义
Steering Behavior 是一类局部运动智能算法,让虚拟角色/Agent 根据周围环境实时计算转向力,实现自然、平滑的移动,不需要预先规划完整路径。
由 Craig Reynolds 在1999年提出,是群体AI(Boids)的基础。
本质:输出一个转向矢量(steering force),用来修正当前速度,引导物体朝目标运动。
2. 常见基础 Steering Behavior(经典类型)
- Seek(追逐)
朝着目标位置移动,持续逼近目标。 - Flee(逃离)
远离威胁目标。 - Arrive(抵达)
靠近目标时自动减速,平稳停下(Seek不会减速,会冲过目标)。 - Pursuit(追击)
预判目标未来位置,追踪移动目标(比Seek更智能)。 - Evade(规避)
预判移动物体轨迹,提前躲开。 - Wander(漫游/游荡)
随机平滑转向,模拟漫无目的闲逛。 - Avoid Obstacle(障碍物规避)
检测前方障碍,侧向绕行。 - Separation(分离)
群体内个体互相推开,防止挤在一起(鸟群、人群必备)。 - Alignment(对齐)
群体个体朝向与周围同伴运动方向保持一致。 - Cohesion(凝聚)
向群体中心靠拢,维持集群。
Separation + Alignment + Cohesion = 经典 Boids 鸟群算法
3. 工作简易流程
- Agent 当前有速度向量
velocity - 行为计算出期望速度
desired velocity - Steering Force = desired velocity − current velocity
- 将转向力施加到物体,限制最大加速度、最大速度,更新位置
4. 使用场景
- Unity / Unreal 游戏NPC、怪物、载具AI
- 人群仿真、车流模拟
- 无人机、机器人局部避障运动控制
- 自动驾驶局部路径跟随
区分两个易混概念
- Pathfinding(寻路):A*、NavMesh → 找整条静态路线(宏观)
- Steering Behavior(转向行为):沿着路线平滑移动、避障、群体互动(微观运动控制)
如何实现 Steering Behavior 算法?
核心公式(重中之重)
SteeringForce(转向力)= DesiredVelocity(期望速度)− CurrentVelocity(当前速度)
约束:
- 转向力有最大上限
maxForce(避免瞬间急转) - 物体有最大速度
maxSpeed - 使用加速度更新速度,速度更新位置
运动更新统一框架(所有行为共用)
// 每一帧执行
steeringForce = 各个行为算出的转向力加权叠加
steeringForce = ClampMagnitude(steeringForce, maxForce);
velocity += steeringForce * deltaTime;
velocity = ClampMagnitude(velocity, maxSpeed);
position += velocity * deltaTime;
所有 Steering 行为,只是计算不同的 DesiredVelocity。
一、逐个实现经典行为(向量伪代码)
假设向量库提供:Normalize()、Magnitude()、ClampMagnitude()
1. Seek 追逐(奔向目标点)
Vector3 Seek(Vector3 targetPos)
{
Vector3 desiredVelocity = (targetPos - position).normalized * maxSpeed;
Vector3 steering = desiredVelocity - velocity;
return steering;
}
2. Arrive 抵达(靠近目标自动减速,不会冲过去)
Vector3 Arrive(Vector3 targetPos, float slowRadius)
{
Vector3 toTarget = targetPos - position;
float distance = toTarget.magnitude;
Vector3 desiredVelocity;
if (distance < 0.001f)
desiredVelocity = Vector3.zero;
else if (distance < slowRadius)
{
// 距离越近,速度越低
float speed = maxSpeed * (distance / slowRadius);
desiredVelocity = toTarget.normalized * speed;
}
else
{
desiredVelocity = toTarget.normalized * maxSpeed;
}
Vector3 steering = desiredVelocity - velocity;
return steering;
}
3. Flee 逃离
Vector3 Flee(Vector3 threatPos)
{
Vector3 desiredVelocity = (position - threatPos).normalized * maxSpeed;
Vector3 steering = desiredVelocity - velocity;
return steering;
}
4. Pursuit 预判追击(追踪移动目标)
思路:预测目标未来位置,再对预测点执行Seek
Vector3 Pursuit(Agent targetAgent)
{
// 预估追击时间:距离/自身最大速度
float dist = Vector3.Distance(position, targetAgent.position);
float predictTime = dist / maxSpeed;
// 预测目标未来位置
Vector3 futureTargetPos = targetAgent.position + targetAgent.velocity * predictTime;
return Seek(futureTargetPos);
}
5. Evade 预判躲避
和Pursuit相反,预测威胁位置然后Flee
Vector3 Evade(Agent threatAgent)
{
float dist = Vector3.Distance(position, threatAgent.position);
float predictTime = dist / maxSpeed;
Vector3 futureThreatPos = threatAgent.position + threatAgent.velocity * predictTime;
return Flee(futureThreatPos);
}
6. Wander 随机漫游(平滑闲逛,NPC常用)
原理:前进方向前方虚拟圆圈,随机取点作为临时目标
Vector3 Wander()
{
// 1. 前进方向前方生成一个圆心
Vector3 circleCenter = position + velocity.normalized * wanderDistance;
// 2. 在圆上随机一点
wanderAngle += Random.Range(-wanderAngleChange, wanderAngleChange);
Vector3 offset = new Vector3(Mathf.Cos(wanderAngle), 0, Mathf.Sin(wanderAngle)) * wanderRadius;
Vector3 target = circleCenter + offset;
return Seek(target);
}
7. Boids三规则(群体行为,鸟群/人群)
Separation 分离(避免互相挤压)
Vector3 Separation(List<Agent> neighbors, float separationRange)
{
Vector3 steer = Vector3.zero;
int count = 0;
foreach(var neighbor in neighbors)
{
float dist = Vector3.Distance(position, neighbor.position);
if(dist > 0 && dist < separationRange)
{
// 距离越近排斥力越大
Vector3 away = position - neighbor.position;
away /= dist;
steer += away;
count++;
}
}
if(count > 0)
{
steer /= count;
steer.Normalize();
steer *= maxSpeed;
steer -= velocity;
}
return steer;
}
Cohesion 凝聚(向群体中心靠拢)
Vector3 Cohesion(List<Agent> neighbors, float cohesionRange)
{
Vector3 center = Vector3.zero;
int count = 0;
foreach(var neighbor in neighbors)
{
float dist = Vector3.Distance(position, neighbor.position);
if(dist < cohesionRange)
{
center += neighbor.position;
count++;
}
}
if(count == 0) return Vector3.zero;
center /= count;
return Seek(center);
}
Alignment 对齐(和同伴运动方向保持一致)
Vector3 Alignment(List<Agent> neighbors, float alignRange)
{
Vector3 avgVel = Vector3.zero;
int count = 0;
foreach(var neighbor in neighbors)
{
float dist = Vector3.Distance(position, neighbor.position);
if(dist < alignRange)
{
avgVel += neighbor.velocity;
count++;
}
}
if(count == 0) return Vector3.zero;
avgVel /= count;
avgVel.Normalize();
avgVel *= maxSpeed;
return avgVel - velocity;
}
鸟群最终转向力 = Separationw1 + Cohesionw2 + Alignment*w3
8. Obstacle Avoidance 障碍物规避
简化思路:
- 沿自身前进方向发射探测射线
- 如果前方有障碍,生成一个侧向躲避期望速度
复杂版本需要:侧面多条探测射线,区分障碍物远近。