Пример #1
0
        public void Execute(int i, TransformAccess transform)
        {
            AgentBehaviors mask = AgentBehaviors.Active;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            float mass   = movementConfigs[movement[i]].mass;
            int3  grid   = GridPosition(transform.position);
            int3  bucket = new int3(
                grid.x / size.x,
                grid.y / size.y,
                grid.z / size.z
                );

            Agents.AgentKinematics agent = agents[i];
            agent.position = transform.position;
            agents[i]      = agent;

            SpatialMapData data = new SpatialMapData();

            data.position = transform.position;
            data.height   = collision.height;
            data.radius   = collision.radius;
            data.mass     = mass;

            spatialMap.Add(bucket, data);
        }
Пример #2
0
    /// <summary>
    /// Adds a new agent to the scene
    /// </summary>
    public NavAgent Spawn(Vector3 position)
    {
        int      index = Random.Range(0, agentsToSpawn.Count);
        NavAgent agent = Poolable.TryGetPoolable <NavAgent>(
            agentsToSpawn[index].gameObject);

        agent.transform.localScale = Vector3.one * world.scale;
        agent.transform.rotation   = world.transform.rotation;
        agent.transform.position   = position;
        agent.gameObject.SetActive(true);

        NavAgentArchetype archetype            = agent.configuration.archetype;
        int archetypeIndex                     = agentManager.archetypes.IndexOf(archetype);
        NativeArray <AgentBehaviors> behaviors = agentManager.agentBehaviors[archetypeIndex];

        // set the agent's navigation behaviors
        AgentBehaviors flags = AgentBehaviors.Active
                               | AgentBehaviors.Queueing
                               | AgentBehaviors.Avoiding
                               | AgentBehaviors.Seeking;

        NativeSlice <AgentBehaviors> slice      = behaviors.Slice(agent.index, 1);
        SetAgentBehaviors            activation = new SetAgentBehaviors()
        {
            flags = flags, behaviors = slice
        };

        activation.Schedule(1, 1).Complete();

        return(agent);
    }
Пример #3
0
        public void Execute(int i)
        {
            AgentBehaviors mask = AgentBehaviors.Active;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            AgentKinematics agent = agents[i];
            float3          min   = agent.position + new float3(-collision.radius, -collision.radius, -collision.radius);
            float3          max   = agent.position + new float3(collision.radius, collision.radius, collision.radius);

            int3 minBucket = GetSpatialBucket(min);
            int3 maxBucket = GetSpatialBucket(max);

            if (minBucket.Equals(maxBucket))
            {
                ResolveCollisions(i, minBucket);
            }
            else
            {
                ResolveCollisions(i, minBucket, maxBucket);
            }
        }
Пример #4
0
        public void Execute(int i)
        {
            AgentBehaviors mask = AgentBehaviors.Queueing;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            AgentKinematics agent     = agents[i];
            float3          direction = math.normalizesafe(agent.velocity, float3.zero);
            float3          ahead     = agent.position + direction * maxQueueAhead;

            float3 min = ahead + new float3(-maxQueueRadius, -maxQueueRadius, -maxQueueRadius);
            float3 max = ahead + new float3(maxQueueRadius, maxQueueRadius, maxQueueRadius);

            int3 minBucket = GetSpatialBucket(min);
            int3 maxBucket = GetSpatialBucket(max);

            bool obstructed;

            if (minBucket.Equals(maxBucket))
            {
                obstructed = DetectCollision(i, ahead, minBucket);
            }
            else
            {
                obstructed = DetectCollision(i, ahead, minBucket, maxBucket);
            }

            if (obstructed)
            {
                ApplyBrakeForce(i);
            }
        }
Пример #5
0
        public void Execute(int i)
        {
            AgentBehaviors mask = AgentBehaviors.Active;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            AgentKinematics agent = agents[i];
            int3            grid  = GridPosition(agent.position);

            grid += new int3(0, -1, 0);

            byte voxel = voxels[Flatten(grid)];

            if (OverAir(voxel))
            {
                steering[i] += gravity;
            }
            if (InSolid(voxel))
            {
                steering[i] += gravity * -0.5f;
            }
        }
Пример #6
0
        public void Execute(int i)
        {
            AgentBehaviors mask = AgentBehaviors.Stopping;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            ApplyBrakeForce(i);
        }
Пример #7
0
    /// <summary>
    /// Adds multiple agents randomly in the scene
    /// </summary>
    public void SpawnAgents(int count)
    {
        Vector3    position = Vector3.zero;
        Vector3Int grid     = Vector3Int.zero;
        Vector2    center   = new Vector2(
            world.size.x / 2,
            world.size.z / 2
            );

        for (int i = 0; i < count; i++)
        {
            // choose a random (x,z) position inside a circle
            Vector2 randomXZ = Random.insideUnitCircle;
            randomXZ *= world.size.x / 2;
            randomXZ += center;

            // update the agents grid position and
            // convert the grid position to world space
            grid.x   = (int)randomXZ.x; grid.z = (int)randomXZ.y;
            grid.y   = heightMap.Read(grid.x, grid.z) + 1;
            position = world.GridToScene(grid);

            // spawn the new enemy agent
            int      index = Random.Range(0, agentsToSpawn.Count);
            NavAgent agent = Poolable.TryGetPoolable <NavAgent>(
                agentsToSpawn[index].gameObject);

            agent.transform.localScale = Vector3.one * world.scale;
            agent.transform.rotation   = world.transform.rotation;
            agent.transform.position   = position;
            agent.gameObject.SetActive(true);

            // enable the agents navigation behaviors to SEEK, QUEUE, and AVOID

            NavAgentArchetype archetype            = agent.configuration.archetype;
            int archetypeIndex                     = agentManager.archetypes.IndexOf(archetype);
            NativeArray <AgentBehaviors> behaviors = agentManager.agentBehaviors[archetypeIndex];

            AgentBehaviors flags = AgentBehaviors.Active
                                   | AgentBehaviors.Queueing
                                   | AgentBehaviors.Avoiding
                                   | AgentBehaviors.Seeking;

            NativeSlice <AgentBehaviors> slice      = behaviors.Slice(agent.index, 1);
            SetAgentBehaviors            activation = new SetAgentBehaviors()
            {
                flags = flags, behaviors = slice
            };
            activation.Schedule(1, 1).Complete();
        }
    }
