自律行動キャラクター
http://www.red3d.com/cwr/steer/gdc99/figure1.gif
自律行動キャラクタの論文(?)
自律行動ロジックにおける3つの層
アクションの選択
パス検索とか。どこに向かうかを決定する層
ステアリング
前に進むとか、右へ曲がるとか、どう動くかを決める層
運動
足を動かすとか、タイヤを回すとか、動くにはどうするかを決める層
ウーバーイーツで、配達先の決定(アクション選択)と運転手(ステアリング)と運転する乗り物は相互に関連しない。というような話(論文ではカウボーイがどうのこうの)
運動
このモデルにおけるシミュレーションの手順
ステアリングロジックによりステアリング方向を計算する
ステアリング方向の(力の)大きさをmax_forceまで切り詰めて、ステアリング力とする
加速度 = ステアリング力 / 質量
速度 + 加速度の大きさをmax_speedまで切り詰めて、速度とする
位置 = 位置 + 速度
こんな感じで実装してみる
code:js
class BOID {
constructor(){
this.mass = 1; // 質量スカラー(kg)
this.position = new THREE.Vector2(); // 位置ベクトル
this.velocity = new THREE.Vector2(); // 速度ベクトル
this.MAX_FORCE = 10;
this.MAX_SPEED = 10;
this.direction = 0; // 向き、右が前 (3Dだとクォータニオン、2Dだと方位角)
}
update(){
this._move(new THREE.Vector2(0.01, 0.01));
this._rotate();
}
_move(force){
const fixed_force = force.clampLength(0, this.MAX_FORCE);
const acc = fixed_force.divideScalar(this.mass);
this.velocity.add(acc).clampLength(0, this.MAX_SPEED);
this.position.add(this.velocity);
}
_rotate(){
const rad = Math.atan2(this.velocity.y, this.velocity.x);
this.direction = rad * 180 / Math.PI;
}
}
ステアリング
Seek, Flee
ターゲットに向かうか離れるかする動き。
http://www.red3d.com/cwr/steer/gdc99/figure3.gif
code:seek
desired_velocity = normalize(現在地 - ターゲット) * max_speed
ステアリング方向 = desired_velocity - 速度
desired_velocityを逆にすれば離れる動き
Pursuit, Evasion
移動方向を予測するバージョン
Wander
ランダム軌道
https://gyazo.com/84662bcf5b31a6b37cb5c9c70c8116b5
code:js
let sec = time_sec * 0.1; // 軌道変換の頻度(周波数)
let random = Simplex.noise2D(boid.userData.id, sec); // -1 ~ 1
let maxRad = Math.PI * 1; // -180 ~ 180
let rad = random * maxRad;
let speed = (Simplex.noise2D(sec, boid.userData.id) + 1 ) * 0.5 * MAX_SPEED; // 0 ~ MAX_SPEED
let dir = new THREE.Vector3( Math.cos(rad), 0, Math.sin(rad) );
dir = dir.multiplyScalar(speed);
dir = dir.sub(boid.userData.velocity); // 速度を加速度に変換
return dir;