// 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
    }
示例#3
0
    // 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);
        }
    }
示例#4
0
    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));
    }
示例#5
0
    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;
        }
    }
示例#6
0
    // 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();
    }
示例#7
0
    public OffMeshLinkInformation GetCurrentOffMeshLinkInformation()
    {
        Vector3 meshLinkStartPos = gridNavigationTasks[currentPlanExecutionIndex].goalState.getPosition();

        return(CentralizedManager.GetOffMeshLinkInformation(meshLinkStartPos));
    }
示例#8
0
    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;
        }
    }