Пример #8
0
        public void Execute(int i)
        {
            AgentBehaviors mask = AgentBehaviors.Avoiding;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            AgentKinematics agent         = agents[i];
            float           dynamicLength = math.length(agent.velocity) / avoidDistance;
            float3          direction     = math.normalizesafe(agent.velocity, float3.zero);
            float3          closest       = new float3(float.MaxValue, float.MaxValue, float.MaxValue);

            float3 ahead  = agent.position + direction * dynamicLength;
            float3 ahead2 = agent.position + direction * dynamicLength * 0.5f;

            float3 min  = ahead + new float3(-avoidRadius, -avoidRadius, -avoidRadius);
            float3 max  = ahead + new float3(avoidRadius, avoidRadius, avoidRadius);
            float3 min2 = ahead2 + new float3(-avoidRadius, -avoidRadius, -avoidRadius);
            float3 max2 = ahead2 + new float3(avoidRadius, avoidRadius, avoidRadius);

            int3 minBucket = math.min(GetSpatialBucket(min), GetSpatialBucket(min2));
            int3 maxBucket = math.max(GetSpatialBucket(max), GetSpatialBucket(max2));

            bool shouldAvoid;

            if (minBucket.Equals(maxBucket))
            {
                shouldAvoid = DetectObstruction(i, ahead, ahead2, minBucket, ref closest);
            }
            else
            {
                shouldAvoid = DetectObstruction(i, ahead, ahead2, minBucket, maxBucket, ref closest);
            }

            if (shouldAvoid)
            {
                ApplyAvoidanceForce(i, ahead, closest);
            }
        }
Пример #9
0
    /// <summary>
    /// Removes an agent from the scene
    /// </summary>
    public void Remove(Enemy enemy)
    {
        NavAgent agent = enemy.GetComponent <NavAgent>();

        Poolable.TryPool(agent.gameObject);

        // set the agent's navigation behaviors to NONE

        NavAgentArchetype archetype            = agent.configuration.archetype;
        int archetypeIndex                     = agentManager.archetypes.IndexOf(archetype);
        NativeArray <AgentBehaviors> behaviors = agentManager.agentBehaviors[archetypeIndex];
        AgentBehaviors flags                   = AgentBehaviors.None;

        NativeSlice <AgentBehaviors> slice      = behaviors.Slice(agent.index, 1);
        SetAgentBehaviors            activation = new SetAgentBehaviors()
        {
            flags = flags, behaviors = slice
        };

        activation.Schedule(1, 1).Complete();
    }
Пример #10
0
        public void Execute(int i)
        {
            AgentBehaviors mask = AgentBehaviors.Seeking;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            AgentKinematics agent = agents[i];
            int3            grid  = GridPosition(agent.position);

            grid += new int3(0, -1, 0);

            if (OutOfBounds(grid))
            {
                steering[i] = float3.zero;
                return;
            }

            int  fieldIndex     = Flatten(grid);
            byte directionIndex = flowField[fieldIndex];

            if (directionIndex == 0)    // no direction
            {
                steering[i] = float3.zero;
                return;
            }

            int3   flowDirection = flowDirections[directionIndex];
            int3   nextGrid      = grid + flowDirection + new int3(0, 1, 0);
            float3 nextPosition  = ScenePosition(nextGrid);

            float3 desired = nextPosition - agent.position;

            desired  = math.normalizesafe(desired, float3.zero);
            desired *= movementTypes[agentMovement[i]].topSpeed;

            steering[i] = desired - agent.velocity;
        }
Пример #11
0
        public void Execute(int i, TransformAccess transform)
        {
            AgentBehaviors mask = AgentBehaviors.Active;

            if ((behaviors[i] & mask) == 0)
            {
                return;
            }

            float3     up       = new float3(0, 1, 0);
            float3     position = transform.position;
            quaternion rotation = transform.rotation;

            AgentMovement   movement = movementTypes[agentMovement[i]];
            AgentKinematics agent    = agents[i];

            steering[i] = Clamp(steering[i], maxForce);
            steering[i] = steering[i] / movement.mass;

            agent.velocity = Clamp(agent.velocity + steering[i], agent.maxSpeed);
            steering[i]    = float3.zero; // reset steering forces for next frame
            agents[i]      = agent;       // update the kinematics for the next frame

            float3 nextPosition = agent.position + agent.velocity * deltaTime;
            int3   nextGrid     = GridPosition(nextPosition);

            if (OutOfBounds(nextGrid))
            {
                return;
            }
            transform.position = nextPosition;

            if (agent.velocity.Equals(float3.zero))
            {
                return;
            }
            quaternion look = quaternion.LookRotation(agent.velocity, up);

            transform.rotation = math.slerp(rotation, look, movement.turnSpeed * deltaTime);
        }
Пример #12
0
        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();
        }