protected override void OnUpdate() { //Debug.Log("On StateEvent Update"); //Create parallel writer NativeQueue <AnimationInfo> .ParallelWriter animationEvents = EventsHolder.AnimationEvents.AsParallelWriter(); ComponentDataContainer <AnimationData> animatedEntities = new ComponentDataContainer <AnimationData> { Components = GetComponentDataFromEntity <AnimationData>() }; ReadOnlyList <StateInfo> stateEvents = new ReadOnlyList <StateInfo>() { List = EventsHolder.StateEvents }; //Should work, but might be slow because lots of foreach lolololololololol Entities.ForEach((Entity e, DynamicBuffer <DynamicAnimator> dynamicAnimator, ref StateComponent component, in TypeData type) => { NativeList <StateInfo> events = new NativeList <StateInfo>(Allocator.Temp); //Retrieve all event corresponding to this entity for (var index = 0; index < stateEvents.List.Length; index++) { var info = stateEvents.List[index]; if (info.Entity == e) { events.Add(info); } } //Return if no events with this entity if (events.Length <= 0) { return; } // bool stateChanged = false; //Look for an unlock event for (var index = 0; index < events.Length; index++) { if (events[index].Action == StateInfo.ActionType.Unlock) { UnLock(ref component); // stateChanged = true; } } //Retrieve all states desired and choose the most important state State stateToChangeTo = 0; State animationStateToChangeTo = 0; bool shouldStateMachineLock = false; bool tryChangeEvent = false; for (var index = 0; index < events.Length; index++) { var info = events[index]; if (info.Action == StateInfo.ActionType.TryChange) { tryChangeEvent = true; if (info.DesiredState > stateToChangeTo) { stateToChangeTo = info.DesiredState; shouldStateMachineLock = false; } if (info.DesiredState > animationStateToChangeTo) { if (Contains(ref dynamicAnimator, info.DesiredState)) { animationStateToChangeTo = info.DesiredState; } } } else if (info.Action == StateInfo.ActionType.TryChangeAndLock) { tryChangeEvent = true; if (info.DesiredState > stateToChangeTo) { stateToChangeTo = info.DesiredState; shouldStateMachineLock = true; } if (info.DesiredState > animationStateToChangeTo) { if (Contains(ref dynamicAnimator, info.DesiredState)) { animationStateToChangeTo = info.DesiredState; } } } } //Change state if (tryChangeEvent) { if (component.CurrentState != stateToChangeTo) { TryChangeState(ref component, stateToChangeTo, shouldStateMachineLock); } } //Create animation event (only if state changed) if (animatedEntities.Components.HasComponent(e)) { //Make sure animation desired isnt already playing if (component.CurrentAnimationState != animationStateToChangeTo) { component.CurrentAnimationState = animationStateToChangeTo; animationEvents.Enqueue(new AnimationInfo { Entity = e, Type = AnimationInfo.EventType.OnSwapAnimation, NewState = animationStateToChangeTo }); } } events.Dispose(); }).ScheduleParallel(Dependency).Complete(); }
public static void Enqueue <T>(this NativeQueue <T> q, T[] vals) where T : struct => q.Enqueue(vals);
void RunTest() { var em = World.All[0].EntityManager; if (!em.HasComponent <Navmesh>(Navmesh.Entity)) { return; } _runTest = true; BurstCompiler.Options.EnableBurstCompilation = BurstInsert; var r = new Random((uint)Seed); var l = new NativeList <float2>(Allocator.Persistent); var a = new NativeList <int>(Allocator.Persistent); _entities = new NativeList <Entity>(Amount, Allocator.Persistent); if (Select && P) { P.position = ((float2)SelectPos).ToXxY(); } for (int i = 0; i < Amount; i++) { var p = Prefabs[r.NextInt(Prefabs.Length)]; var scale = 1 - ScaleOffset + r.NextFloat() * 2 * ScaleOffset; var rot = r.NextFloat(2 * math.PI); var vertices = p.Vertices.Select(f => Math.Rotate((float2)(scale * f), rot)).ToList(); var min = new float2(float.MaxValue); var max = new float2(float.MinValue); foreach (var f in vertices) { min = math.min(f, min); max = math.max(f, max); } var size = max - min; var range = Size - size; var offset = r.NextFloat2(range); if (Select) { var add = false; for (int j = 0; j < vertices.Count - 1; j++) { if (i < 10 || IntersectSegCircle(vertices[j] - min + offset, vertices[j + 1] - min + offset, SelectPos, SelectRadius) > 0) { add = true; break; } } if (!add) { DestroyImmediate(p.gameObject); continue; } } foreach (var f in vertices) { l.Add(f - min + offset); } a.Add(vertices.Count); } _points = l.Length; Warmup(); for (int i = 0; i < Amount; i++) { _entities.Add(em.CreateEntity()); } var navmeshes = new NativeArray <NavmeshComponent>(1, Allocator.TempJob); navmeshes[0] = em.GetComponentData <NavmeshComponent>(Navmesh.Entity); var toRemove = new NativeQueue <Entity>(Allocator.TempJob); new InsertValidateJob { Navmesh = navmeshes, Destroyed = em.GetBuffer <DestroyedTriangleElement>(Navmesh.Entity), Points = l, Amounts = a, ObstacleEntities = _entities, Validation = Validation, ToRemove = toRemove } .RunTimed($"Insert and refine {_points} points"); em.SetComponentData(Navmesh.Entity, navmeshes[0]); if (Remove) { RunRemove(); } navmeshes.Dispose(); l.Dispose(); a.Dispose(); toRemove.Dispose(); }
public static void Collide(ref BallData ball, ref NativeQueue <EventData> .ParallelWriter events, ref CollisionEventData collEvent, ref BumperRingAnimationData ringData, ref BumperSkirtAnimationData skirtData, in Collider collider, in BumperStaticData data, ref Random random)
protected override void OnCreate() { _player = Object.FindObjectOfType <Player>(); _simulateCycleSystemGroup = World.GetOrCreateSystem <SimulateCycleSystemGroup>(); _eventQueue = new NativeQueue <EventData>(Allocator.Persistent); }
//private NativeReference<int> _pointsToAdd; //private int* p_pointsToAdd; //unsafe protected override void OnCreate() //{ // //_pointsToAdd = new Unity.Collections.NativeArray<int>(1, Allocator.Persistent); // //p_pointsToAdd = (int*)Unity.Collections.LowLevel.Unsafe.NativeArrayUnsafeUtility.GetUnsafePtr(this._pointsToAdd); // _pointsToAdd = new NativeReference<int>(Allocator.Persistent); // p_pointsToAdd = (int*)_pointsToAdd.GetUnsafePtr(); // base.OnCreate(); //} //protected override void OnDestroy() //{ // _pointsToAdd.Dispose(this.Dependency); // base.OnDestroy(); //} unsafe protected override void OnUpdate() { //System.GC.Collect(); //itterate every player that has a triggerbuffer //look at entities in triggerbuffer, and if any have a collectable, mark the collectable to be killed ////single threaded //{ // var ecb = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>().CreateCommandBuffer(); // var pointsToAdd = 0; // Entities // .WithAll<Player>() // .ForEach((Entity playerEntity, DynamicBuffer<TriggerBuffer> tBuffer, in Player player) => // { // for (var i = 0; i < tBuffer.Length; i++) // { // var _tb = tBuffer[i]; // if (HasComponent<Collectable>(_tb.entity) && !HasComponent<Kill>(_tb.entity)) // { // ecb.AddComponent(_tb.entity, new Kill() { timer = 0 }); // } // if (HasComponent<Collectable>(_tb.entity) && !HasComponent<Kill>(_tb.entity)) // { // ecb.AddComponent(_tb.entity, new Kill() { timer = 0 }); // var collectable = GetComponent<Collectable>(_tb.entity); // pointsToAdd += collectable.points; // //System.Threading.Interlocked.Add(ref pointsToAdd, collectable.points); // //GameManager.instance.AddPoints(collectable.points); // } // if (HasComponent<PowerPill>(_tb.entity) && !HasComponent<Kill>(_tb.entity)) // { // ecb.AddComponent(_tb.entity, new Kill() { timer = 0 }); // var pill = GetComponent<PowerPill>(_tb.entity); // ecb.AddComponent(playerEntity, pill); // } // } // }).WithoutBurst().Run(); // GameManager.instance.AddPoints(pointsToAdd); //} ////parallel using class field for accumulation //{ // var ecbSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>(); // var ecb = ecbSystem.CreateCommandBuffer().AsParallelWriter(); // var p_pointsToAdd = this.p_pointsToAdd; // Entities // .WithAll<Player>() // .ForEach((int entityInQueryIndex, Entity playerEntity, DynamicBuffer<TriggerBuffer> triggerBuffer, in Player player) => // { // for (var i = 0; i < triggerBuffer.Length; i++) // { // var _tb = triggerBuffer[i]; // if (HasComponent<Collectable>(_tb.entity) && !HasComponent<Kill>(_tb.entity)) // { // ecb.AddComponent(entityInQueryIndex, _tb.entity, new Kill() { timer = 0 }); // var collectable = GetComponent<Collectable>(_tb.entity); // System.Threading.Interlocked.Add(ref *p_pointsToAdd, collectable.points); // } // if (HasComponent<PowerPill>(_tb.entity) && !HasComponent<Kill>(_tb.entity)) // { // ecb.AddComponent(entityInQueryIndex, _tb.entity, new Kill() { timer = 0 }); // var pill = GetComponent<PowerPill>(_tb.entity); // ecb.AddComponent(entityInQueryIndex, playerEntity, pill); // } // } // }) // .WithNativeDisableUnsafePtrRestriction(p_pointsToAdd) // .ScheduleParallel(); // ecbSystem.AddJobHandleForProducer(this.Dependency); // if (_pointsToAdd.Value != 0) // { // var pointsToAdd = System.Threading.Interlocked.Exchange(ref *p_pointsToAdd, 0); // GameManager.instance.AddPoints(pointsToAdd); // } //} //UNSAFE parallel using only job temp variable //SAFE nativeQueue parallel version { var ecbSystem = World.GetOrCreateSystem <EndSimulationEntityCommandBufferSystem>(); var ecb = ecbSystem.CreateCommandBuffer().AsParallelWriter(); //SAFE nativeQueue var EXAMPLE_SAFE_queue = new NativeQueue <int>(Allocator.TempJob); var EXAMPLE_SAFE_queue_writer = EXAMPLE_SAFE_queue.AsParallelWriter(); //UNSAFE var pointsToAdd = new NativeReference <int>(Allocator.TempJob); var p_pointsToAdd = (int *)pointsToAdd.GetUnsafePtr(); //SAFE nativeArray var EXAMPLE_SAFE_array = new NativeArray <int>(_query.CalculateEntityCount(), Allocator.TempJob, NativeArrayOptions.UninitializedMemory); Entities .WithStoreEntityQueryInField(ref _query) .WithAll <Player>() .ForEach((int nativeThreadIndex, int entityInQueryIndex, Entity playerEntity, DynamicBuffer <TriggerBuffer> triggerBuffer, in Player player) => { var pointsToAdd = 0; for (var i = 0; i < triggerBuffer.Length; i++) { var _tb = triggerBuffer[i]; if (HasComponent <Collectable>(_tb.entity) && !HasComponent <Kill>(_tb.entity)) { ecb.AddComponent(entityInQueryIndex, _tb.entity, new Kill() { timer = 0 }); var collectable = GetComponent <Collectable>(_tb.entity); //UNSAFE System.Threading.Interlocked.Add(ref *p_pointsToAdd, collectable.points); //SAFE nativeQueue EXAMPLE_SAFE_queue_writer.Enqueue(collectable.points); //SAFE nativeArray (part 1/2) pointsToAdd += collectable.points; } if (HasComponent <PowerPill>(_tb.entity) && !HasComponent <Kill>(_tb.entity)) { ecb.AddComponent(entityInQueryIndex, _tb.entity, new Kill() { timer = 0 }); var pill = GetComponent <PowerPill>(_tb.entity); ecb.AddComponent(entityInQueryIndex, playerEntity, pill); } } //SAFE nativeArray (part 2/2) EXAMPLE_SAFE_array[entityInQueryIndex] = pointsToAdd; }) .WithNativeDisableUnsafePtrRestriction(p_pointsToAdd) .ScheduleParallel(); ecbSystem.AddJobHandleForProducer(this.Dependency); Job.WithReadOnly(pointsToAdd).WithCode(() => { //UNSAFE GameManager.instance.AddPoints(pointsToAdd.Value); //SAFE nativeQueue while (EXAMPLE_SAFE_queue.TryDequeue(out var pts)) { GameManager.instance.AddPoints(pts); } //SAFE nativeArray foreach (var pointsToAdd in EXAMPLE_SAFE_array) { GameManager.instance.AddPoints(pointsToAdd); } }) //.WithDisposeOnCompletion(pointsToAdd) //doesn't work .WithoutBurst() .Run(); pointsToAdd.Dispose(this.Dependency); //pointsToAdd.Dispose() would also work, as internally it finds this.Dependency EXAMPLE_SAFE_queue.Dispose(this.Dependency); EXAMPLE_SAFE_array.Dispose(this.Dependency); } }
public override void UpdateSystem() { NativeArray <Translation> resourceTranslations = m_resourceQuery.ToComponentDataArrayAsync <Translation>(Allocator.TempJob, out JobHandle getResourceTranslations); NativeArray <TargetableByAI> resourceTargets = m_resourceQuery.ToComponentDataArrayAsync <TargetableByAI>(Allocator.TempJob, out JobHandle getResourceTargets); NativeArray <Entity> resourceEntities = m_resourceQuery.ToEntityArrayAsync(Allocator.TempJob, out JobHandle getResourceEntities); JobHandle resourceQueries = JobHandle.CombineDependencies(getResourceTranslations, getResourceTargets, getResourceEntities); NativeArray <Translation> enemyTranslations = m_resourceQuery.ToComponentDataArrayAsync <Translation>(Allocator.TempJob, out JobHandle getEnemyTranslations); NativeArray <TargetableByAI> enemyTargets = m_enemyQuery.ToComponentDataArrayAsync <TargetableByAI>(Allocator.TempJob, out JobHandle getEnemyTargets); NativeArray <Entity> enemyEntities = m_resourceQuery.ToEntityArrayAsync(Allocator.TempJob, out JobHandle getEnemyEntites); JobHandle enemyQueries = JobHandle.CombineDependencies(getEnemyTranslations, getEnemyTargets, getEnemyEntites); NativeArray <Translation> storeTranslations = m_storeQuery.ToComponentDataArrayAsync <Translation>(Allocator.TempJob, out JobHandle getStoreTranslations); NativeArray <TargetableByAI> storeTargets = m_storeQuery.ToComponentDataArrayAsync <TargetableByAI>(Allocator.TempJob, out JobHandle getStoreTargets); NativeArray <Entity> storeEntities = m_storeQuery.ToEntityArrayAsync(Allocator.TempJob, out JobHandle getStoreEntities); JobHandle storeQueries = JobHandle.CombineDependencies(getStoreTranslations, getStoreTargets, getStoreEntities); Dependency = JobHandle.CombineDependencies(JobHandle.CombineDependencies(resourceQueries, enemyQueries, storeQueries), Dependency); #if UNITY_EDITOR Dependency = JobHandle.CombineDependencies(Dependency, m_debugDrawer.debugDrawDependencies); NativeQueue <DebugDrawCommand> .ParallelWriter debugDrawCommandQueue = m_debugDrawer.DebugDrawCommandQueueParallel; #endif Dependency = Entities .WithReadOnly(resourceTranslations) .WithReadOnly(resourceTargets) .WithReadOnly(resourceEntities) .WithReadOnly(enemyTranslations) .WithReadOnly(enemyTargets) .WithReadOnly(enemyEntities) .WithReadOnly(storeTranslations) .WithReadOnly(storeTargets) .WithReadOnly(storeEntities) .WithDisposeOnCompletion(resourceTranslations) .WithDisposeOnCompletion(resourceTargets) .WithDisposeOnCompletion(resourceEntities) .WithDisposeOnCompletion(enemyTranslations) .WithDisposeOnCompletion(enemyTargets) .WithDisposeOnCompletion(enemyEntities) .WithDisposeOnCompletion(storeTranslations) .WithDisposeOnCompletion(storeTargets) .WithDisposeOnCompletion(storeEntities) .ForEach((Entity entity, int entityInQueryIndex, ref DynamicBuffer <Command> commandBuffer, ref CurrentTarget currentTarget, ref CurrentAIState currentAIState, in Translation translation) => { if (commandBuffer.Length <= 0) { if (currentAIState.currentAIState != AIState.Idle) { currentAIState.RequestStateChange(AIState.Idle); } return; } #if UNITY_EDITOR for (int commandIndex = 1; commandIndex < commandBuffer.Length; commandIndex++) { debugDrawCommandQueue.Enqueue(new DebugDrawCommand { debugDrawCommandType = DebugDrawCommandType.Line, debugDrawLineData = new DebugDrawLineData { colour = Color.red, start = commandBuffer[commandIndex - 1].commandData.targetData.targetPos, end = commandBuffer[commandIndex].commandData.targetData.targetPos } }); } #endif Command currentCommand = commandBuffer[0]; if (currentCommand.commandStatus == CommandStatus.Complete) { //If the command is complete remove it from the queue commandBuffer.RemoveAt(0); if (commandBuffer.Length != 0) { //Process the next command currentCommand = commandBuffer[0]; } else { return; } } if (currentCommand.commandStatus == CommandStatus.Queued) { //If we have not been assigned a target for this command, then we attempt to find a target for it. //We loop here until we hit a command with a target or the command queue is empty, in which case we switch to idle. while (currentCommand.commandData.targetData.targetEntity == Entity.Null) { //If we don't find a target, then we move on to the next command if there is one, or set our state to idle. if (!FindNearestTarget(ref currentCommand, translation, resourceTargets, resourceTranslations, resourceEntities, storeTargets, storeTranslations, storeEntities, enemyTargets, enemyTranslations, enemyEntities)) { commandBuffer.RemoveAt(0); if (commandBuffer.Length > 0) { currentCommand = commandBuffer[0]; } else { currentAIState.RequestStateChange(AIState.Idle); return; } } } currentCommand.commandStatus = CommandStatus.MovingPhase; Debug.Log($"Processing the moving phase { currentCommand.commandType } command from queue"); ProcessMovingPhaseCommand(entity, ref currentCommand, ref currentAIState); //We do not progress state to execution here as we leave the specific systems to tell us when we are in range for the command. } else if (currentCommand.commandStatus == CommandStatus.ExecutionPhase && currentCommand.commandStatus != currentCommand.previousCommandStatus) { Debug.Log($"Processing the execution phase { currentCommand.commandType } command from queue"); ProcessExecutionPhaseCommand(entity, ref currentCommand, ref currentAIState); //We do not progress state to complete here as we leave the specific systems to tell us when we have completed the command. } currentCommand.previousCommandStatus = currentCommand.commandStatus; commandBuffer[0] = currentCommand; }).Schedule(Dependency); #if UNITY_EDITOR m_debugDrawer.debugDrawDependencies = Dependency; #endif }
protected override void OnCreate() { endSimulationEntityCommandBufferSystem = World.GetOrCreateSystem <EndSimulationEntityCommandBufferSystem>(); buildPhysicsWorld = World.GetOrCreateSystem <BuildPhysicsWorld>(); bulletEvents = new NativeQueue <BulletInfo>(Allocator.Persistent); }
protected override void OnUpdate() { //Get Physic World PhysicsWorld physicsWorld = buildPhysicsWorld.PhysicsWorld; //Create ECB var entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(); //Create parallel writer NativeQueue <BulletInfo> .ParallelWriter events = bulletEvents.AsParallelWriter(); //Get all enemy existing ComponentDataContainer <EnemyTag> enemies = new ComponentDataContainer <EnemyTag> { Components = GetComponentDataFromEntity <EnemyTag>(true) }; //Get all entities with life ComponentDataContainer <LifeComponent> entitiesLife = new ComponentDataContainer <LifeComponent> { Components = GetComponentDataFromEntity <LifeComponent>(true) }; // ComponentDataContainer <DropChanceComponent> dropChance = new ComponentDataContainer <DropChanceComponent> { Components = GetComponentDataFromEntity <DropChanceComponent>(true) }; //Get Player entity Entity player = GameVariables.Player.Entity; JobHandle job = Entities.ForEach((Entity entity, int entityInQueryIndex, ref DamageProjectile projectile, ref Translation translation, in Rotation rotation, in BulletCollider bulletCollider, in BulletPreviousPositionData previousPosition) => { //Create Personal Filter for each Bullet CollisionFilter filter = new CollisionFilter { BelongsTo = bulletCollider.BelongsTo.Value, CollidesWith = bulletCollider.CollidesWith.Value, GroupIndex = bulletCollider.GroupIndex }; //Find direction float3 direction = translation.Value - previousPosition.Value; direction = math.normalizesafe(direction); //Find Vector to add float3 offset = default; float offsetRad = math.radians(90f); float cos = math.cos(offsetRad); float sin = math.sin(offsetRad); offset.x = direction.x * cos - direction.z * sin; offset.z = direction.x * sin + direction.z * cos; offset *= projectile.Radius; //Create Ray Inputs RaycastInput middleRayCast = GetRayCastInput(filter, translation.Value, previousPosition.Value, float3.zero); RaycastInput rightRayCast = GetRayCastInput(filter, translation.Value, previousPosition.Value, offset); RaycastInput leftRayCast = GetRayCastInput(filter, translation.Value, previousPosition.Value, -offset); //Adding a negative radius bool hitDetected = false; Entity hitEntity = Entity.Null; RaycastHit hit = default; float3 hitPosition = default; //Try first RayCast if (physicsWorld.CollisionWorld.CastRay(middleRayCast, out RaycastHit middleRayCastHit)) { hitDetected = true; hit = middleRayCastHit; hitPosition = float3.zero; //Get Hit Entity hitEntity = physicsWorld.Bodies[middleRayCastHit.RigidBodyIndex].Entity; } else if (physicsWorld.CollisionWorld.CastRay(rightRayCast, out RaycastHit rightRayCastHit)) { hitDetected = true; hit = rightRayCastHit; hitPosition = -offset; //Get Hit Entity hitEntity = physicsWorld.Bodies[rightRayCastHit.RigidBodyIndex].Entity; } //Try second RayCast (Only if first one didnt hit) else if (physicsWorld.CollisionWorld.CastRay(leftRayCast, out RaycastHit leftRayCastHit)) { hitDetected = true; hit = leftRayCastHit; hitPosition = offset; //Get Hit Entity hitEntity = physicsWorld.Bodies[leftRayCastHit.RigidBodyIndex].Entity; } //Make sure theres a collision if (!hitDetected) { return; } //Make sure an Entity was found if (hitEntity == Entity.Null) { return; } //Make sure collision hasn't been found before //TODO //Treat Collision //Collision = Wall until proven opposite BulletInfo.BulletCollisionType collisionType = BulletInfo.BulletCollisionType.ON_WALL; //Look if HitEntity is Player's if (hitEntity == player) { collisionType = BulletInfo.BulletCollisionType.ON_PLAYER; } //Look if HitEntity is an enemy else if (enemies.Components.HasComponent(hitEntity)) { collisionType = BulletInfo.BulletCollisionType.ON_ENEMY; } bool shouldBulletBeDestroyed = true; //Damage entity if (collisionType != BulletInfo.BulletCollisionType.ON_WALL) { //Make sure HitEntity has LifeComponent if (entitiesLife.Components.HasComponent(hitEntity)) { //Make sure HitEntity has LifeComponent if (entitiesLife.Components.HasComponent(hitEntity)) { //Get LifeComponent of this entity LifeComponent life = entitiesLife.Components[hitEntity]; //Decrease life if (player == hitEntity) { shouldBulletBeDestroyed = life.DecrementLifeWithInvincibility(); } else if (entitiesLife.Components[hitEntity].Life.Value <= 0) { shouldBulletBeDestroyed = false; } else { life.DecrementLife(); } //Set Back entityCommandBuffer.SetComponent(entityInQueryIndex, hitEntity, life); } } } //Destroy bullet if (shouldBulletBeDestroyed) { entityCommandBuffer.DestroyEntity(entityInQueryIndex, entity); events.Enqueue(new BulletInfo { HitEntity = hitEntity, ProjectileType = projectile.Type, CollisionType = collisionType, HitPosition = hit.Position + hitPosition, HitRotation = rotation.Value }); } }).ScheduleParallel(Dependency);
protected override void OnCreate() { eventsQueue = new NativeQueue <SpeedEvent>(Allocator.Persistent); }
public QueueWrapper() { m_IPCQueue = new NativeQueue <IPCManager.IPCQueuedMessage>(Allocator.Persistent); }
protected override void OnCreate() { stateEvents = new NativeQueue <StateInfo>(Allocator.Persistent); entityCommandBuffer = World.GetExistingSystem <EndInitializationEntityCommandBufferSystem>(); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (units.entities.Length == 0) { return(inputDeps); } Profiler.BeginSample("Explosion wait"); spellSystem.CombinedExplosionHandle.Complete(); // TODO try to remove this Profiler.EndSample(); inputDeps.Complete(); Profiler.BeginSample("Spawn "); if (!deathQueue.IsCreated) { deathQueue = new NativeQueue <Entity>(Allocator.Persistent); } if (!createdArrows.IsCreated) { createdArrows = new NativeQueue <ArrowData>(Allocator.Persistent); } while (createdArrows.Count > 0) { var data = createdArrows.Dequeue(); Spawner.Instance.SpawnArrow(data); } UpdateInjectedComponentGroups(); var cleanupJob = new CleanupJob { deathQueue = deathQueue, minionData = units.data, entitites = units.entities }; var moveUnitsJob = new MoveUnitsBelowGround() { dyingUnitData = dyingUnits.dyingData, transforms = dyingUnits.transforms, time = Time.time }; var cleanupJobFence = cleanupJob.Schedule(units.Length, SimulationState.BigBatchSize, inputDeps); var moveUnitsBelowGroundFence = moveUnitsJob.Schedule(dyingUnits.Length, SimulationState.HugeBatchSize, spellSystem.CombinedExplosionHandle); Profiler.EndSample(); cleanupJobFence.Complete(); moveUnitsBelowGroundFence.Complete(); Profiler.BeginSample("LifeCycleManager - Main Thread"); float time = Time.time; if (dyingUnits.Length > 0) { for (int i = 0; i < dyingUnits.Length; i++) { if (time > dyingUnits.dyingData[i].TimeAtWhichToExpire) { var entityToKill = dyingUnits.entities[i]; queueForKillingEntities.Enqueue(entityToKill); } //else if (time > dyingData[i].TimeAtWhichToExpire - 2f) //{ // float t = (dyingData[i].TimeAtWhichToExpire - time) / 2f; // var transform = transforms[i]; // transform.Position.y = math.lerp(dyingData[i].StartingYCoord, dyingData[i].StartingYCoord - 1f, t); // transforms[i] = transform; //} } } if (dyingArrows.Length > 0) { for (int i = 0; i < dyingArrows.Length; i++) { if (time > dyingArrows.dyingData[i].TimeAtWhichToExpire) { var arrowToKill = dyingArrows.entities[i]; queueForKillingEntities.Enqueue(arrowToKill); } } } Profiler.EndSample(); Profiler.BeginSample("Queue processing"); float timeForUnitExpiring = Time.time + 5f; float timeForArrowExpiring = Time.time + 1f; Profiler.BeginSample("Death queue"); int processed = 0; while (deathQueue.Count > 0) { var entityToKill = deathQueue.Dequeue(); if (EntityManager.HasComponent <MinionData>(entityToKill)) { EntityManager.RemoveComponent <MinionData>(entityToKill); entitiesThatNeedToBeKilled.Enqueue(entityToKill); } if (EntityManager.HasComponent <ArrowData>(entityToKill)) { EntityManager.AddComponentData(entityToKill, new DyingUnitData(timeForArrowExpiring, 0)); } } Profiler.EndSample(); Profiler.BeginSample("Explosion wait"); spellSystem.CombinedExplosionHandle.Complete(); Profiler.EndSample(); Profiler.BeginSample("Killing minionEntities"); // TODO try batched replacing while (entitiesThatNeedToBeKilled.Count > 0 && processed < MaxDyingUnitsPerFrame) { processed++; var entityToKill = entitiesThatNeedToBeKilled.Dequeue(); if (EntityManager.HasComponent <MinionTarget>(entityToKill)) { EntityManager.RemoveComponent <MinionTarget>(entityToKill); if (EntityManager.HasComponent <AliveMinionData>(entityToKill)) { EntityManager.RemoveComponent <AliveMinionData>(entityToKill); } var textureAnimatorData = EntityManager.GetComponentData <TextureAnimatorData>(entityToKill); textureAnimatorData.NewAnimationId = AnimationName.Death; var transform = EntityManager.GetComponentData <UnitTransformData>(entityToKill); EntityManager.AddComponentData(entityToKill, new DyingUnitData(timeForUnitExpiring, transform.Position.y)); EntityManager.SetComponentData(entityToKill, textureAnimatorData); var formations = GetComponentDataFromEntity <FormationData>(); var formation = formations[transform.FormationEntity]; formation.UnitCount--; formation.Width = (int)math.ceil((math.sqrt(formation.UnitCount / 2f) * 2f)); if (formation.UnitCount == 0) { formation.FormationState = FormationData.State.AllDead; } formations[transform.FormationEntity] = formation; } } Profiler.EndSample(); processed = 0; Profiler.BeginSample("Flying queue"); while (entitiesForFlying.Count > 0 && processed < MaxDyingUnitsPerFrame) { processed++; var entity = entitiesForFlying.Dequeue(); if (EntityManager.Exists(entity) && !EntityManager.HasComponent <FlyingData>(entity)) { if (EntityManager.HasComponent(entity, typeof(AliveMinionData))) { EntityManager.RemoveComponent <AliveMinionData>(entity); } EntityManager.AddComponentData(entity, new FlyingData()); } } Profiler.EndSample(); Profiler.BeginSample("Destroying entities"); while (queueForKillingEntities.Count > 0) { EntityManager.DestroyEntity(queueForKillingEntities.Dequeue()); } Profiler.EndSample(); Profiler.EndSample(); return(new JobHandle()); }
public NetworkLogger(LogLevel level) { m_Level = level; m_PendingLog = new NativeQueue <LogMessage>(Allocator.Persistent); m_LogFile = new NativeList <LogMessage>(Allocator.Persistent); }
/// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: public BasicNetworkDriver(params INetworkParameter[] param) { m_NetworkParams = default(Parameters); object boxedParams = m_NetworkParams; foreach (var field in typeof(Parameters).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { for (int i = 0; i < param.Length; ++i) { if (field.FieldType.IsAssignableFrom(param[i].GetType())) { field.SetValue(boxedParams, param[i]); } } } m_NetworkParams = (Parameters)boxedParams; if (m_NetworkParams.bitStream.size == 0) { m_NetworkParams.bitStream.size = NetworkParameterConstants.DriverBitStreamSize; } if (m_NetworkParams.config.maxConnectAttempts == 0) { m_NetworkParams.config.maxConnectAttempts = NetworkParameterConstants.MaxConnectAttempts; } if (m_NetworkParams.config.connectTimeout == 0) { m_NetworkParams.config.connectTimeout = NetworkParameterConstants.ConnectTimeout; } if (m_NetworkParams.config.disconnectTimeout == 0) { m_NetworkParams.config.disconnectTimeout = NetworkParameterConstants.DisconnectTimeout; } m_BitStream = new BitStream(m_NetworkParams.bitStream.size, Allocator.Persistent); m_NetworkInterface = new T(); m_NetworkInterface.Initialize(); m_NetworkAcceptQueue = new NativeQueue <int>(Allocator.Persistent); m_ConnectionList = new NativeArray <Connection>(NetworkParameterConstants.MaximumConnectionsSupported, Allocator.Persistent); m_FreeList = new ConnectionFreeList(NetworkParameterConstants.MaximumConnectionsSupported); m_EventQueue = new NetworkEventQueue(NetworkParameterConstants.MaximumConnectionsSupported, NetworkParameterConstants.NetworkEventQLength); for (int i = 0; i < NetworkParameterConstants.MaximumConnectionsSupported; i++) { m_ConnectionList[i] = new Connection { Id = i, Version = 1 } } ; m_InternalState = new NativeArray <int>(1, Allocator.Persistent); m_PendingFree = new NativeQueue <int>(Allocator.Persistent); Listening = false; }
private void Update() { List <Transform> children = new List <Transform>(); foreach (var child in transform) { children.Add(child as Transform); } var sdf = GetComponent <SDFBehaviour>().GetNode().Compile(); var pairArrays = new NativeArray <KeyValuePair <int3, float3> > [Chunks * Chunks]; for (int i = 0; i < pairArrays.Length; i++) { pairArrays[i] = new NativeArray <KeyValuePair <int3, float3> >(Resolution * Resolution * Resolution, Allocator.TempJob); } NativeArray <JobHandle> handles = new NativeArray <JobHandle>(Chunks * Chunks, Allocator.TempJob); var counts = new NativeArray <int>(Chunks * Chunks, Allocator.TempJob); var offsets = new NativeArray <int>(Chunks * Chunks, Allocator.TempJob); float size = (Resolution - 1) * GridSize; //STEP 1 { int pairIndex = 0; for (int dx = 0; dx < Chunks; dx++) { for (int dz = 0; dz < Chunks; dz++) { handles[pairIndex] = new BuildVertices() { Resolution = Resolution, GridSize = GridSize, GridCorner = transform.position + new Vector3(dx, 0, dz) * size, SDF = sdf, Vertices = pairArrays[pairIndex], Counts = counts, CountIndex = pairIndex, CellOffset = new int3(dx * (Resolution - 1), 0, dz * (Resolution - 1)), UseVoxelStyle = UseVoxelStyle }.Schedule(); pairIndex++; } } JobHandle.CompleteAll(handles); } //STEP 2 { new CalculateOffsets() { Counts = counts, Offsets = offsets }.Run(); } int totalVerts = 0; for (int i = 0; i < counts.Length; i++) { totalVerts += counts[i]; } var verts = new NativeArray <Vector3>(totalVerts, Allocator.TempJob); var map = new NativeHashMap <int3, int>(totalVerts, Allocator.TempJob); //STEP 3 { int pairIndex = 0; for (int dx = 0; dx < Chunks; dx++) { for (int dz = 0; dz < Chunks; dz++) { new BuildVertexArrayAndMap() { InVertices = pairArrays[pairIndex], Counts = counts, Offsets = offsets, CountIndex = pairIndex, Vertices = verts, VertexMap = map.ToConcurrent() }.Schedule().Complete(); pairIndex++; } } } var triQueue = new NativeQueue <int3>(Allocator.TempJob); //STEP 4 { int pairIndex = 0; for (int dx = 0; dx < Chunks; dx++) { for (int dz = 0; dz < Chunks; dz++) { new BuildTriQueue() { InVertices = pairArrays[pairIndex], Counts = counts, CountIndex = pairIndex, TriQueue = triQueue.ToConcurrent(), VertexMap = map, SDF = sdf, GridCorner = transform.position, GridSize = GridSize }.Schedule().Complete(); pairIndex++; } } } var triArray = new NativeArray <int>(triQueue.Count * 3, Allocator.TempJob); //STEP 5 new BuildTriArray() { TriQueue = triQueue, Triangles = triArray }.Schedule().Complete(); _mesh.Clear(); _mesh.vertices = verts.ToArray(); _mesh.triangles = triArray.ToArray(); _mesh.RecalculateNormals(); Graphics.DrawMesh(_mesh, Matrix4x4.identity, previewMat, 0); foreach (var pairArray in pairArrays) { pairArray.Dispose(); } counts.Dispose(); offsets.Dispose(); sdf.Dispose(); verts.Dispose(); map.Dispose(); triQueue.Dispose(); triArray.Dispose(); handles.Dispose(); }
public Mesh GenerateMesh() { Vector3Int cubesDimensions = dimensions - Vector3Int.one; var cubes = new NativeArray <Cube>(cubesDimensions.x * cubesDimensions.y * cubesDimensions.z, Allocator.TempJob); for (int x = 0; x < cubesDimensions.x; x++) { for (int y = 0; y < cubesDimensions.y; y++) { for (int z = 0; z < cubesDimensions.z; z++) { var cube = new Cube( new int3(x, y, z), voxels[x, y, z], voxels[x, y, 1 + z], voxels[1 + x, y, 1 + z], voxels[1 + x, y, z], voxels[x, 1 + y, z], voxels[x, 1 + y, 1 + z], voxels[1 + x, 1 + y, 1 + z], voxels[1 + x, 1 + y, z] ); cubes[x + cubesDimensions.x * (y + cubesDimensions.y * z)] = cube; } } } var trianglesQueue = new NativeQueue <Triangle>(Allocator.TempJob); new PolygoniseJob() { cubes = cubes, isolevel = isoLevel, trianglesQueue = trianglesQueue.AsParallelWriter() }.Schedule(cubes.Length, 128).Complete(); cubes.Dispose(); var vertexDictionary = new Dictionary <Vector3, int>(trianglesQueue.Count, new Vector3EqualityComparer()); var triangles = new int[trianglesQueue.Count * 3]; for (int i = 0; trianglesQueue.TryDequeue(out Triangle triangle); i += 3) { int Dedupe(Vector3 vertex) { int vertexIndex; if (!vertexDictionary.TryGetValue(vertex, out vertexIndex)) { vertexIndex = vertexDictionary.Count; vertexDictionary.Add(vertex, vertexIndex); } return(vertexIndex); } triangles[i] = Dedupe(triangle.v1); triangles[i + 1] = Dedupe(triangle.v2); triangles[i + 2] = Dedupe(triangle.v3); } trianglesQueue.Dispose(); Vector3[] vertices = vertexDictionary.Keys.ToArray(); var uv = new Vector2[vertices.Length]; for (int i = 0; i < uv.Length; i++) { uv[i] = new Vector2(vertices[i].x / dimensions.x, vertices[i].z / dimensions.z); } var mesh = new Mesh() { name = $"Terrain{System.DateTime.UtcNow.ToFileTime().ToString()} Mesh", vertices = vertices, triangles = triangles, uv = uv, }; mesh.RecalculateBounds(); mesh.RecalculateNormals(); mesh.RecalculateTangents(); mesh.Optimize(); return(mesh); }
private void Awake() { //Sound_Manager.Init((Sound_Manager.AudioType audioType) => .015f); instance = this; queuedActions = new NativeQueue <MarineShotZombieAction>(Allocator.Persistent); }
protected override void OnCreate() { base.OnCreate(); spawnData = new NativeQueue <InternalSpawnTrailData>(Allocator.TempJob); }
public void DisposeJob() { var container = new NativeQueue <int>(Allocator.Persistent); var disposeJob = container.Dispose(default);
protected override void OnCreateManager() { base.OnCreateManager(); m_RemoveQueue = new NativeQueue <Entity>(Allocator.Persistent); }
protected override void OnCreate() { m_LineGroup = GetEntityQuery(ComponentType.ReadWrite <LineRendererComponentData>()); m_LineQueue = World.GetOrCreateSystem <LineRenderSystem>().LineQueue; }
public override void InitSystem() { m_EndSimECBSystem = World.GetOrCreateSystem <EndSimulationEntityCommandBufferSystem>(); m_resourcesQuery = GetEntityQuery(ComponentType.ReadWrite <Resources>()); m_resourcesQueue = new NativeQueue <ResourceTypeValuePair>(Allocator.Persistent); }
protected override JobHandle OnUpdate(JobHandle inputDeps) { var settings = ECSController.FlockParams; var gameSettings = GlobalSettings.Instance; EntityManager.GetAllUniqueSharedComponentData(UniqueTypes); int targetsCount = BoidTargetsGroup.CalculateLength(); int obstaclesCount = BoidObstaclesGroup.CalculateLength(); UIControl.Instance.NrOfObstacles = obstaclesCount; // Ignore typeIndex 0, can't use the default for anything meaningful. for (int typeIndex = 1; typeIndex < UniqueTypes.Count; typeIndex++) { Boid boid = UniqueTypes[typeIndex]; BoidGroup.SetFilter(boid); var boidCount = BoidGroup.CalculateLength(); UIControl.Instance.NrOfBoidsAlive = boidCount; var cacheIndex = typeIndex - 1; // containers that store all the data. var cellIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var hashMap = new NativeMultiHashMap <int, int>(boidCount, Allocator.TempJob); var cellCount = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellAlignment = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var cellPositions = new NativeArray <float3>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var targetsPositions = new NativeArray <float3>(targetsCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var closestTargetIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var obstaclesPositions = new NativeArray <float3>(obstaclesCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var closestObstacleIndices = new NativeArray <int>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var closestObstacleSqDistances = new NativeArray <float>(boidCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); float3 sumOfAllBoidsPositions = float3.zero; // copy values to buffers. var initialCellAlignmentJob = new CopyHeadingsInBuffer { headingsResult = cellAlignment }; var initialCellAlignmentJobHandle = initialCellAlignmentJob.Schedule(BoidGroup, inputDeps); var initialCopyPositionJob = new CopyPositionsInBuffer { positionsResult = cellPositions }; var initialCopyPositionJobHandle = initialCopyPositionJob.Schedule(BoidGroup, inputDeps); var sumPositionsJob = new SumPositions { positionsSum = sumOfAllBoidsPositions }; var sumPositionsJobHandle = sumPositionsJob.Schedule(BoidGroup, inputDeps); // copy targets positions var copyPositionsOfTargetsJob = new CopyPositionsInBuffer { positionsResult = targetsPositions }; var copyPositionsOfTargetsJobHandle = copyPositionsOfTargetsJob.Schedule(BoidTargetsGroup, inputDeps); // copy obstacles positions var copyPositionsOfObstaclesJob = new CopyPositionsInBuffer { positionsResult = obstaclesPositions }; var copyPositionsOfObstaclesJobHandle = copyPositionsOfObstaclesJob.Schedule(BoidObstaclesGroup, inputDeps); var newCellData = new CellsData { indicesOfCells = cellIndices, hashMapBlockIndexWithBoidsIndex = hashMap, sumOfDirectionsOnCells = cellAlignment, sumOfPositionsOnCells = cellPositions, nrOfBoidsOnCells = cellCount, targetsPositions = targetsPositions, closestTargetIndices = closestTargetIndices, closestObstacleIndices = closestObstacleIndices, closestObstacleSqDistances = closestObstacleSqDistances, obstaclesPositions = obstaclesPositions, }; if (cacheIndex > (_CellsData.Count - 1)) { _CellsData.Add(newCellData); } else { DisposeCellData(_CellsData[cacheIndex]); } _CellsData[cacheIndex] = newCellData; // hash the entity position var hashPositionsJob = new HashPositionsToHashMap { hashMap = hashMap.ToConcurrent(), cellRadius = ECSController.Instance.CellSizeVaried, positionOffsetVary = ECSController.Instance.PositionNeighbourCubeOffset }; var hashPositionsJobHandle = hashPositionsJob.Schedule(BoidGroup, inputDeps); // set all cell count to 1. var initialCellCountJob = new MemsetNativeArray <int> { Source = cellCount, Value = 1 }; var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps); // bariers. from now on we need to use the created buffers. // and we need to know that they are finished. var initialCellBarrierJobHandle = JobHandle.CombineDependencies( initialCellAlignmentJobHandle, initialCopyPositionJobHandle, initialCellCountJobHandle); var mergeCellsBarrierJobHandle = JobHandle.CombineDependencies( hashPositionsJobHandle, initialCellBarrierJobHandle, sumPositionsJobHandle); var targetsJobHandle = JobHandle.CombineDependencies(mergeCellsBarrierJobHandle, copyPositionsOfTargetsJobHandle, copyPositionsOfObstaclesJobHandle); var mergeCellsJob = new MergeCellsJob { indicesOfCells = cellIndices, cellAlignment = cellAlignment, cellPositions = cellPositions, cellCount = cellCount, targetsPositions = targetsPositions, closestTargetIndexToCells = closestTargetIndices, closestObstacleSqDistanceToCells = closestObstacleSqDistances, closestObstacleIndexToCells = closestObstacleIndices, obstaclesPositions = obstaclesPositions }; // job now depends on last barrier. var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, targetsJobHandle); EntityCommandBuffer.Concurrent commandBuffer = barrierCommand.CreateCommandBuffer().ToConcurrent(); NativeQueue <float3> killedPositionsQueue = new NativeQueue <float3>(Allocator.TempJob); var steerJob = new MoveBoids { cellIndices = newCellData.indicesOfCells, alignmentWeight = gameSettings.AlignmentWeight, separationWeight = gameSettings.SeparationWeight, cohesionWeight = gameSettings.CohesionWeight, cellSize = ECSController.Instance.CellSizeVaried, sphereBoundarySize = gameSettings.SphereBoundarySize, sphereBoundaryWeight = gameSettings.BoundaryWeight, moveSpeed = gameSettings.MoveSpeed, cellAlignment = cellAlignment, cellPositions = cellPositions, cellCount = cellCount, dt = Time.deltaTime, walkToFlockCenterWeight = gameSettings.WalkToFlockCenterWeight, sumOfAllPositions = sumOfAllBoidsPositions, nrOfTotalBoids = boidCount, maintainYWeight = gameSettings.maintainYWeight, yLength = gameSettings.yLength, perlinNoiseScale = settings.perlinNoiseScale, targetsPositions = targetsPositions, cellClosestTargetsIndices = closestTargetIndices, goToTargetsWeight = gameSettings.goToTargetsWeight, obstaclesPositions = obstaclesPositions, cellClosestObstaclesIndices = closestObstacleIndices, cellClosestObstaclesSqDistances = closestObstacleSqDistances, startAvoidingObstacleAtDistance = gameSettings.avoidDistanceObstacles, avoidObstaclesWeight = gameSettings.avoidObstaclesWeight, terrainY = ECSController.TerrainY, distanceToAvoidTerrain = settings.distanceToAvoidTerrain, avoidTerrainWeight = gameSettings.avoidTerrainWeight, avoidXZwhileHeightBiggerThan = settings.avoidXZwhileHeightBiggerThan, avoidXZwhileHeightBiggerFade = settings.avoidXZwhileHeightBiggerFade, obstacleKillRadius = settings.obstacleKillRadius, commandBuffer = commandBuffer, diedPositions = killedPositionsQueue.ToConcurrent(), }; // job depends on merge cells job var steerJobHandle = steerJob.Schedule(BoidGroup, mergeCellsJobHandle); barrierCommand.AddJobHandleForProducer(steerJobHandle); steerJobHandle.Complete(); if (killedPositionsQueue.TryDequeue(out float3 pos)) { GameController.Instance.KilledBoidAt(pos); } killedPositionsQueue.Dispose(); inputDeps = steerJobHandle; BoidGroup.AddDependency(inputDeps); } UniqueTypes.Clear(); return(inputDeps); }
protected override void OnCreateManager() { lineGroup = GetComponentGroup(ComponentType.ReadWrite <LineRendererComponentData>()); lineQueue = World.GetOrCreateManager <LineRenderSystem>().LineQueue; }
public static void Collide(ref BallData ball, ref NativeQueue <EventData> .ParallelWriter events, ref CollisionEventData collEvent, ref DynamicBuffer <BallInsideOfBufferElement> insideOfs, ref TriggerAnimationData animationData, in Collider coll)
protected override void OnCreateManager() { m_ShipArrivedQueue = new NativeQueue <Entity>(Allocator.Persistent); }
static void ExpectedCount <T>(ref NativeQueue <T> container, int expected) where T : unmanaged { Assert.AreEqual(expected == 0, container.IsEmpty()); Assert.AreEqual(expected, container.Count); }
internal static PlanGraph <int, StateInfo, int, ActionInfo, StateTransitionInfo> BuildLattice(int midLatticeDepth = 10) { int nextStateIndex = 0; int totalStates = (int)Math.Pow(2, midLatticeDepth) * 2; var planGraph = new PlanGraph <int, StateInfo, int, ActionInfo, StateTransitionInfo>(totalStates, totalStates, totalStates); var builder = new PlanGraphBuilder <int, int> { planGraph = planGraph }; var queue = new NativeQueue <int>(Allocator.TempJob); // Add root int rootStateIndex = nextStateIndex; nextStateIndex++; builder.AddState(rootStateIndex); queue.Enqueue(rootStateIndex); for (int horizon = 0; horizon < midLatticeDepth; horizon++) { var statesInHorizon = Math.Pow(2, horizon); for (int i = 0; i < statesInHorizon; i++) { var state = queue.Dequeue(); var stateContext = builder.WithState(state); var leftIndex = i == 0 ? nextStateIndex : nextStateIndex - 1; nextStateIndex++; stateContext.AddAction(0).AddResultingState(leftIndex); if (i == 0) { queue.Enqueue(leftIndex); } var rightIndex = nextStateIndex; nextStateIndex++; stateContext.AddAction(1).AddResultingState(rightIndex); queue.Enqueue(rightIndex); } } for (int horizon = midLatticeDepth - 1; horizon >= 0; horizon--) { var statesInHorizon = Math.Pow(2, horizon); for (int i = 0; i < statesInHorizon; i++) { var state = queue.Dequeue(); var stateContext = builder.WithState(state); if (i > 0) { var leftIndex = nextStateIndex - 1; stateContext.AddAction(0).AddResultingState(leftIndex); //queue.Enqueue(leftIndex); } if (i < statesInHorizon - 1) { var rightIndex = nextStateIndex; nextStateIndex++; stateContext.AddAction(1).AddResultingState(rightIndex); queue.Enqueue(rightIndex); } } } queue.Dispose(); return(planGraph); }
protected override void OnCreate() { statesChanged = new NativeQueue <AnimationInfo>(Allocator.Persistent); }