// Update is called once per frame void FixedUpdate() { Vector3 newPosition = transform.position; if (prevPosition.Equals(newPosition) == false) { Debug.LogError("obstacle has moved"); Vector3[] posChange = new Vector3[2]; // {oldPos, newPos} posChange[0] = prevPosition; posChange[1] = transform.position; // this event goes to all grid navigation tasks that have encountered this obstacle during its planning observable.notifyObservers(Event.NON_DETERMINISTIC_OBSTACLE_CHANGED, posChange); if (GlobalNavigator.usingDynamicNavigationMesh == true) { polygonIndex = CentralizedManager.UpdatePolygonDictionary(transform.position, polygonIndex, this); } prevPosition = newPosition; transform.position = newPosition; } //transform.position = newPosition; }
// Use this for initialization void Start() { GlobalNavigator.navigationMeshChoice = navigationMeshChoice; GlobalNavigator.usingDynamicNavigationMesh = useDynamicNavigationMesh; CentralizedManager.Initialize(); CentralizedManager.textDisplayPrefab = textDisplayPrefab; // so that all scripts can access it }
// Update is called once per frame void Update() { //transform.position = agentToFollow.transform.position; //Vector3 target = agentToFollow.steeringTarget; //float distance = Vector3.Distance(transform.position,target); if (GlobalNavigator.usingDynamicNavigationMesh) { polygonIndex = CentralizedManager.UpdatePolygonDictionary(transform.position, polygonIndex, null); } }
public bool IsOnOffMeshLink() { //Debug.Log ("is off mesh link " + CentralizedManager.IsOffMeshLink(currentState.getPosition())); //return offMeshLinkWayPoint[currentPlanExecutionIndex]; if (currentPlanExecutionIndex >= gridNavigationTasks.Count) { return(false); } Vector3 meshLinkStartPos = gridNavigationTasks[currentPlanExecutionIndex].goalState.getPosition(); if (CentralizedManager.IsOffMeshLink(meshLinkStartPos) == true) { Debug.LogError("on off mesh link " + currentPlanExecutionIndex + " " + meshLinkStartPos); } return(CentralizedManager.IsOffMeshLink(meshLinkStartPos)); }
public void notifyEvent(Event ev, System.Object data) { switch (ev) { case Event.GLOBAL_PATH_CHANGED: Debug.Log("the global path has changed, we must update the path"); // removing the agent from the polygons associated with the old path in the centralized manager if (GlobalNavigator.usingDynamicNavigationMesh) { for (int i = 0; i < numGlobalPathWaypoints; i++) { CentralizedManager.polygonDictionary[globalPathPolygonIndices[i]].agents.Remove(this); } } // probably make this an event handler if (GlobalNavigator.pathStatus != NavMeshPathStatus.PathInvalid) { // TODO :: do some checking how much plan has changed // ALSO, we could do some filtering here maybe --- sometimes it gives points which are very close to each otehr Debug.Log("number of points in nav mesh path " + GlobalNavigator.numberOfNodes); // we dont want to put in the start state, so starting from 1 int currentGlobalPathWaypoint = 0; for (int i = 1; i < GlobalNavigator.numberOfNodes; i++) { // should we round off here ... we prob want to round of when we give it to the discrete planner // TODO this rounding off might sometimes place it on an obstacle // either we make hte nav mesh more conservative (give it 0.5 boundary around obstracles) or do some check here Vector3 p = GlobalNavigator.path[i]; // check for off mesh link before rounding off -- only using x-z values // using previous point to determin because the dictionary keys in using the start point -- NOT ANY MORE bool offMeshLinkState = CentralizedManager.IsOffMeshLink(GlobalNavigator.path[i]); p.x = Mathf.Round(p.x); p.y = Mathf.Round(p.y); p.z = Mathf.Round(p.z); // TODO : maybe off mesh link has its own time computation float time = (GlobalNavigator.pathCost[i] / GlobalNavigator.totalPathCost) * (goalState._time - currentState._time); // we ignore points that are the same as the previos point in the nav mesh path if (currentGlobalPathWaypoint != 0 && globalPath[currentGlobalPathWaypoint - 1].positionEquals(p)) { continue; } // todo check for automatic offmesh link as well ... maybe we will just create all of them manually if (currentGlobalPathWaypoint < globalPath.Count) { // some global path nodes have been statically allocated if (currentGlobalPathWaypoint >= numGlobalPathWaypoints && offMeshLinkState == false) { // we are now introducing more waypoints than before -- we need to make these valid globalPath[currentGlobalPathWaypoint].notifyObservers(Event.GOAL_VALID); } } else { _addNewEmptyGlobalPathWayPointAtIndex(currentGlobalPathWaypoint); if (offMeshLinkState == false) { globalPath[currentGlobalPathWaypoint].notifyObservers(Event.GOAL_VALID); } } // TODO: here check if the position actually changed -- else no need to call setPosition -- which triggers goal change event globalPath[currentGlobalPathWaypoint].setPosition(p); // adding time computation // TODO : REMOVE TIME.TIME if (currentGlobalPathWaypoint == 0) { globalPath[currentGlobalPathWaypoint]._time = currentState._time + time; } else { globalPath[currentGlobalPathWaypoint]._time = globalPath[currentGlobalPathWaypoint - 1]._time + time; } // TODO COMPUTE SPEED // storing offmesh link state if (offMeshLinkState == true) // this is an offlink { globalPath[currentGlobalPathWaypoint].notifyObservers(Event.GOAL_INVALID); } // setting off mesh link offMeshLinkWayPoint[currentGlobalPathWaypoint] = offMeshLinkState; if (GlobalNavigator.usingDynamicNavigationMesh) { globalPathPolygonIndices[currentGlobalPathWaypoint] = GlobalNavigator.recastSteeringManager.GetClosestPolygon(p); // adding agent to the respective polygon in the centralized manager if (CentralizedManager.polygonDictionary.ContainsKey(globalPathPolygonIndices[currentGlobalPathWaypoint]) == false) { CentralizedManager.polygonDictionary.Add(globalPathPolygonIndices[currentGlobalPathWaypoint], new PolygonData()); } CentralizedManager.polygonDictionary[globalPathPolygonIndices[currentGlobalPathWaypoint]].agents.Add(this); } currentGlobalPathWaypoint++; } Debug.LogWarning("current " + currentGlobalPathWaypoint + " prev " + numGlobalPathWaypoints); for (int i = currentGlobalPathWaypoint; i < numGlobalPathWaypoints; i++) { // this loop is iterating through all states in globalPath which are currently inactive globalPath[i].notifyObservers(Event.GOAL_INVALID); } numGlobalPathWaypoints = currentGlobalPathWaypoint; } else { Debug.LogError("Path is invalid for agent"); // this does happen when the goal is on an obstacle } break; } }
// Update is called once per frame void Update() { //Debug.LogError("Agent Brain Update " + currentPlanExecutionIndex + " " + numGlobalPathWaypoints); // TODO // while time is remaining // pick current highest priority task and execute it // evaluate the status of the task -- and depending on status, evaluate new priority and add it back. // TODO : can exexcute multiple tasks ? float maxTime = 1.0F; Task task = taskManager.getHighestPriorityTask(); if (task != null) { Debug.Log("Executing task " + task.taskName); task.execute(maxTime); } else { //Debug.Log ("task manager does not have task"); } // clearing curves curves[0] = new AnimationCurve(); curves[1] = new AnimationCurve(); curves[2] = new AnimationCurve(); curves[3] = new AnimationCurve(); endTime = 0.0f; // assigning curves //Debug.LogError("num global points " + numGlobalPathWaypoints + " num space time paths " + spaceTimePaths.Count + " grid tasks " + gridNavigationTasks.Count); for (int i = currentPlanExecutionIndex; i < Mathf.Min(currentPlanExecutionIndex + numGlobalPathWaypoints, spaceTimePaths.Count); i++) { // TODO CHECK HERE IF THE SPACE TIME PLAN IS CURRENTLY VALID OR NOT if (offMeshLinkWayPoint[i] == true) // this one is an off mesh link -- does not have a space time path { spaceTimePaths[i].Clear(); // TODO GET MOST RECENT POSITION FOR BETTER VIEWING spaceTimePaths[i].Add(gridNavigationTasks[i].startState); spaceTimePaths[i].Add(gridNavigationTasks[i].goalState); } else if (gridNavigationTasks[i].spaceTimePathStatus == false) // not an off mesh link and does not have a path { break; } endTime = AnimationCurveHelper.GetPlanAnimationCurve(spaceTimePaths[i], curves); //Debug.LogError("we populated the curve till " + endTime); } // TODO CHECK HERE IF WE ARE CURRENTLY CONTROLLED BY THE MESH LINK if (moveAutomatically == true) { if (stop == false) { ExecuteNextAction(Time.deltaTime); } else { currentState._time += Time.deltaTime; // THIS HAPPENS WHEN OFF MESH LINK HAS CONTROL } } else if (Input.GetKeyDown(KeyCode.A)) { ExecuteNextAction(0.2f); } // monitoring positions of agents in the polygon dictionary if (GlobalNavigator.usingDynamicNavigationMesh) { currentPolygonIndex = CentralizedManager.UpdatePolygonDictionary(currentState.getPosition(), currentPolygonIndex, null); } if (text != null) { string t = ""; t = t + "global path " + numGlobalPathWaypoints.ToString() + "\n"; t = t + "Current plan execution index : " + currentPlanExecutionIndex.ToString() + "\n"; t = t + "current state " + currentState.getPosition().ToString() + " " + currentState._time.ToString() + " " + currentState._speed.ToString() + " \n"; for (int i = 0; i < gridNavigationTasks.Count; i++) { t = t + offMeshLinkWayPoint[i].ToString() + " grid task " + i.ToString() + " " + gridNavigationTasks[i].taskPriority.ToString() + " " + gridNavigationTasks[i].startState.getPosition().ToString() + " " + gridNavigationTasks[i].startState._time.ToString() + " " + gridNavigationTasks[i].goalState.getPosition().ToString() + " " + gridNavigationTasks[i].goalState._time.ToString() + " " + localPaths[i].Count.ToString() + " " + spaceTimePaths[i].Count.ToString() + "\n"; } text.text = t; } // trying text mesh int timeLeftForGlobalGoal = Mathf.RoundToInt(goalState._time - currentState._time); int timeLeftForCurrentWaypoint; if (goalReached == false) { timeLeftForCurrentWaypoint = Mathf.RoundToInt(gridNavigationTasks[currentPlanExecutionIndex].goalState._time - currentState._time); } else { timeLeftForCurrentWaypoint = 0; } textMesh.text = timeLeftForGlobalGoal.ToString() + "/" + timeLeftForCurrentWaypoint.ToString(); }
public OffMeshLinkInformation GetCurrentOffMeshLinkInformation() { Vector3 meshLinkStartPos = gridNavigationTasks[currentPlanExecutionIndex].goalState.getPosition(); return(CentralizedManager.GetOffMeshLinkInformation(meshLinkStartPos)); }
public static void CalculateNavigationMeshPath(Vector3 startPosition, Vector3 goalPosition, int passableMask) { ClearNavigationMeshPath(); switch (navigationMeshChoice) { default: case NavigationMeshChoice.USE_UNITY: NavMeshPath unityPath = new NavMeshPath(); NavMesh.CalculatePath(startPosition, goalPosition, passableMask, unityPath); pathStatus = unityPath.status; if (pathStatus == NavMeshPathStatus.PathInvalid) { numberOfNodes = 0; } else { if (unityPath.corners.Length >= maxNumberOfNodes) { Debug.LogWarning("Navigation mesh path greater than maximum number of nodes"); numberOfNodes = maxNumberOfNodes; pathStatus = NavMeshPathStatus.PathPartial; } else { numberOfNodes = unityPath.corners.Length; } for (int i = 0; i < numberOfNodes; i++) { // MAKING SURE LAST WAYPOINT IS THE GOAL if (i == numberOfNodes - 1) { path[i] = goalPosition; } else { path[i] = unityPath.corners[i]; } // computing path cost if (i == 0) { pathCost[i] = 0.0f; } else { // assuming that all off mesh links will override cost if (CentralizedManager.IsOffMeshLink(path[i])) { pathCost[i] = CentralizedManager.GetOffMeshLinkInformation(path[i]).offMeshLink.costOverride; } else { pathCost[i] = Vector3.Distance(path[i], path[i - 1]); } } totalPathCost += pathCost[i]; } } break; case NavigationMeshChoice.USE_RECAST: if (recastSteeringManager == null) { recastSteeringManager = GameObject.Find("ADAPTPrefab").GetComponentInChildren <SteeringManager>(); } numberOfNodes = recastSteeringManager.FindPath(startPosition, goalPosition, path, maxNumberOfNodes); if (numberOfNodes > 0) { path[numberOfNodes - 1] = goalPosition; } // computing path cost for (int i = 1; i < numberOfNodes; i++) { // TODO : incorporate number of obstacles from centralized manager here pathCost[i] = Vector3.Distance(path[i], path[i - 1]); totalPathCost += pathCost[i]; } if (numberOfNodes == 0) { pathStatus = NavMeshPathStatus.PathInvalid; } else if (numberOfNodes == maxNumberOfNodes) { pathStatus = NavMeshPathStatus.PathPartial; } else { pathStatus = NavMeshPathStatus.PathComplete; } break; } }