BOIDアルゴリズム
魚群シミュレーション。のようなもの
3種類のアルゴリズムで行動パターンを決定する
速度じゃなくて加速度まで考慮した方が動きが綺麗な気がする
グループで見るより視界を定義して、その中に入った相手を見るのが良いかも
BOID以外の行動基準を持たせる必要もありそう
参考資料
https://youtu.be/mhjuuHl6qHM
基本的な3要素
離散(Separation)
code:cs
Vector3 Separation(self, boids) {
var separation_sensitive = 21f;
var acceleration = Vector3.zero;
foreach( boid in boids) {
if(boid == self) continue;
var distance = self.position - boid.position;
var acceleration += separation_sensitive * distance / distance.sqrtMagnitude;
}
return Vector3.ClampMagnitude(acceleration, 1f);
}
仲間たちから離れる方向へすすむ
ただし、仲間との距離が遠いなら、影響力を弱くする。そのための distance / dinstance.sqrtMagnitude
separation_sensitiveでどれくらい近づいたらブレーキかけるかを調整する。
適当な値は探るしかないのが微妙
$ 1/xと$ x/x^2 が同じグラフなので、スカラーかベクトルかで使い分けるのがコツ
整列
code:cs
Vector3 Alignment(self, boids) {
var sum_of_velocity = Vector3.zero;
foreach( boid in boids ) {
if(boid == self) continue;
sum_of_velocity += boid.velocity
}
return sum_of_velocity.normalized;
}
仲間の進んでる方向へすすむ
「速度」を見て「加速度」を作ってるので、単位に注意
結合
code:cs
Vector3 Cohesion(self, boids) {
var sum_of_position = Vector3.zero;
foreach( boid in boids ) {
if(boid == self) continue;
sum_of_position += boid.position;
}
return (sum_of_position - self.position).normalized;
}
仲間の居る方向へすすむ
「場所」を見て「加速度」を作ってるので、単位に注意
その他動作のヒント
特定の点と一定の距離を取る
code:cs
Vector3 Turn(Vector3 position, Vector3 centerPosition)
{
// 中心点との線分に直角
var distance = startPosition - position;
var distanceCross = new Vector3(distance.z, 0, -distance.x);
// 中心へ向かうベクトルを追加して、離れすぎるのを防ぐ
var toCenter = distance * distance.sqrMagnitude * 0.0005f; // この数字はグラフ見ながら調整
return (distanceCross + toCenter).normalized;
}
急旋回を抑える
code:cs
Vector3 AccelerateToGliding(Rigidbody rigidbody, Vector3 accelerate)
{
// 急旋回を抑える
var velocity = rigidbody.velocity;
velocity.y = 0f;
velocity = velocity.normalized;
var dot = Vector3.Dot(velocity, accelerate.normalized); // 正規化した値を使う事で、値域を-1~1に
var fixedDot = 1f - ((dot + 1f) * 0.5f); // -1~1を 0~1に
return velocity * fixedDot;
}