100体でも1000体でもいいのですが、とりあえず物体を大量に動かしたかった。
未来の自分のために ソースコード完全コピペで動かせる のを目指しました。
・環境
Unity 2019.1.11f
ECS : preview 0.1.0
※LWRPで検証
PakcageManager
Entities と HybridRenderer をインストール
ComponentSystem 用のソースコード
スクリプト1つです。
using System.Collections; using System.Collections.Generic; using UnityEngine; using Unity.Entities; using Unity.Rendering; using Unity.Transforms; public class ZombieComponentSystem : ComponentSystem { static EntityArchetype archetype; // Entity用データ構造体 struct Zombie : IComponentData { public Quaternion rotation; } public static void CreateEntity(Vector3 position, Mesh mesh, Material mat) { // Entityを作成する var e = World.Active.EntityManager.CreateEntity(archetype); // Entityの初期値設定 // ゾンビ Zombie z = World.Active.EntityManager.GetComponentData<Zombie>(e); z.rotation = Quaternion.Euler(-90, Random.Range(-360, 360), 0); World.Active.EntityManager.SetComponentData<Zombie>(e, z); // 描画するメッシュ RenderMesh r = World.Active.EntityManager.GetSharedComponentData<RenderMesh>(e); r.mesh = mesh; r.material = mat; World.Active.EntityManager.SetSharedComponentData<RenderMesh>(e, r); // 位置(MonoBehaviourのTransformとほぼ同じ) Translation t = World.Active.EntityManager.GetComponentData<Translation>(e); t.Value = position; World.Active.EntityManager.SetComponentData<Translation>(e, t); } protected override void OnCreate() { // アーキタイプを作成 archetype = World.Active.EntityManager.CreateArchetype( typeof(Zombie), typeof(Translation), typeof(Rotation), typeof(LocalToWorld), typeof(RenderMesh)); } protected override void OnUpdate() { // !!! Rotationもクエリに入れるとエラーが出る(バグ?) Entities.WithAll<Zombie>().ForEach((Entity e, ref Zombie zombie, ref Translation translation) => { // 回転の設定 zombie.rotation = Quaternion.Euler(0, Random.Range(-10, 10) + zombie.rotation.eulerAngles.y, 0); Rotation rotation = World.Active.EntityManager.GetComponentData<Rotation>(e); rotation.Value = zombie.rotation; World.Active.EntityManager.SetComponentData<Rotation>(e, rotation); // 向いている方向に移動 Vector3 move = (zombie.rotation * Vector3.forward) * 0.1f; translation.Value = translation.Value + new Unity.Mathematics.float3(move); }); } }
シーンに置いてEntityを生成するコード
スクリプト1ツです。
描画したいメッシュとマテリアルを設定しておきます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ZombieSpawner : MonoBehaviour { [SerializeField] Mesh mesh; [SerializeField] Material mat; void Start() { for (int i = 0; i < 1000; i++) ZombieComponentSystem.CreateEntity(new Vector3(Random.Range(-20, 20), 0, Random.Range(-20, 20)), mesh, mat); } }
Entity Component System | Package Manager UI website
Struct RenderMesh | Package Manager UI website
あとアニメーションもさせたいので下記記事を参考に実装中。