// ----------------------------------------------------
        #region // Public Methods

        public MainRoutineSystem(ConstructorParam param)
        {
            this._barrageParamPtr = param.BarrageParamPtr;
            this._enemyParams     = param.EnemyParams;
        }
Пример #2
0
        // ----------------------------------------------------
        #region // Public Methods

        public ECSManager(LookSettings lookSettings, Collider2DSettings collider2DSettings, EnemySettings enemySettings, GameStatus gameStatus)
        {
            // 各種ScriptableObjectの参照を保持
            this._lookSettings       = lookSettings;
            this._collider2DSettings = collider2DSettings;
            this._enemySettings      = enemySettings;

            // ComponentSystem(JobComponentSystem)にパラメータを渡すために一部の設定データはポインタとして持つ
            {
                // 弾幕設定のポインタを取得
                var barrageParamSize = UnsafeUtility.SizeOf <BarrageParam>();
                this._barrageParamPtr = (BarrageParam *)UnsafeUtility.Malloc(barrageParamSize, UnsafeUtility.AlignOf <BarrageParam>(), Allocator.Persistent);
                UnsafeUtility.MemClear(this._barrageParamPtr, barrageParamSize);
                UnsafeUtility.CopyStructureToPtr <BarrageParam>(ref this._enemySettings.Barrage, this._barrageParamPtr);

                // 敵情報をNativeArrayに格納
                var enemyParamsSource = this._enemySettings.EnemyParams;
                this._enemyParams = new NativeArray <EnemyParam>(enemyParamsSource.Length, Allocator.Persistent);
                this._enemyParams.CopyFrom(enemyParamsSource);
            }

#if SYNC_BARRAGE_PARAM
            // シンボル有効時は毎フレーム構造体の値をポインタにコピーして常時反映されるようにする
            this._debugEveryUpdate = Observable.EveryUpdate().Subscribe(_ =>
            {
                UnsafeUtility.CopyStructureToPtr <BarrageParam>(ref this._enemySettings.Barrage, this._barrageParamPtr);
                this._enemyParams.CopyFrom(this._enemySettings.EnemyParams);
            });
#endif

            // World Settings
            World.Active        = new World(Constants.WorldName);
            this._entityManager = World.Active.CreateManager <EntityManager>();
            World.Active.CreateManager(typeof(TransformBarrierSystem));
            World.Active.CreateManager(typeof(DestroyBarrier));
            World.Active.CreateManager(typeof(DestroySystem));
            // ※ポインタを直接object型にはキャスト出来ないので、遠回りでは有るが一つ構造体に挟んで渡す
            var mainRoutineSystem = World.Active.CreateManager <MainRoutineSystem>(
                new MainRoutineSystem.ConstructorParam {
                BarrageParamPtr = this._barrageParamPtr, EnemyParams = this._enemyParams
            });
            World.Active.CreateManager(typeof(Transform2DSystem));
            World.Active.CreateManager(typeof(Collider2DUpdate));
            this._collision2DSystem = World.Active.CreateManager <Collision2DSystem>(gameStatus);
            World.Active.CreateManager(typeof(RenderingSystemBootstrap));
#if ENABLE_DEBUG
            World.Active.CreateManager(typeof(DebugUtility.DrawCollider2DSystem));
#endif
            ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.Active);

            // 敵の最大数
            var maxEnemyNum = this._lookSettings.EnemyLooks.Length;

            // MeshInstanceRendererの生成
            // SpriteをMeshに変換する形で持たせる
            this._enemyLooks = new MeshInstanceRenderer[maxEnemyNum];
            for (int i = 0; i < this._enemyLooks.Length; i++)
            {
                this._enemyLooks[i] = SpriteUtility.CreateMeshInstanceRenderer(this._lookSettings.EnemyLooks[i]);
            }
            this._playerBulletLook = SpriteUtility.CreateMeshInstanceRenderer(this._lookSettings.PlayerBulletLook);
            this._enemyBulletLook  = SpriteUtility.CreateMeshInstanceRenderer(this._lookSettings.EnemyBulletLook);

            // コリジョンとなる球体形状の半径と位置のオフセット
            var radiusSettings = this._collider2DSettings.Radius;
            var offsetSettings = this._collider2DSettings.Offset;

            // Create Entity Prefabs
            // ※Prefabベースでの生成を想定しているのでArchetypeは保存しない
            {
                // Player Bullet
                var playerBulletArchetype = this._entityManager.CreateArchetype(
                    ComponentType.Create <BulletTag>(), ComponentType.Create <PlayerTag>(),
                    ComponentType.Create <BulletData>(),
                    // 衝突判定、破棄可能
                    ComponentType.Create <SphereCollider2D>(), ComponentType.Create <Destroyable>(),
                    // Transform
                    ComponentType.Create <Position2D>(),
                    // Built-in ComponentData
                    ComponentType.Create <Prefab>(), ComponentType.Create <LocalToWorld>(), ComponentType.Create <MeshInstanceRenderer>());
                this._playerBulletPrefab = this._entityManager.CreateEntity(playerBulletArchetype);
                this._entityManager.SetComponentData(
                    this._playerBulletPrefab,
                    new SphereCollider2D {
                    Radius = radiusSettings.PlayerBullet, OffsetPosition = offsetSettings.PlayerBullet
                });
                this._entityManager.SetSharedComponentData(this._playerBulletPrefab, this._playerBulletLook);

                // Enemy Bullet
                var enemyBulletArchetype = this._entityManager.CreateArchetype(
                    ComponentType.Create <BulletTag>(), ComponentType.Create <EnemyTag>(),
                    ComponentType.Create <BulletData>(),
                    // 衝突判定、破棄可能
                    ComponentType.Create <SphereCollider2D>(), ComponentType.Create <Destroyable>(),
                    // Transform
                    ComponentType.Create <Position2D>(),
                    // Built-in ComponentData
                    ComponentType.Create <Prefab>(), ComponentType.Create <LocalToWorld>(), ComponentType.Create <MeshInstanceRenderer>());
                this._enemyBulletPrefab = this._entityManager.CreateEntity(enemyBulletArchetype);
                this._entityManager.SetComponentData(
                    this._enemyBulletPrefab,
                    new SphereCollider2D {
                    Radius = radiusSettings.EnemyBullet, OffsetPosition = offsetSettings.EnemyBullet
                });
                this._entityManager.SetSharedComponentData(this._enemyBulletPrefab, this._enemyBulletLook);
            }

            this._enemyPrefabs = new Entity[maxEnemyNum];
            {
                // Enemy Prefab
                var enemyArchetype = this._entityManager.CreateArchetype(
                    ComponentType.Create <EnemyTag>(),
                    ComponentType.Create <EnemyData>(),
                    // 衝突判定、破棄可能
                    ComponentType.Create <SphereCollider2D>(), ComponentType.Create <Destroyable>(),
                    // Transform
                    ComponentType.Create <Position2D>(),
                    // Built-in ComponentData
                    ComponentType.Create <Prefab>(), ComponentType.Create <LocalToWorld>(), ComponentType.Create <MeshInstanceRenderer>());
                for (int i = 0; i < this._enemyLooks.Length; i++)
                {
                    var prefab = this._entityManager.CreateEntity(enemyArchetype);
                    this._entityManager.SetComponentData(
                        prefab,
                        new SphereCollider2D {
                        Radius = radiusSettings.Enemy, OffsetPosition = offsetSettings.Enemy
                    });
                    this._entityManager.SetSharedComponentData(prefab, this._enemyLooks[i]);
                    this._enemyPrefabs[i] = prefab;
                }
            }

            {
                // Player prefab
                var playerArchetype = this._entityManager.CreateArchetype(
                    ComponentType.Create <PlayerTag>(),
                    ComponentType.Create <PlayerStatus>(),
                    // 衝突判定、破棄可能
                    ComponentType.Create <SphereCollider2D>(), ComponentType.Create <Destroyable>(),
                    // Transform
                    ComponentType.Create <Position2D>(),
                    // Built-in ComponentData
                    ComponentType.Create <Prefab>());
                this._playerPrefab = this._entityManager.CreateEntity(playerArchetype);
                this._entityManager.SetComponentData(
                    this._playerPrefab,
                    new SphereCollider2D {
                    Radius = radiusSettings.Player, OffsetPosition = offsetSettings.Player
                });
            }

            {
                // Generate Events
                // ※生成通知は生成したらその場で破棄するのでDestroyableは付けない
                var playerBulletGenerateArchetype = this._entityManager.CreateArchetype(
                    ComponentType.Create <PlayerBulletGenerate>(),
                    ComponentType.Create <BulletData>(),
                    ComponentType.Create <Prefab>());
                this._playerBulletGeneratePrefab = this._entityManager.CreateEntity(playerBulletGenerateArchetype);

                var enemyGenerateArchetype = this._entityManager.CreateArchetype(
                    ComponentType.Create <EnemyGenerate>(),
                    ComponentType.Create <EnemyData>(),
                    ComponentType.Create <Prefab>());
                this._enemyGeneratePrefab = this._entityManager.CreateEntity(enemyGenerateArchetype);
            }

            // ComponentSystem内でEntityの生成を行うSystemに対し、Prefabを渡す。
            // HACK: 渡し方が若干力技感あるのでなんとかしたい..
            mainRoutineSystem.SetPrefabEntities(new MainRoutineSystem.PrefabEntities
            {
                PlayerBulletPrefab = this._playerBulletPrefab,
                EnemyBulletPrefab  = this._enemyBulletPrefab,
                EnemyPrefabs       = this._enemyPrefabs,
            });
        }