public void initializeController(GameObject[] agents, Vector2[] boundingPoly, World.TrajectoryMap trajectory, Vector2[] formationPositions, float agentHeight, float deltaX, float deltaY, float simulationFactor, float vehicleDt, bool formationDecreasingGoalVelocity) { this.simulationSpeedFactor = simulationFactor; this.vehicleDt = vehicleDt; this.agentHeight = agentHeight; this.agents = agents; this.formationDecreasingGoalVelocity = formationDecreasingGoalVelocity; // Get trajectory coordinates this.trajectory = new Vector3[trajectory.x.Length]; for (int i = 0; i < trajectory.x.Length; i++) { this.trajectory [i] = new Vector3(trajectory.x [i], agentHeight, trajectory.y [i]); } // Get trajectory orientations this.trajectoryOrientation = new float[trajectory.theta.Length]; for (int i = 0; i < trajectory.theta.Length; i++) { this.trajectoryOrientation [i] = trajectory.theta [i]; } // Get timestamps for each step of the trajectory this.trajectoryTimestamps = new float[trajectory.t.Length]; for (int i = 0; i < trajectory.t.Length; i++) { this.trajectoryTimestamps [i] = trajectory.t [i]; } // set formationPositions in parent class to relative positions from the virtual center setRelativeFormationPositions(formationPositions, formationPositions.Length - 1); // Get starting absolute positions and relative to the leader positions. this.desiredRelativePositions = getDesiredPositions(agents.Length - 1, false); this.desiredAbsolutePositions = getDesiredPositions(agents.Length - 1); // Visualize starting desired positions //Visualizer.visualizePoints(this.desiredRelativePositions); //Visualizer.visualizePoints(this.desiredAbsolutePositions); // Set a controller within each agent agents [0].AddComponent <LeaderController> (); for (int i = 1; i < agents.Length; i++) { agents [i].AddComponent <FootballPlayerController> (); } formationRectangle = new VirtualStructureRectangle(formationPositions, boundingPoly, deltaX, deltaY, agentHeight); // Get nearest agent to opponent player winnerIdx = agents.Length - 1; for (int t = 1; t < agents.Length - 1; t++) { // Get closest player to opponent float minDistance = float.MaxValue; for (int i = 1; i < agents.Length - 1; i++) { // If this agent has failed moving before, due to moving the formation out of the polygon float distance = Vector2.Distance(new Vector2(agents[0].transform.position.x, agents[0].transform.position.z), getDesiredPosition(i - 1)); if (distance < minDistance) { minDistance = distance; winnerIdx = i; } } } currentVelocities = new Vector3[agents.Length]; }
public VirtualStructureRectangle(VirtualStructureRectangle structure) { center = new Vector3(structure.center.x, structure.center.y, structure.center.z); vertices = new PointInfo[structure.vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new PointInfo(structure.vertices[i].pos, structure.vertices[i].vel, structure.vertices[i].orientation, structure.vertices[i].currentTime); } }
private bool moveNearestAgent(Vector3 target, int nearestAgentIdx) { // Get next position information of the nearestAgentIdx FootballPlayerController nearestAgentController = agents[nearestAgentIdx].GetComponent <FootballPlayerController>(); PointInfo lastPos = nearestAgentController.getLastPosInfo(); BaseModel model = nearestAgentController.getMotionModel(); PointInfo nextPoint; if (formationDecreasingGoalVelocity) { PointInfo goalPointInfo = new PointInfo(target, Vector3.zero, Vector3.forward, lastPos.currentTime + vehicleDt); nextPoint = model.moveTowardsWithDecreasingVelocity(lastPos, goalPointInfo, nearestAgentController.getWorld(), false); } else { PointInfo goalPointInfo = new PointInfo(target, getAgentVelocity(0), getAgentOrientation(0), lastPos.currentTime + vehicleDt); List <PointInfo> path = model.completePath(lastPos, goalPointInfo, nearestAgentController.getWorld(), false); if (path != null && path.Count > 0) { nextPoint = path [0]; } else { return(false); } } nearestAgentController.getWorld().currentVelocities[nearestAgentIdx - 1] = nextPoint.vel; setCurrentVelocity(nearestAgentIdx, nextPoint.vel); // Get previous position of agent Vector3 prevPos = new Vector3(agents[nearestAgentIdx].transform.position.x, agents[nearestAgentIdx].transform.position.y, agents[nearestAgentIdx].transform.position.z); agents[nearestAgentIdx].transform.position = nextPoint.pos; Vector2[] tmpDesiredRelativePositions = getDesiredPositions(winnerIdx, false, false); // Store previous positional information Vector2[] prevRelativeFormationPositions = new Vector2[this.relativeFormationPositions.Length]; for (int i = 0; i < prevRelativeFormationPositions.Length; i++) { prevRelativeFormationPositions [i] = new Vector2(this.relativeFormationPositions[i].x, this.relativeFormationPositions[i].y); } Vector2[] prevDesiredRelative = getDesiredPositions(winnerIdx, false, false); Vector2[] prevDesiredAbsolute = getDesiredPositions(winnerIdx, false, true); // Calculate new positional information setRelativeFormationPositions(this.relativeFormationPositions, nearestAgentIdx - 1); this.desiredRelativePositions = getDesiredPositions(winnerIdx, false, false); this.desiredAbsolutePositions = getDesiredPositions(winnerIdx, false, true); // Get virtual center controller and its last position FootballPlayerController virtualCenterController = agents[agents.Length - 1].GetComponent <FootballPlayerController>(); PointInfo lastCenterPos = virtualCenterController.getLastPosInfo(); // Move center in the same way the nearest agent moves, anchoring the formation to the agent Vector2 desiredCenterPosition = getDesiredPosition(agents.Length - 2); Vector3 desiredCenter3D = new Vector3(desiredCenterPosition.x, agentHeight, desiredCenterPosition.y); // Get copy of formation rectangle VirtualStructureRectangle tmp = new VirtualStructureRectangle(formationRectangle); // Update rectangle with new desired center tmp.updateRectangle(desiredCenter3D); // Check if new rectangle gets out of the bounding polygon in case the agent is not already near the boundary if (lastPos.currentTime > 30.0f && !tmp.isInPolygon(nearestAgentController.getWorld().boundingPolygon)) { // If it is not entirely inside, restore changes and return false agents[nearestAgentIdx].transform.position = prevPos; this.relativeFormationPositions = prevRelativeFormationPositions; this.desiredAbsolutePositions = prevDesiredAbsolute; this.desiredRelativePositions = prevDesiredRelative; return(false); } // Otherwise make all necessary changes to variables of the closest agent and formation center agents[nearestAgentIdx].transform.position = prevPos; agents [nearestAgentIdx].transform.LookAt(agents[nearestAgentIdx].transform.position + (target - agents[nearestAgentIdx].transform.position).normalized); PointInfo nextPos = new PointInfo(nextPoint.pos, Vector3.zero, nextPoint.orientation, nextPoint.currentTime + vehicleDt); nearestAgentController.setNextPosInfo(nextPoint); agents [agents.Length - 1].transform.position = desiredCenter3D; lastCenterPos.pos = desiredCenter3D; lastCenterPos.vel = nextPoint.vel; lastCenterPos.orientation = nextPoint.orientation; lastCenterPos.currentTime = nextPoint.currentTime; formationRectangle = tmp; agents [agents.Length - 1].transform.LookAt(agents[agents.Length - 1].transform.position + (target - agents[agents.Length - 1].transform.position).normalized); virtualCenterController.setLastPosInfo(lastCenterPos); nextPos = new PointInfo(lastCenterPos.pos, Vector3.zero, lastCenterPos.orientation, lastCenterPos.currentTime + vehicleDt); virtualCenterController.setNextPosInfo(nextPos); virtualCenterController.setPlay(false); return(true); }