ã¯ããã«
ã©ãããåéã§ãã
ååã«å¼ãç¶ããé½å¸éçºã·ãã¥ã¬ã¼ã·ã§ã³ã²ã¼ã ãUnityECSã§å®è£ ãã¦ãããã¨æãã¾ãã
ååãæ¸ãã¾ããããç¾ç¶ææ¢ãã§è¨äºãæ¸ãã¦ããã®ã§ãããè¯ãå®è£ ãã§ã次第ãè¨äºãæ´æ°ãã¦ããã¾ãã
ååã®è¨äºã¯ãã¡ã
åºãä½ã
ä»åã¯ä½æ°ã訪ããåºãªã©ã®å»ºç©ãä½ã£ã¦ãä½æ°ããã®å»ºç©ã«ç§»åããããã«ãã¦ã¿ã¾ãã
建ç©ã®Entityãä½ã
ã³ã¼ãã®æ¸ãæ¹ã«é¢ãã¦ã¯åååæ§ãªã®ã§èª¬æã¯çç¥ãã¾ãã
Component
using Unity.Entities; using UnityEngine; namespace Building { [System.Serializable] public struct BuildingBase : IComponentData { public BuildingType buildingType; // 建ç©ã®ã¿ã¤ã public int numberEmployee; // å¾æ¥å¡æ° } }
Baker
using Unity.Entities; using UnityEngine; namespace Building { public class BuildingAuthoring : MonoBehaviour { [SerializeField] private BuildingType _buildingType; [SerializeField] private int _numberEmployee; class Baker : Baker<BuildingAuthoring> { public override void Bake(BuildingAuthoring src) { var data = new BuildingBase() { buildingType = src._buildingType, numberEmployee = src._numberEmployee }; AddComponent(GetEntity(TransformUsageFlags.Dynamic),data); } } } }
ã·ã¹ãã ã¯å¾æ¥è¿½å äºå®ã
ä½æ°ãç®çå°ãè¨å®ãã¦è¨ªåããããã«
ååä½ã£ãä½æ°ã®Systemã«ä¸çªè¿ã建ç©ã«åããã³ã¼ãã追å ãã¦ã¿ã¾ãã
using Building; using Unity.Burst; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; using UnityEngine; namespace Citizen { public partial struct CitizenSystem : ISystem { private EntityQuery _buildingQuery; [BurstCompile] public void OnCreate(ref SystemState state) { _buildingQuery = state.GetEntityQuery(typeof(LocalTransform), typeof(BuildingBase)); } [BurstCompile] public void OnUpdate(ref SystemState state) { // Jobã®çºè¡å¦ç var job = new CitizenUpdateJob() { Elapsed = (float)SystemAPI.Time.ElapsedTime, buildingsTransforms = _buildingQuery.ToComponentDataArray<LocalTransform>(Allocator.TempJob) }; // åæå job.ScheduleParallel(); // Jobã®äºç´ } } [BurstCompile] partial struct CitizenUpdateJob : IJobEntity { public float Elapsed; // çµéæé public NativeArray<LocalTransform> buildingsTransforms; // å ¨å»ºç© private bool _isNowDestination; void Execute(ref CitizenBase citizen, ref LocalTransform transform) { LocalTransform closestBuildingTransform = default; float minDistanceSq = float.MaxValue; // å建ç©ã®ä½ç½®ã¨ä½æ°ã®ä½ç½®ãæ¯è¼ãã¦æãè¿ããã®ãæ¢ã foreach (var buildingTransform in buildingsTransforms) { float distanceSq = math.distancesq(buildingTransform.Position, transform.Position); if (distanceSq < minDistanceSq) { minDistanceSq = distanceSq; closestBuildingTransform = buildingTransform; } } citizen.destination = closestBuildingTransform.Position; Move(citizen, ref transform); } void Move(CitizenBase citizen, ref LocalTransform transform) { // ç¾å¨ä½ç½®ããç®çå°ã«åãã£ã¦ä¸å®ã®ã¹ãã¼ãã§ç§»å transform.Position = Vector3.MoveTowards(transform.Position, citizen.destination, citizen.moveSpeed * Elapsed); // ç®çå°ã«å°éãããã©ããã®ãã§ã㯠if (Vector3.Distance(transform.Position, citizen.destination) < 0.01f) { Debug.Log("ç®çå°ã«å°éãã¾ããï¼"); _isNowDestination = true; } else { _isNowDestination = false; } } } }
ã³ã¼ãã®è§£èª¬
private EntityQuery _buildingQuery; [BurstCompile] public void OnCreate(ref SystemState state) { _buildingQuery = state.GetEntityQuery(typeof(LocalTransform), typeof(BuildingBase)); }
OnCreateã¡ã½ããã¯ããããUnityå¾æ¥ã®Startã«ãããã¡ã½ããã§Entityçææã«å®è¡ãããã¤ã¡ã¼ã¸ã§ãã
ãã®é¨åã§BuildingBaseãæã¤Entityã®Queryãåå¾ãã¦ãã¾ãã
buildingsTransforms = _buildingQuery.ToComponentDataArray<LocalTransform>(Allocator.TempJob)
CitizenUpdateJobã®NativeArray
ãããããã¨ã§CitizenUpdateJobå
ã§ä½æ°ãããã£ã¨ãè¿ã建ç©ãåå¾ãã¦ç§»åããããã«ã§ãã¾ãã
æ£ç´ãå®è£ ã¨ãã¦å¾®å¦ãªæ°ã¯ãã¦ããã®ã§ãå¾æ¥æ¸ãç´ãã¾ãã