コード例 #1
0
 // This takes your current path, if you have one, and extends it one stage towards a destination.
 // NEEDS WORK !!!
 private void ExtendCurrentPathTowards(Vector3 destination)
 {
     // If you actually HAVE a current path
     if (currentPath.Count > 1)
     {
         // NEEDS CHANGE. This function just walks to player with small chance of error. Not good.
         // He should actually try to figure out where to go.
         Node_Wrapper bestExtension = currentPath[currentPath.Count - 1];
         foreach (Node_Wrapper node in currentPath[currentPath.Count - 1].neighbours)
         {
             if (Vector3.Distance(node.position, destination) < Vector3.Distance(bestExtension.position, destination) &&
                 Random.Range(1, 20) < 11 + (2))                       // This adds random chance that he'll walk wrong.
             {
                 bestExtension = node;
             }
         }
         currentPath.Add(bestExtension);
     }
 }
コード例 #2
0
    private void TeleportToSafety()
    {
        if (nodeList.Count < 1)
        {
            return;
        }

        float        RandomFleeDistance = maximumDistanceFromPlayer;
        Node_Wrapper bestEscapeNode     = nodeList[0];

        foreach (Node_Wrapper node in nodeList)
        {
            if (!IsTransformVisibleFrom(node.position, player))
            {
                if (Mathf.Abs(Vector3.Distance(node.position, player.position) - RandomFleeDistance)
                    < Mathf.Abs(Vector3.Distance(bestEscapeNode.position, player.position) - RandomFleeDistance))
                {
                    bestEscapeNode = node;
                }
            }
        }
        transform.position = bestEscapeNode.position;
        return;
    }
コード例 #3
0
    private const float MAX_NEIGHBOUR_DISTANCE = 40F; // This is in meters.

    #endregion Fields

    #region Constructors

    public Node_Wrapper(GameObject node)
    {
        gameobject = node;
        thisNode = this;
        position = node.transform.position;
    }
コード例 #4
0
    private const float MAX_NEIGHBOUR_DISTANCE = 40F;     // This is in meters.

    public Node_Wrapper(GameObject node)
    {
        gameobject = node;
        thisNode   = this;
        position   = node.transform.position;
    }
コード例 #5
0
    // Murderer finds the most effective path from himself to the defined object.
    // The function overwrites murderer's current path with the new one it finds.
    private void FindPathTo(Transform destination)
    {
        if (nodeList.Count < 1)
        {
            pathIsImpossible = true;
            return;
        }

        // Find the nodes closest to start and goal
        Node_Wrapper startNode = null;
        Node_Wrapper goalNode  = null;

        foreach (Node_Wrapper node in nodeList)
        {
            // Set startnode if this node is closer than the closest so far.
            if (IsTransformVisibleFrom(node.position, transform) || (transform.position - node.position).sqrMagnitude < 0.5F)
            {
                if (startNode != null)
                {
                    if ((transform.position - node.position).sqrMagnitude < (transform.position - startNode.position).sqrMagnitude)
                    {
                        startNode = node;
                    }
                }
                else
                {
                    startNode = node;
                }
            }
            // Set goalnode if this node is closer than the closest so far.
            if (IsTransformVisibleFrom(node.position, destination, new string[] { "Door" }) || (destination.position - node.position).sqrMagnitude < 0.5F)
            {
                if (goalNode != null)
                {
                    if ((destination.position - node.position).sqrMagnitude < (destination.position - goalNode.position).sqrMagnitude)
                    {
                        goalNode = node;
                    }
                }
                else
                {
                    goalNode = node;
                }
            }
        }
        if (startNode == null || goalNode == null)
        {
            currentPath.Clear();
            pathIsImpossible = true;
            return;
        }

        // A* algorithm
        int failSafe = 0;
        List <Node_Wrapper> openList   = new List <Node_Wrapper>();
        List <Node_Wrapper> closedList = new List <Node_Wrapper>();

        openList.Add(startNode);
        while (openList.Count > 0 && failSafe < 1000F)
        {
            failSafe++;

            // This is to find element with lowest score.
            Node_Wrapper bestNode      = null;
            float        bestPathScore = float.MaxValue;
            foreach (Node_Wrapper node in openList)
            {
                float nodeScore = node.distanceTraveled + ((node.position - goalNode.position).sqrMagnitude / 2);
                if (nodeScore < bestPathScore)
                {
                    bestNode      = node;
                    bestPathScore = nodeScore;
                }
            }

            // Find all neighbours of that node, that haven't been tried out yet.
            foreach (Node_Wrapper node in bestNode.neighbours)
            {
                if (!openList.Contains(node) && !closedList.Contains(node))
                {
                    node.parentNode       = bestNode;
                    node.distanceTraveled = bestNode.distanceTraveled + (bestNode.position - node.position).sqrMagnitude;
                    openList.Add(node);
                }
                else if (node.distanceTraveled > bestNode.distanceTraveled + (bestNode.position - node.position).sqrMagnitude)
                {
                    node.parentNode       = bestNode;
                    node.distanceTraveled = bestNode.distanceTraveled + (bestNode.position - node.position).sqrMagnitude;
                }
            }

            if (bestNode.position != goalNode.position)
            {
                closedList.Add(bestNode);
                openList.Remove(bestNode);
            }
            else
            {
                currentPath      = bestNode.PathHere();           // JIPPI!
                pathStage        = 0;
                arrivedAtPathEnd = false;
                pathIsImpossible = false;
                break;
            }
        }

        // Is the path impossible??
        if (openList.Count <= 0 || failSafe >= 1000F)
        {
            pathIsImpossible = true;
        }
        // Cleans up!
        foreach (Node_Wrapper node in nodeList)
        {
            node.parentNode       = null;
            node.distanceTraveled = 0F;
        }
    }