Unityでパーティクルの実験

最近Unityをいじくったりしてます。
Unityの簡単な説明をすると、米Unity Technologies社製のゲームエンジンで、PCやブラウザ、iPhone等で動く3Dアプリケーションを作ることができます。GUI環境に3Dモデル等の素材を放り込んで、JavaScriptやC#でスクリプトを書くだけで(割と)簡単に動かせます。Flashを触っている方は、Flash IDEの3D版だと考えればだいたい感覚的にあってるかも。ブラウザ上でGPUアクセラレーションつきの本格的な3Dが動くこと、iPhoneの3Dゲームが比較的手軽に作れること、開発環境の制限バージョンが無料になったことなどで人気が出ているようです(残念ながらまだ日本語化されていないのですが)。ブラウザのプラグインをインストールして公式のデモを見ると、かなりのものが動くのが分かると思います。
というところで、唐突ですが、ABAさんのパーティクルテストにつられて、似たような、オブジェクトをたくさん出す実験をしてみました。
プロジェクトファイルはこちら。
おそらく個々のGameObjectがパーティクルを描画するのはGPU的に嫌だろうということで、GameObjectは座標を保持するだけにして、下のようなスクリプトでビルボード群のメッシュを毎フレーム作成してまとめて描画してみました。とりあえずCore 2 Duo/3.16GHz、RADEON 4550で10000個は出ているようです(上限を上げればもっと出るかもしれません)。UnityのJavaScriptは.NET(Mono)ベースで、C++の半分の速度は出るよとのことなんですが、確かに結構な速さはあるようです。
function LateUpdate()
{
var particles = GameObject.FindGameObjectsWithTag("Particle");
...
var i = 0;
var size = 0.5;
for (var particle in particles) {
var position = particle.transform.position;
vertices[i++] = Vector3(position.x - size, position.y - size, position.z);
vertices[i++] = Vector3(position.x - size, position.y + size, position.z);
vertices[i++] = Vector3(position.x + size, position.y + size, position.z);
vertices[i++] = Vector3(position.x + size, position.y - size, position.z);
}
...
var mesh = GetComponent(MeshFilter).mesh;
mesh.Clear();
mesh.vertices = vertices;
mesh.colors = colors;
mesh.uv = uv;
mesh.triangles = triangles;
}
まあ、パーティクルを多数出すだけならUnity組み込みのパーティクルシステムを使えばいいんですが、シューティングの敵弾などで自前でやる必要が出てくることもあるかなと。
ちなみにUnityのいいところは、開発環境がそのまま実行・デバッグ環境になることですね。下の画面のように、実行中に視点を動かして、描画が正しく行われているか確認したりというのが、何の苦労もなくできます。
Unityというプラットフォームがどんな感じかについてはまた後ほど(たぶん)。

