官术网_书友最值得收藏!

Creating a group of followers

In this example, we're going to build another AI type called a follower agent. This time, a group of followers will stay together and move toward their leader. The leader, on the other hand, is still the same seeking agent that will randomly move around the sandbox, completely oblivious to the group of followers behind it.

Group-based movement using separation, cohesion, and alignment

To create followers, we'll use multiple steering forces to combine, separate, and align our agents to the leader agent they are following.

Create the Lua file as follows:

src/my_sandbox/script/FollowerAgent.lua

FollowerAgent.lua:

require "AgentUtilities";

local leader;

function Agent_Initialize(agent)
    AgentUtilities_CreateAgentRepresentation(
        agent, agent:GetHeight(), agent:GetRadius());

    -- Randomly assign a position to the agent.
    agent:SetPosition(Vector.new(
        math.random(-50, 50), 0, math.random(-50, 50)));

    -- Assign the first valid agent as the leader to follow.
    local agents = Sandbox.GetAgents(agent:GetSandbox());
    for index = 1, #agents do
        if (agents[index] ~= agent) then
            leader = agents[index];
            break;
        end
    end
end

function Agent_Update(agent, deltaTimeInMillis)
    local deltaTimeInSeconds = deltaTimeInMillis / 1000;
    local sandboxAgents = Sandbox.GetAgents(agent:GetSandbox());

    -- Calculate a combining force so long as the leader stays
    -- within a 100 meter range from the agent, and has less than
    -- 180 degree difference in forward direction.
    local forceToCombine =
        Agent.ForceToCombine(agent, 100, 180, { leader } );

    -- Force to stay away from other agents that are closer than
    -- 2 meters and have a maximum forward degree difference of
    -- less than 180 degrees.
    local forceToSeparate =
        Agent.ForceToSeparate(agent, 2, 180, sandboxAgents );

    -- Force to stay away from getting too close to the leader if
    -- within 5 meters of the leader and having a maximum forward
    -- degree difference of less than 45 degrees.
    local forceToAlign =
        Agent.ForceToSeparate(agent, 5, 45, { leader } );

    -- Summation of all separation and cohesion forces.
    local totalForces =
        forceToCombine + forceToSeparate * 1.15 + forceToAlign;
    
    -- Apply all steering forces.
    AgentUtilities_ApplyPhysicsSteeringForce(
        agent, totalForces, deltaTimeInSeconds);
    AgentUtilities_ClampHorizontalSpeed(agent);
    
    local targetRadius = agent:GetTargetRadius();
    local position = agent:GetPosition();
    local destination = leader:GetPosition();
    
    -- Draw debug information for target and target radius.
    Core.DrawCircle(
        position, 1, Vector.new(1, 1, 0));
    Core.DrawCircle(
        destination, targetRadius, Vector.new(1, 0, 0));
    Core.DrawLine(position, destination, Vector.new(0, 1, 0));
end

Our following agent is very similar to the pathing agent; it first finds a leader during the initialization and then uses cohesion and alignment steering forces to try and stay as close to the leader as possible while using a separation force at the same time to stay at least two meters away from all other agents, including the leader:

Sandbox.lua:

function Sandbox_Initialize(sandbox)

    ...
    
    -- Create a pursuing agent to follow the seeking agent.
    Sandbox.CreateAgent(sandbox, "PursuingAgent.lua");

    -- Create a group of followers that follow the seeking agent.
    for i=1, 5 do
        Sandbox.CreateAgent(sandbox, "FollowerAgent.lua");
    end

    ...

end

Creating five followers and drawing debug circles around them for their separation areas makes it very easy to see how each force applies to the agent's movements.

Creating a group leader and followers.

主站蜘蛛池模板: 麻栗坡县| 商城县| 资溪县| 和政县| 河西区| 包头市| 黄龙县| 邓州市| 体育| 京山县| 黎川县| 锦屏县| 平阳县| 福清市| 垫江县| 高阳县| 泰宁县| 平利县| 玉山县| 玉山县| 古蔺县| 云龙县| 大宁县| 上杭县| 宜城市| 甘孜县| 志丹县| 浪卡子县| 武夷山市| 上虞市| 余姚市| 德州市| 东平县| 桐乡市| 阳原县| 华坪县| 长沙县| 金门县| 安平县| 榕江县| 莆田市|