Tiny Unity (Unity Tiny Mode)のベンチマークを書いてみた

# 目的

こちらの各HTML5ゲームエンジンの比較がよくまとまっています
https://cloud.tencent.com/developer/article/1075163

このベンチマークと同じものを動かしてみたいと思いTiny Unityでプロジェクトを作り動かしてみました

# 流れ

こちらの記事の通りまずは環境を構築してみました
https://qiita.com/motoyasu-yamada/items/90ed5d5b61cdf639fc82

# プロジェクトの構成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/4a6334e6-51f5-92b8-f67a-38a7403daa40.png)

`Entities`に起動用の`Scene`EntityGroupを作成しました

動的に生成する`Entity`を配置する`Image`EntityGroupを作成し、その中に`Image`Entityを作成しました
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/6d5e95db-947d-dcb7-0565-245809bd3a69.png)

次に、動的に生成＆アニメーションするエンティティを識別するために`ImageTag`コンポーネントを作成します。

これはタグ用のコンポーネントなので特にフィールドの設定はしません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/7b27bfca-23d0-1774-8916-6ecaac7a66c6.png)


インスペクターから、`Image`エンティティに、表示用のテクスチャを設定します。
さらに、先ほど作成した`ImageTag`を追加してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/302078/214d935e-3063-94f0-9a04-92ded470c4cf.png)

# ソースコード
`AnimationSystem`と`SpawnSystem`を作成します。

オブジェクトを生成するSpawnSystemは起動後一回だけ実行したいのですが、やり方が不明なため`inited`フラグで管理しています。

```ts
namespace game {

    @ut.executeAfter(ut.Shared.UserCodeStart)
    @ut.executeBefore(ut.Shared.UserCodeEnd)
    export class SpawnerSystem extends ut.ComponentSystem {
        private static inited: boolean = false;
        private static NUMBER_OF_SPAWN : number = 10000;

        OnUpdate():void {
            if (SpawnerSystem.inited) {
                return;
            }

            for (let i:number=0; i < SpawnerSystem.NUMBER_OF_SPAWN; i++) {
                const x = Math.random() * 8 - 4;
                const y = Math.random() * 6 - 3;

                const e = ut.EntityGroup.instantiate(this.world, "game.Image")[0];
                this.world.usingComponentData(e, [ut.Core2D.TransformLocalPosition,ut.Core2D.TransformLocalScale], (p,s) => 
                {
                    p.position.x = x;
                    p.position.y = y;
                });
            }

            SpawnerSystem.inited = true;
        }
    }
}
```


`this.world.forEach`の第一引数で処理したいエンティティを絞り込むためにコンポーネントを指定します。ここで`ImageTag`コンポーネントをはったエンティティだけをアニメーションさせます。

```ts:AnimationSystem.ts
namespace game {

    @ut.executeAfter(ut.Shared.UserCodeStart)
    @ut.executeBefore(ut.Shared.UserCodeEnd)
    export class AnimationSystem extends ut.ComponentSystem  {     
        static framesForFpsCount : number = 0;
        static timeForFpsCount : number = 0;
        static rotationPerFrame : Quaternion = new Quaternion();

        constructor() {
            super();
            AnimationSystem.rotationPerFrame.setFromAxisAngle(new Vector3(0,0,1),0.1);
        }

        OnUpdate():void {
            AnimationSystem.timeForFpsCount += this.scheduler.deltaTime();
            AnimationSystem.framesForFpsCount++;
            if (AnimationSystem.framesForFpsCount % 100 === 0) {
                console.log(AnimationSystem.framesForFpsCount / AnimationSystem.timeForFpsCount, AnimationSystem.framesForFpsCount,AnimationSystem.timeForFpsCount);
            }

            this.world.forEach([ut.Core2D.TransformLocalRotation, game.ImageTag],(rotation,tag) => {
                rotation.rotation = rotation.rotation.multiply(AnimationSystem.rotationPerFrame);
            });
        }
    }
}
```

# まとめ

あくまでも手元のパソコン(X280 / Chrome)でのテストですが、TinyUnityは5FPSですがEgretEngineは60FPS近く安定してでます。


ソースコードはこちらから
https://github.com/motoyasu-yamada/HTML5-Benchmark-201812/tree/master/TinyUnity