7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PrefabからEntityを生成する方法メモ(Entities v0.8.0)

Last updated at Posted at 2020-03-23

はじめに

DOTS以前のUnityでは、


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnPrefab : MonoBehaviour {

    [SerializeField] private GameObject prefab;

    private void Start () {
        Instantiate (prefab);
    }
}

のようなスクリプトを作成し、何らかのオブジェクトにアタッチしておけば、実行時にPrefabからGameObjectが生成されていました。

これと同じことをHybrid ECSで行う工程をメモとして残しておきたいと思い、この記事を書きました。

環境

  • Unity 2019.3.6f1
  • Entities 0.8.0
  • Unity Physics 0.2.5
  • Hybrid Renderer 0.4.0

Prefabの準備

生成したいGameObjectにConvertToEntityをアタッチし、必要に応じてAuthoring、PhysicsShape、PhysicsBody等をつけた後、Prefab化します。
(旧アーキテクチャのColliderがついている場合は消しておきましょう)

必要なComponentDataの作成

using Unity.Entities;

/// <summary>
/// 生成するPrefabに対応するEntityの情報
/// </summary>
public struct SpawnerData : IComponentData
{
    public Entity PrefabEntity;
}
using Unity.Entities;

/// <summary>
/// Spawnerを識別するためのタグコンポーネント
/// </summary>
public struct Spawner : IComponentData
{
}


using Unity.Entities;

/// <summary>
/// Spawnをするタイミングを伝えるためのタグコンポーネント
/// </summary>
public struct SpawnTag : IComponentData
{
}

Spawnerオブジェクトの作成

空のゲームオブジェクトを作成し、ConvertToEntityを付けます。

SpawnerAuthoringの作成

using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;

[DisallowMultipleComponent]
[RequiresEntityConversion]
public class SpawnerAuthoring : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
{
    [SerializeField] private GameObject prefab;
    
    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        dstManager.AddComponentData(entity, new Spawner());

        dstManager.AddComponentData(entity, new SpawnerData()
        {
            PrefabEntity = conversionSystem.GetPrimaryEntity(prefab)
        });

        // 今回は簡単な例を考え、実行時にEntityを生成することにします。なのでここでSpawnTagをつけます
        dstManager.AddComponentData(entity, new SpawnTag());
    }

    public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
    {
        referencedPrefabs.Add(prefab);
    }
}

これをSpawnerオブジェクトにアタッチし、最初に作成したPrefabをエディタ上のPrefabフィールドに代入します。

SpawnSystemの作成

using Unity.Entities;

/// <summary>
/// Prefabを生成するSystem
/// </summary>
public class SpawnSystem : SystemBase
{
    private EntityCommandBufferSystem _entityCommandBufferSystem;
    
    protected override void OnCreate()
    {
        _entityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    }

    protected override void OnUpdate()
    {
        var concurrent = _entityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();
        
        Entities
            .WithBurst()
            .WithAll<SpawnTag, Spawner>()
            .ForEach(
            (Entity entity, int entityInQueryIndex, in SpawnerData spawnerData) =>
            {
                concurrent.Instantiate(entityInQueryIndex, spawnerData.PrefabEntity);

                // Entityを2つ以上生成しないために、ここでSpawnTagを剥がします
                // これをしないと、毎フレームEntityが生成されてしまうので
                concurrent.RemoveComponent<SpawnTag>(entityInQueryIndex, entity);
            }).ScheduleParallel();
        
        _entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    }
}

これで実行時にPrefabからEntityが生成されます。

ここでは、実行時にEntityを生成する簡単な場合を考えましたが、好きなタイミングでEntityを生成したい場合は、そのタイミングでSpawnTag ComponentDataをSpawnerのEntityに付ければokです。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?