土法炼钢兴趣小组的算法知识备份

游戏中的数学 (13) - 导航与行为

目录

引言

游戏 AI 的核心任务通常是:我知道我在哪,我要去哪,怎么去? 这涉及两个层面: 1. 宏观寻路: 规划一条从 A 到 B 的路径(A* 算法)。 2. 微观移动: 如何控制速度和方向来沿着路径移动,并避开障碍(操纵行为)。

1. 寻路 (Pathfinding) - A*

A* (A-Star) 是最著名的寻路算法。它结合了 Dijkstra 的广度优先搜索和贪婪最佳优先搜索。 核心公式: \[ F = G + H \]

2. 操纵行为 (Steering Behaviors)

一旦有了路径,或者在开放空间中移动,我们需要计算每一帧的力。 Craig Reynolds 在 1986 年提出了著名的 Boids 模型来模拟鸟群。

Steering Behaviors

基本公式: \[ \vec{Steering} = \vec{Desired} - \vec{Velocity} \] \[ \vec{Force} = \text{clamp}(\vec{Steering}, \text{maxForce}) \]

2.1 分离 (Separation)

“别挤我!” 检查周围邻居,计算一个背离它们的向量平均值。距离越近,斥力越大。

2.2 对齐 (Alignment)

“随大流。” 计算周围邻居的平均速度方向(Heading),并尝试转向该方向。

2.3 内聚 (Cohesion)

“别掉队。” 计算周围邻居的平均位置(Center of Mass),并尝试向该点移动。

代码实现 (Seek 行为): 这是所有操纵行为的基础。

Vector3 Seek(Vector3 target) {
    Vector3 desired = (target - position).normalized * maxSpeed;
    Vector3 steering = desired - velocity;
    return Vector3.ClampMagnitude(steering, maxForce);
}

// 在 Update 中应用
void Update() {
    Vector3 force = Seek(targetPosition);
    // 可以叠加其他力:Separation, Alignment...
    
    velocity += force * Time.deltaTime;
    velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
    position += velocity * Time.deltaTime;
    
    // 朝向速度方向
    if (velocity != Vector3.zero)
        transform.forward = velocity;
}

3. 组合行为

将上述力加权求和: \[ \vec{F}_{total} = w_1 \vec{F}_{sep} + w_2 \vec{F}_{align} + w_3 \vec{F}_{coh} + w_4 \vec{F}_{path} \] 通过调整权重,可以模拟出鱼群、鸟群甚至僵尸潮的运动模式。

总结


< 上一篇: 随机与噪声 | 回到目录


By .