public void Execute(Entity entity, int index, [ReadOnly] ref Translation translation) { float3 Cube_Pos = translation.Value; float3 closestTargetPosition = float3.zero; Entity Target = Entity.Null; //Debug.Log("搜尋"); for (int i = 0; i < targetarray.Length; i++) { EntityJobArray targetentityJobArray = targetarray[i]; if (Target == Entity.Null) { // No target Target = targetentityJobArray.entity; closestTargetPosition = targetentityJobArray.position; } else { if (math.distance(Cube_Pos, targetentityJobArray.position) < math.distance(Cube_Pos, closestTargetPosition)) { // This target is closer Target = targetentityJobArray.entity; closestTargetPosition = targetentityJobArray.position; } } } //這邊也跟第一種不一樣,將陣列保存目標Entity的數據 TargetEntityArray[index] = Target; }
public void Execute(Entity entity, int index, [ReadOnly] ref Translation translation) { float3 Cube_Pos = translation.Value; float3 closestTargetPosition = float3.zero; Entity Target = Entity.Null; //Debug.Log("搜尋"); for (int i = 0; i < targetarray.Length; i++) { EntityJobArray targetentityJobArray = targetarray[i]; if (Target == Entity.Null) { Target = targetentityJobArray.entity; closestTargetPosition = targetentityJobArray.position; } else { if (math.distance(Cube_Pos, targetentityJobArray.position) < math.distance(Cube_Pos, closestTargetPosition)) { Target = targetentityJobArray.entity; closestTargetPosition = targetentityJobArray.position; } } } //放入敵人數據 if (Target != Entity.Null) { //EntityCommandBuffer實體命令緩衝 //使用了這個是無法使用BurstCompile entityCommandBuffer.AddComponent(index, entity, new Cube_Look_Target { targetEntity = Target }); } }
protected override JobHandle OnUpdate(JobHandle inputDeps) { bool JobAdd = GameHander_test.GameHander_test_ins.JobAddComponent; bool JobEnabled = GameHander_test.GameHander_test_ins.JobBool; //Debug.Log(JobAdd); //共通部分,為了拿到目標物的Entity //因為Job中無法訪問世界所以要先訪問佇列 //這句意思就是找有Ball_Target組件 並有Translation組件 EntityQuery targetQuery = GetEntityQuery(typeof(Ball_Target), ComponentType.ReadOnly <Translation>()); //轉成陣列 NativeArray <Entity> targetEntityArray = targetQuery.ToEntityArray(Allocator.TempJob); NativeArray <Translation> targetTranslationArray = targetQuery.ToComponentDataArray <Translation>(Allocator.TempJob); //轉換完,這是目標圓球陣列 NativeArray <EntityJobArray> targetArray = new NativeArray <EntityJobArray>(targetEntityArray.Length, Allocator.TempJob); //輸入資料 for (int i = 0; i < targetEntityArray.Length; i++) { targetArray[i] = new EntityJobArray { entity = targetEntityArray[i], position = targetTranslationArray[i].Value, }; } //釋放陣列 targetEntityArray.Dispose(); targetTranslationArray.Dispose(); JobHandle jobHandle; //共通結束 //是否啟動JobSystem還是ComponentSystem if (JobEnabled == true) { //啟動JobSystem if (JobAdd == false) { //第一種作法 FindTargetJobSystem_No1 findTargetJobSystem_No1 = new FindTargetJobSystem_No1 { targetarray = targetArray, entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent() }; jobHandle = findTargetJobSystem_No1.Schedule(this, inputDeps); } else { //第二種作法 //這句意思就是找有Cube_Unit組件 並排除Ball_Target組件 EntityQuery unitQuery = GetEntityQuery(typeof(Cube_Unit), ComponentType.Exclude <Ball_Target>()); NativeArray <Entity> closestTargetEntityArray = new NativeArray <Entity>(unitQuery.CalculateEntityCount(), Allocator.TempJob); FindTargetJobSystem_No2 findTargetJobSystem_No2 = new FindTargetJobSystem_No2 { targetarray = targetArray, TargetEntityArray = closestTargetEntityArray }; jobHandle = findTargetJobSystem_No2.Schedule(this, inputDeps); AddComponentJob addComponentJob = new AddComponentJob { TargetEntityArray = closestTargetEntityArray, entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(), }; jobHandle = addComponentJob.Schedule(this, jobHandle); } } else { //啟動ComponentSystem但JobSystem不能return空,所以用一空Job賦值 FindTargetJobSystem_Null findTargetJobSystem_Null = new FindTargetJobSystem_Null { }; jobHandle = findTargetJobSystem_Null.Schedule(this, inputDeps); } // 備註 //從作業寫入命令緩衝區時,必須添加 //通過調用此函數將該Job映射到此緩衝區系統的依賴項列表。 //否則,當寫入作業仍在進行時,緩衝區系統可以執行命令緩衝區中當前的命令。 //以上Unity官方 //每當將命令緩衝區傳遞給系統時,您都需要將作業句柄返回到擁有命令緩衝區的系統(您可以簡單地將其返回到系統末尾傳遞最終的作業句柄。) //這是確保作業的必需條件在屏障系統運行之前,已完成使用命令緩衝區的操作。 //以上Unity論壇 //大致理解,就是為了保護,避免內存出意外,所以擁有EntityCommandBuffer的Job都必須加上這句,放在末尾 endSimulationEntityCommandBufferSystem.AddJobHandleForProducer(jobHandle); return(jobHandle); }