Birds and Unity3D、最適化の試み

Unity3Dでの鳥の作成に関する投稿を読んだ後、最適化オプションを提供することにしました。



Unityでは、各オブジェクトにスクリプトを配置するのは良くありません。特にそれらが多数ある場合、強い遅れが現れます。 スクリプトをハングさせないために、Boid.csは異なる方法で実行できます。



クラスBoidを作成します。



public class Boid { public Vector3 velocity; public Vector3 position;//     private float cohesionRadius = 10; private float separationDistance = 5; private Boid[] boids; private Vector3 cohesion; private Vector3 separation; private int separationCount; private Vector3 alignment; private float maxSpeed = 15; public Boid(Vector3 pos) { position = pos; } }
      
      





このクラスでは、すべての計算が行われます。 ゲームオブジェクトから独立させるには、Physics.OverlapSphere関数を置き換える必要があります。

  public static Boid[] boids; static public Boid[] Sphere(Vector3 position, float radius) { List<Boid> mids = new List<Boid>(); for (int i = 0; i < boids.Length; i++) { if (Vector3.Distance(position, boids[i].position) < radius) mids.Add(boids[i]); } return mids.ToArray(); }
      
      





この関数は別のクラスにあります。

これで、計算関数自体を追加できます。

 public void CalculateVelocity() { Vector3 newVelocity = Vector3.zero; cohesion = Vector3.zero; separation = Vector3.zero; separationCount = 0; alignment = Vector3.zero; boids = Boids.Sphere(position, cohesionRadius); //    Physics.OverlapSphere   foreach (Boid boid in boids) { alignment += boid.velocity;//       cohesion += boid.position;//    Transfom if (boid != this && (position - boid.position).magnitude < separationDistance) { separation += (position - boid.position) / (position - boid.position).magnitude; separationCount++; } } cohesion = cohesion / boids.Length; cohesion = cohesion - position; cohesion = Vector3.ClampMagnitude(cohesion, maxSpeed); if (separationCount > 0) separation = separation / separationCount; separation = Vector3.ClampMagnitude(separation, maxSpeed); alignment = alignment / boids.Length; alignment = Vector3.ClampMagnitude(alignment, maxSpeed); newVelocity += cohesion * 0.5f + separation * 15f + alignment * 1.5f; newVelocity = Vector3.ClampMagnitude(newVelocity, maxSpeed); velocity = (velocity * 2f + newVelocity) / 3f;//     if (position.magnitude > 40) { velocity += -position.normalized; } }
      
      





この関数で速度を取得します。 次に、鳥を移動する必要があります。そのために、更新機能を追加します。

 public void Update() { position += velocity * Time.deltaTime; Debug.DrawRay(position, separation, Color.green);//       Debug.DrawRay(position, cohesion, Color.magenta); Debug.DrawRay(position, alignment, Color.blue); }
      
      





これで、Boidクラスが完成しました。

ここで、どのように鳥を表示する必要があります。

これを行うために、ステージ上で移動したプリミティブの配列を作成しました。 これはすべてBoids.csスクリプトで行われました。

 using UnityEngine; using System.Collections; using System.Collections.Generic; public class Boids : MonoBehaviour { GameObject[] boidsObjects; // Use this for initialization void Start () { boidsObjects = new GameObject[1500];// 1500  boids = new Boid[boidsObjects.Length]; for (int i = 0; i < boids.Length; i++) { GameObject boid = GameObject.CreatePrimitive(PrimitiveType.Cube);//   boid.transform.position = Random.insideUnitSphere * 35f; Destroy(boid.collider);//     boidsObjects[i] = boid; boids[i] = new Boid(boid.transform.position);//  Boid } StartCoroutine(UpdatePhis());// InvokeRepeating    } IEnumerator UpdatePhis() { while (true) { int UpdateCount = 0; for (int i = 0; i < boids.Length; i++) { boids[i].CalculateVelocity(); UpdateCount++; if (UpdateCount > 100)//   fps      { yield return null; UpdateCount = 0; } } } } // Update is called once per frame void Update () { for (int i = 0; i < boids.Length; i++) { boids[i].Update();//  boidsObjects[i].transform.position = boids[i].position; } } //    OverlapSphere public static Boid[] boids; static public Boid[] Sphere(Vector3 position, float radius) { List<Boid> mids = new List<Boid>(); for (int i = 0; i < boids.Length; i++) { if (Vector3.Distance(position, boids[i].position) < radius) mids.Add(boids[i]); } return mids.ToArray(); } }
      
      





Boids.csをカメラに掛けて起動します。 1,500羽の鳥では、コンピューターで70 fpsを取得しました。

WebPlayer: こちら

コード: ダウンロード



All Articles