/// <summary> /// Schedules background jobs to move all agents using the given delta time /// </summary> public JobHandle MoveAgents(float dt, JobHandle dependsOn = default) { m_spatialMap.Clear(); AgentWorld agentWorld = new AgentWorld(); agentWorld.offset = world.transform.position; agentWorld.rotation = world.transform.rotation; agentWorld.center = world.data.center; agentWorld.scale = world.scale; agentWorld.size = new int3( world.size.x, world.size.y, world.size.z ); if (!movingAllAgents.IsCompleted) { movingAllAgents.Complete(); } // update the spatial map with all agent positions JobHandle spatialMaps = UpdateSpatialMap(agentWorld, dependsOn); // update each agents position by archetype for (int i = 0; i < archetypes.Count; i++) { m_movingByArchetype[i] = MoveByArchetype(i, agentWorld, dt, spatialMaps); } movingAllAgents = JobHandle.CombineDependencies(m_movingByArchetype); return(movingAllAgents); }
public void AgentsRiseWhenBuried() { NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(1, Allocator.Persistent); agents[0] = new AgentKinematics() { velocity = new float3(0, 0, 0) }; NativeArray <float3> steering = new NativeArray <float3>(1, Allocator.Persistent); steering[0] = new float3(0, 0, 0); NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(1, Allocator.Persistent); active[0] = AgentBehaviors.Active; NativeArray <VRoxel.Navigation.Block> blocks = new NativeArray <VRoxel.Navigation.Block>(1, Allocator.Persistent); VRoxel.Navigation.Block solidBlock = new VRoxel.Navigation.Block(); solidBlock.solid = true; solidBlock.cost = 1; blocks[0] = solidBlock; NativeArray <byte> voxels = new NativeArray <byte>(1, Allocator.Persistent); AgentWorld world = new AgentWorld() { scale = 1f, offset = float3.zero, center = new float3(0.5f, 0.5f, 0.5f), rotation = quaternion.identity, }; GravityBehavior job = new GravityBehavior() { gravity = new float3(0, -4f, 0), world = world, steering = steering, behaviors = active, agents = agents, blocks = blocks, voxels = voxels, }; job.Schedule(1, 1).Complete(); Assert.AreEqual(new float3(0, 2, 0), steering[0]); agents.Dispose(); active.Dispose(); blocks.Dispose(); voxels.Dispose(); steering.Dispose(); }
// Use this for initialization void Start() { spawner = FindObjectOfType <AgentSpawner>(); world = FindObjectOfType <AgentWorld>(); leaderBoardText = FindObjectOfType <LeaderBoardText>(); playerNameToId = new Dictionary <string, int>(); playerIdToName = new string[leaderBoardSize]; playerScores = new int[leaderBoardSize]; File.WriteAllText(logPath, string.Empty); FileStream fileStream = new FileStream(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); streamReader = new StreamReader(fileStream); }
/// <summary> /// Schedules background jobs to update the spatial map for all agents /// </summary> protected JobHandle UpdateSpatialMap(AgentWorld agentWorld, JobHandle dependsOn = default) { JobHandle handle = dependsOn; for (int i = 0; i < archetypes.Count; i++) { BuildSpatialMapJob job = new BuildSpatialMapJob(); job.movementConfigs = m_movementTypes; job.movement = m_agentMovementTypes[i]; job.collision = archetypes[i].collision; job.spatialMap = m_spatialMapWriter; job.behaviors = m_agentBehaviors[i]; job.agents = m_agentKinematics[i]; job.size = spatialBucketSize; job.world = agentWorld; handle = job.Schedule( m_transformAccess[i], handle ); } return(handle); }
// Use this for initialization void Start() { world = FindObjectOfType <AgentWorld>(); textMesh = GetComponent <TextMesh>(); }
public void AddBrakeForceWhenAgentsCollide() { float3 position1 = float3.zero; float3 position2 = new float3(0f, 1f, 0f); NativeMultiHashMap <int3, SpatialMapData> spatialMap = new NativeMultiHashMap <int3, SpatialMapData>(1, Allocator.Persistent); spatialMap.Add(int3.zero, new SpatialMapData() { position = position1 }); spatialMap.Add(int3.zero, new SpatialMapData() { position = position2 }); NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(2, Allocator.Persistent); agents[0] = new AgentKinematics() { position = position1, velocity = new float3(0, 0, 0) }; agents[1] = new AgentKinematics() { position = position2, velocity = new float3(0, 1, 0) }; NativeArray <float3> steering = new NativeArray <float3>(2, Allocator.Persistent); steering[0] = new float3(0, 1, 0); steering[1] = new float3(1, 0, 1); NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(2, Allocator.Persistent); for (int i = 0; i < 2; i++) { active[i] = AgentBehaviors.Queueing; } AgentWorld world = new AgentWorld() { scale = 1f, offset = float3.zero, center = new float3(0.5f, 0.5f, 0.5f), rotation = quaternion.identity, }; QueueBehavior job = new QueueBehavior() { maxBrakeForce = 0.8f, maxQueueAhead = 1f, maxQueueRadius = 1f, maxDepth = 100, world = world, size = new int3(1, 1, 1), spatialMap = spatialMap, steering = steering, behaviors = active, agents = agents }; job.Schedule(2, 1).Complete(); // first agent should be braking float3 expected = new float3(0, 0.2f, 0); Assert.AreEqual(true, Mathf.Approximately(expected.x, steering[0].x)); Assert.AreEqual(true, Mathf.Approximately(expected.y, steering[0].y)); Assert.AreEqual(true, Mathf.Approximately(expected.z, steering[0].z)); // second agent should not be braking expected = new float3(1, 0, 1); Assert.AreEqual(true, Mathf.Approximately(expected.x, steering[1].x)); Assert.AreEqual(true, Mathf.Approximately(expected.y, steering[1].y)); Assert.AreEqual(true, Mathf.Approximately(expected.z, steering[1].z)); spatialMap.Dispose(); steering.Dispose(); agents.Dispose(); active.Dispose(); }
// Use this for initialization void Start() { agentManager = FindObjectOfType <AgentWorld>(); phosphorManager = FindObjectOfType <PhosphorManager>(); }
// Use this for initialization void Start() { cloudMaterial = new Material(cloudShader); world = FindObjectOfType <AgentWorld>(); cloudMaterial.SetFloat("timeOffset", Random.value); }
public void UpdatesDirections() { NativeArray <float3> directions = new NativeArray <float3>(1, Allocator.Persistent); NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(1, Allocator.Persistent); agents[0] = new AgentKinematics() { position = Vector3.up }; NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(1, Allocator.Persistent); active[0] = AgentBehaviors.Seeking; NativeArray <byte> flowField = new NativeArray <byte>(1, Allocator.Persistent); NativeArray <int3> flowDirections = new NativeArray <int3>(27, Allocator.Persistent); for (int i = 0; i < 1; i++) { flowField[i] = (byte)Direction3Int.Name.Up; } for (int i = 0; i < 27; i++) { Vector3Int dir = Direction3Int.Directions[i]; flowDirections[i] = new int3(dir.x, dir.y, dir.z); } NativeArray <int> agentMovementTypes = new NativeArray <int>(1, Allocator.Persistent); NativeArray <AgentMovement> movementTypes = new NativeArray <AgentMovement>(1, Allocator.Persistent); movementTypes[0] = new AgentMovement() { mass = 1f, topSpeed = 1f, turnSpeed = 1f }; AgentWorld world = new AgentWorld() { scale = 1f, offset = float3.zero, center = new float3(0.5f, 0.5f, 0.5f), rotation = quaternion.identity, }; FlowFieldSeekJob job = new FlowFieldSeekJob() { movementTypes = movementTypes, agentMovement = agentMovementTypes, world = world, flowField = flowField, flowDirections = flowDirections, flowFieldSize = new int3(1, 1, 1), agents = agents, steering = directions, behaviors = active, }; JobHandle handle = job.Schedule(1, 1); handle.Complete(); Assert.AreEqual(new float3(0, 1, 0), directions[0]); flowDirections.Dispose(); flowField.Dispose(); directions.Dispose(); agents.Dispose(); active.Dispose(); movementTypes.Dispose(); agentMovementTypes.Dispose(); }
public void AvoidsNearbyAgents() { float3 position1 = float3.zero; float3 position2 = new float3(0f, 1f, 0f); float3 max = new float3(float.MaxValue, float.MaxValue, float.MaxValue); NativeMultiHashMap <int3, SpatialMapData> spatialMap = new NativeMultiHashMap <int3, SpatialMapData>(1, Allocator.Persistent); spatialMap.Add(int3.zero, new SpatialMapData() { position = position1 }); spatialMap.Add(int3.zero, new SpatialMapData() { position = position2 }); NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(2, Allocator.Persistent); agents[0] = new AgentKinematics() { position = position1, velocity = new float3(0, 0, 0) }; agents[1] = new AgentKinematics() { position = position2, velocity = new float3(0, 1, 0) }; NativeArray <float3> steering = new NativeArray <float3>(2, Allocator.Persistent); NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(2, Allocator.Persistent); AgentBehaviors flags = AgentBehaviors.Avoiding; for (int i = 0; i < 2; i++) { active[i] = flags; } AgentWorld world = new AgentWorld() { scale = 1f, offset = float3.zero, center = new float3(0.5f, 0.5f, 0.5f), rotation = quaternion.identity, }; AvoidCollisionBehavior job = new AvoidCollisionBehavior() { avoidDistance = 1f, avoidRadius = 1f, avoidForce = 1f, maxDepth = 100, world = world, size = new int3(1, 1, 1), spatialMap = spatialMap, steering = steering, behaviors = active, agents = agents, }; job.Schedule(2, 1).Complete(); Assert.AreEqual(new float3(0, -1, 0), steering[0]); Assert.AreEqual(new float3(0, 0, 0), steering[1]); spatialMap.Dispose(); steering.Dispose(); agents.Dispose(); active.Dispose(); }
public void UpdatesPositionAndRotation() { Transform[] transforms = new Transform[2]; transforms[0] = GameObject.CreatePrimitive(PrimitiveType.Cube).transform; transforms[1] = GameObject.CreatePrimitive(PrimitiveType.Cube).transform; TransformAccessArray asyncTransforms = new TransformAccessArray(transforms); NativeArray <AgentKinematics> agents = new NativeArray <AgentKinematics>(2, Allocator.Persistent); agents[0] = new AgentKinematics() { maxSpeed = 1f }; agents[1] = new AgentKinematics() { maxSpeed = 1f }; NativeArray <float3> directions = new NativeArray <float3>(2, Allocator.Persistent); directions[0] = Vector3.right; directions[1] = Vector3.left; NativeArray <byte> flowField = new NativeArray <byte>(1, Allocator.Persistent); for (int i = 0; i < 1; i++) { flowField[i] = 1; } NativeArray <AgentBehaviors> active = new NativeArray <AgentBehaviors>(2, Allocator.Persistent); for (int i = 0; i < 2; i++) { active[i] = AgentBehaviors.Active; } NativeArray <int> agentMovementTypes = new NativeArray <int>(2, Allocator.Persistent); NativeArray <AgentMovement> movementTypes = new NativeArray <AgentMovement>(1, Allocator.Persistent); movementTypes[0] = new AgentMovement() { mass = 1f, topSpeed = 1f, turnSpeed = 1f }; AgentWorld world = new AgentWorld() { scale = 1f, offset = float3.zero, center = new float3(0.5f, 0.5f, 0.5f), rotation = quaternion.identity, }; MoveAgentJob job = new MoveAgentJob() { maxForce = 1f, movementTypes = movementTypes, agentMovement = agentMovementTypes, agents = agents, behaviors = active, steering = directions, deltaTime = Time.deltaTime, world = world, flowField = flowField, flowFieldSize = new int3(1, 1, 1) }; Vector3 position_0 = transforms[0].position; Vector3 position_1 = transforms[1].position; Quaternion rotation_0 = transforms[0].rotation; Quaternion rotation_1 = transforms[1].rotation; JobHandle handle = job.Schedule(asyncTransforms); handle.Complete(); Assert.AreNotEqual(position_0, transforms[0].position); Assert.AreNotEqual(position_1, transforms[1].position); Assert.AreNotEqual(rotation_0, transforms[0].rotation); Assert.AreNotEqual(rotation_1, transforms[1].rotation); agents.Dispose(); active.Dispose(); flowField.Dispose(); directions.Dispose(); asyncTransforms.Dispose(); agentMovementTypes.Dispose(); movementTypes.Dispose(); foreach (var t in transforms) { GameObject.DestroyImmediate(t.gameObject); } }
/// <summary> /// Schedules background jobs to move each agent in the scene by the given delta time /// </summary> protected JobHandle MoveByArchetype(int index, AgentWorld agentWorld, float dt, JobHandle dependsOn = default) { FlowFieldSeekJob seekJob = new FlowFieldSeekJob() { world = agentWorld, movementTypes = m_movementTypes, agentMovement = m_agentMovementTypes[index], flowField = m_flowFields[index], flowDirections = m_directions, flowFieldSize = agentWorld.size, behaviors = m_agentBehaviors[index], agents = m_agentKinematics[index], steering = m_agentSteering[index], }; JobHandle seekHandle = seekJob.Schedule(m_totalAgents[index], 1, dependsOn); AvoidCollisionBehavior avoidJob = new AvoidCollisionBehavior() { avoidForce = avoidForce, avoidRadius = avoidRadius, avoidDistance = avoidDistance, maxDepth = maxAvoidDepth, world = agentWorld, behaviors = m_agentBehaviors[index], agents = m_agentKinematics[index], steering = m_agentSteering[index], spatialMap = m_spatialMap, size = spatialBucketSize }; JobHandle avoidHandle = avoidJob.Schedule(m_totalAgents[index], 1, seekHandle); QueueBehavior queueJob = new QueueBehavior() { maxDepth = maxQueueDepth, maxBrakeForce = brakeForce, maxQueueRadius = queueRadius, maxQueueAhead = queueDistance, world = agentWorld, behaviors = m_agentBehaviors[index], agents = m_agentKinematics[index], steering = m_agentSteering[index], size = spatialBucketSize, spatialMap = m_spatialMap }; JobHandle queueHandle = queueJob.Schedule(m_totalAgents[index], 1, avoidHandle); StoppingBehavior stopJob = new StoppingBehavior() { maxBrakeForce = brakeForce, agents = m_agentKinematics[index], steering = m_agentSteering[index], behaviors = m_agentBehaviors[index] }; JobHandle stopHandle = stopJob.Schedule(m_totalAgents[index], 1, queueHandle); CollisionBehavior collisionJob = new CollisionBehavior() { movementConfigs = m_movementTypes, movement = m_agentMovementTypes[index], collision = archetypes[index].collision, minDistance = minCollisionDistance, minForce = minCollisionForce, maxDepth = maxCollisionDepth, world = agentWorld, behaviors = m_agentBehaviors[index], agents = m_agentKinematics[index], steering = m_agentSteering[index], spatialMap = m_spatialMap, size = spatialBucketSize }; JobHandle collisionHandle = collisionJob.Schedule(m_totalAgents[index], 1, stopHandle); GravityBehavior gravityJob = new GravityBehavior() { world = agentWorld, behaviors = m_agentBehaviors[index], agents = m_agentKinematics[index], steering = m_agentSteering[index], blocks = m_blockTypes[index], voxels = world.data.voxels, gravity = new float3( gravity.x, gravity.y, gravity.z ), }; JobHandle gravityHandle = gravityJob.Schedule(m_totalAgents[index], 1, collisionHandle); MoveAgentJob moveJob = new MoveAgentJob() { maxForce = maxForce, movementTypes = m_movementTypes, agentMovement = m_agentMovementTypes[index], world = agentWorld, behaviors = m_agentBehaviors[index], agents = m_agentKinematics[index], steering = m_agentSteering[index], deltaTime = dt, flowField = m_flowFields[index], flowFieldSize = agentWorld.size, }; return(moveJob.Schedule(m_transformAccess[index], gravityHandle)); }