Unity の Transform の読み書きは遅い
Unity のバージョンは 5.4.
Pentium G3220 のマシンで 10,000 個のオブジェクトの transform.position を更新するだけの処理(transform.position = newPos の実行)に約 14 ms かかっている. 60fps の上限が 16ms なので,Unity で 10,000 個の動くオブジェクトを出すのはほぼ不可能だ.
対処法
rigidbody.position を使う
Rigidbody がついているなら,transform.position に代入するのではなく rigidbody.position で移動するようにする. Rigidbody は GetComponent<Rigidbody>() で取得する. これを実行すると約 14ms が 約 8ms になった.
ただし物理エンジンの更新処理は遅いので,全体のフレームレートはそれがない時より落ちる. つまり Rigidbody のついてないオブジェクトに Rigidbody をつけて高速化できるわけではない.
ローカルの Position・Rotation を使う
Position・Rotation 用のメモリを自分で用意し,それを更新する;Transform は一切読み書きしない. レンダリングには Graphics.DrawMesh を使う.このときプレハブの MeshRenderer は無効にしておく. Graphics.DrawMesh 発行分の負荷は増えるが,遅い Transform にアクセスしないためトータルでのフレームレートは増加する.
約 14ms かかっていた位置更新が 約 1ms に短縮できた. ドローコールの発行に約 8ms かかっているので,トータルで 5ms の短縮になった. またトランスフォームの読み出し(次段を参照)も約 4ms から約 2ms へ短縮できている.
ComputeBuffer を使う
【Unity】Unite 2015「Rederer Massive Amount of Objects in Unity」レポート にあるように ComputeBuffer で更新することもできる.
読み出し
読み出しも書き込みほどではないが遅い.10,000 回の読み出し(var nowPos = transform.position の実行)に約 4ms かかっている. 2回以上読みだされるならローカルにキャッシュしたほうがいい.