Exemple #1
0
    private void InitAgents()
    {
        /// Iterate over each SquirrelInfo and configure
        foreach (AgentInfo truckInfo in AgentsInfo)
        {
            if (truckInfo.AgentPrefab == null || truckInfo.Start == null)
            {
                Debug.LogError($"SquirrelInfo is incorrectly configured!");
                continue;
            }

            /// instantiate the squirrel and add to list
            GameObject inst = Instantiate(truckInfo.AgentPrefab, m_agentParent);
            m_instantiatedAgents.Add(inst);

            /// Get the Aware component and listen to events and set move path
            ACOTruck acoTruck = inst.GetComponent <ACOTruck>();
            if (acoTruck)
            {
                acoTruck.Cargo.AddPackages(truckInfo.CargoAmount);

                /// Create ACOConnection list between each goal location
                List <ACOConnection> goalACOConnections = CalculateGoalsAndRoutes(truckInfo.Goals);

                /// Get the closest ACO goal node to use as start
                GameObject acoPathFirstNode = GetClosestACOGoalNodeToPosition(goalACOConnections, truckInfo.Start.transform.position);

                // Calculate ACO path from all waypoints, using the ACOConnections generated
                List <ACOConnection> route = this.GenerateACOPath(AntColonyConfig.MaximumIterations,
                                                                  AntColonyConfig.Ants,
                                                                  m_allWaypoints.ToArray(),
                                                                  goalACOConnections,
                                                                  acoPathFirstNode,
                                                                  AntColonyConfig.MaxPathLength);

                /// Get last ACO node to calculate A* path back to target start position
                GameObject acoPathLastNode = route.LastOrDefault().ToNode;

                /// A* calculate paths from start to ACO start, and from ACO end to start
                List <Connection> startToACOStart = this.NavigateAStar(truckInfo.Start, acoPathFirstNode);
                List <Connection> acoEndToStart   = this.NavigateAStar(acoPathLastNode, truckInfo.Start);

                /// Set this agent to move along ACO path
                acoTruck.SetMovePath(startToACOStart, route, acoEndToStart);

                /// Register to listen to events of trucks
                acoTruck.OnTravelNewConnection += OnTruckTravelNewConnection;
                acoTruck.OnReachedGoal         += OnAgentReachedACOGoal;
            }
            else
            {
                Debug.LogError($"Missing ACOTruck script on Prefab '{truckInfo.AgentPrefab.name}'!");
            }
        }
    }
Exemple #2
0
 private void OnTruckTravelNewConnection(ACOTruck truck, IConnection targetTravelConnection)
 {
     // Update or add new connection to list
     if (m_currentTruckConnections.ContainsKey(truck))
     {
         m_currentTruckConnections[truck] = targetTravelConnection;
     }
     else
     {
         m_currentTruckConnections.Add(truck, targetTravelConnection);
     }
 }
Exemple #3
0
    public void Update()
    {
        if (m_currentTruckConnections.Count > 0)
        {
            /// For each truck and it's current connection
            foreach (KeyValuePair <ACOTruck, IConnection> thisKvp in m_currentTruckConnections)
            {
                /// Compare waypoint names to check if they are the same
                KeyValuePair <ACOTruck, IConnection> matchingKvp = m_currentTruckConnections
                                                                   .FirstOrDefault(kvp => kvp.Value.ToNode.name == thisKvp.Value.ToNode.name && kvp.Key.name != thisKvp.Key.name);
                ACOTruck truckOne = thisKvp.Key;
                ACOTruck truckTwo = matchingKvp.Key;

                /// If current iterarte truck is waiting, check if they can resume
                /// Only check truck one as the others will be checked next iteration
                if (truckOne.IsWaiting)
                {
                    List <ACOTruck> waitingTrucks      = new List <ACOTruck>();
                    bool            isOnSameConnection = false;
                    foreach (KeyValuePair <ACOTruck, IConnection> checkKvp in m_currentTruckConnections)
                    {
                        if (!checkKvp.Key.IsWaiting)
                        {
                            continue;
                        }

                        if (thisKvp.Value.ToNode.name == checkKvp.Value.ToNode.name)
                        {
                            //isOnSameConnection = true;
                            waitingTrucks.Add(checkKvp.Key);
                        }
                    }

                    // More than 1 truck waiting at same connection, resume first one in list
                    if (waitingTrucks.Count > 1)
                    {
                        waitingTrucks[0].ResumeMovement();
                        Debug.Log($"Resuming Truck '{waitingTrucks[0]}' in queue of '{waitingTrucks.Count}'");
                    }
                    // else if truckOne has no others waiting, resume
                    else if (!isOnSameConnection)
                    {
                        truckOne.ResumeMovement();
                        Debug.Log($"Resuming Truck '{truckOne.name}'");
                    }
                }

                // Check match isn't null
                if (matchingKvp.Key != null && matchingKvp.Value != null)
                {
                    /// If isn't waiting and connections are matching...
                    bool eitherTruckWaiting = truckOne.IsWaiting || truckTwo.IsWaiting;
                    if (!eitherTruckWaiting && thisKvp.Value.ToNode.name == matchingKvp.Value.ToNode.name)
                    {
                        if (truckOne.Cargo.PackageCount > truckTwo.Cargo.PackageCount)
                        {
                            ///truckOne is slower, pause it
                            truckOne.PauseMovement();
                            Debug.Log($"Pausing Truck '{truckOne.name};");
                        }
                        else
                        {
                            /// truckTwo is slower
                            /// or cargo is same so prioritise truckTwo
                            truckTwo.PauseMovement();
                            Debug.Log($"Pausing Truck '{truckTwo.name}'");
                        }
                    }
                }
            }
        }
    }
Exemple #4
0
 private void OnAgentReachedACOGoal(ACOTruck agent, GameObject acoGoal)
 {
     agent.DeliverPackage();
 }