コード例 #1
0
    public bool FindPath()
    {
//		Debug.Log ("PathFound"+PathFound.ToString());
        qpNode start_node = qpManager.Instance.nodes[0];
        qpNode end_node   = qpManager.Instance.nodes[0];

        for (int i = 0; i < qpManager.Instance.nodes.Count; i++)
        {
            //Debug.Log (qpManager.Instance.nodes[i].GetCoordinate ().ToString());
            if (qpManager.Instance.nodes[i].GetCoordinate() == new Vector3(0.5f, 0.5f, 0.1f))
            {
                start_node = qpManager.Instance.nodes[i];
            }
            if (qpManager.Instance.nodes[i].GetCoordinate() == new Vector3(9.5f, 9.5f, 0.1f))
            {
                end_node = qpManager.Instance.nodes[i];
            }
        }
        List <qpNode> a = AStar(start_node, end_node);

        Debug.Log(start_node.GetCoordinate().ToString());
        Debug.Log(end_node.GetCoordinate().ToString());
        if (a.Count == 0)
        {
            return(false);
        }
        return(true);
    }
コード例 #2
0
ファイル: qpMoveObject.cs プロジェクト: corhal/Tactics
 private void _move()
 {
     if (Path != null)
     {
         if (_moveCounter < Path.Count)
         {
             Moving = true;
             _updateDestinations();
             if (AbleToMove)
             {
                 transform.position = Vector3.MoveTowards(transform.position, Path [_moveCounter].Coordinate + Offset, Time.deltaTime * Speed);
             }
             if (Vector3.Distance(transform.position, Path [_moveCounter].Coordinate + Offset) < SpillDistance)
             {
                 PreviousNode = Path [_moveCounter];
                 _moveCounter++;
                 if (_moveCounter < Path.Count)
                 {
                     NextNode = Path [_moveCounter];
                 }
                 else
                 {
                     FinishedPath();
                 }
             }
         }
         else
         {
             Moving = false;
         }
     }
 }
コード例 #3
0
 /// <summary>
 /// Creates a mutual connection between this node and another node.
 /// </summary>
 /// <param name="node">the other node.</param>
 /// <param name="diagonal">Is the other node diagonally placed from this?</param>
 public void SetMutualConnection(qpNode node, bool diagonal = false)
 {
     if (node != null)
     {
         if (!Contacts.Contains(node))
         {
             Contacts.Add(node);
         }
         if (!node.Contacts.Contains(this))
         {
             node.Contacts.Add(this);
         }
         if (!diagonal)
         {
             if (!NonDiagonalContacts.Contains(node))
             {
                 NonDiagonalContacts.Add(node);
             }
             if (!node.NonDiagonalContacts.Contains(this))
             {
                 node.NonDiagonalContacts.Add(this);
             }
         }
     }
 }
コード例 #4
0
ファイル: qpManager.cs プロジェクト: corhal/Tactics
 /// <summary>
 /// Deregisters a single node
 /// </summary>
 /// <param name="node"></param>
 public void DelistNode(qpNode node)
 {
     node.outdated = true;
     for (int i = node.Contacts.Count; i > 0; i--)
     {
         node.Contacts [i - 1].RemoveMutualConnection(node);
     }
     nodes.Remove(node);          // shouldn't it also destroy node gameObject?
 }
コード例 #5
0
 /// <summary>
 /// Sets connection to another node.
 /// </summary>
 /// <param name="node">The other node</param>
 public void SetConnection(qpNode node)
 {
     if (node != null)
     {
         if (!Contacts.Contains(node))
         {
             Contacts.Add(node);
         }
     }
 }
コード例 #6
0
 /// <summary>
 /// Remove a mutual connection between this node and another node.
 /// </summary>
 /// <param name="otherNode">The other node that this node is currently connected to.</param>
 public void RemoveMutualConnection(qpNode otherNode)
 {
     if (otherNode != null)
     {
         Contacts.Remove(otherNode);
         NonDiagonalContacts.Remove(otherNode);
         otherNode.Contacts.Remove(this);
         otherNode.NonDiagonalContacts.Add(this);
     }
 }
コード例 #7
0
    /// <summary>
    /// Creates a path to the desired node, and begins walking the path
    /// </summary>
    /// <param name="destination">Desired desination node</param>
    public bool MakePath(qpNode destination)
    {
        List <qpNode> nodes = AStar(_nearNode(), destination);

        if (nodes.Count == 0)
        {
            return(false);
        }
        SetPath(nodes);
        return(true);
    }
コード例 #8
0
ファイル: qpMoveObject.cs プロジェクト: corhal/Tactics
 /// <summary>
 /// Update is called once per frame
 /// </summary>
 protected void FixedUpdate() // Why fixed?..
 {
     _verifyNodes();
     _move();
     if (DrawPathInEditor && Path.Count > 0)
     {
         for (int i = 1; i < Path.Count; i++)
         {
             qpNode prevNode = Path [i - 1];
             Debug.DrawLine(prevNode.Coordinate + Offset, Path [i].Coordinate + Offset, Color.red, 0, false);
         }
     }
 }
コード例 #9
0
ファイル: qpManager.cs プロジェクト: corhal/Tactics
    private List <qpNode> _findNodesNear(qpNode target, float radius)
    {
        List <qpNode> retList = new List <qpNode> ();

        foreach (qpNode node in nodes)
        {
            if (target != node && Vector3.Distance(target.Coordinate, node.Coordinate) < radius)
            {
                retList.Add(node);
            }
        }
        return(retList);
    }
コード例 #10
0
    private List <qpNode> _findNodesNear(qpNode target, float radius)
    {
        List <qpNode> retList = new List <qpNode>();

        foreach (qpNode node in nodes)
        {
            if (target != node && Vector3.Distance(target.GetCoordinate(), node.GetCoordinate()) < radius)
            {
                //Debug.Log("node found at:" + Vector3.Distance(target.transform.position, node.transform.position));
                retList.Add(node);
            }
        }
        return(retList);
    }
コード例 #11
0
ファイル: qpMoveObject.cs プロジェクト: corhal/Tactics
    private qpNode _nearNode()
    {
        qpNode node = (NextNode == null || !NextNode.outdated ? PreviousNode : NextNode);

        if (node != null)
        {
            if (node.outdated || Vector3.Distance(node.Coordinate, this.transform.position) > (SpillDistance * 1.5))
            {
                FindClosestNode();
                return(PreviousNode);
            }
        }
        return(node);
    }
コード例 #12
0
    private qpNode _nearNode()
    {
        qpNode node = (NextNode == null || !NextNode.outdated? PreviousNode : NextNode);

        if (node != null)
        {
            if (node.outdated)
            {
                FindClosestNode();
                return(PreviousNode);
            }
        }
        return(node);
    }
コード例 #13
0
 /// <summary>
 /// Used for A*. Calculates _total - sum of distances between current and end, and current and parent nodes.
 /// </summary>
 /// <param name="start"></param>
 /// <param name="end"></param>
 /// <returns></returns>
 public float CalculateTotal(qpNode end)
 {
     _h = CalculateH(end);
     if (_parent != null)
     {
         _g = CalculateG(_parent) + _parent.G;
     }
     else
     {
         _g = 1;
     }
     _total = _g + _h;
     return(_total);
 }
コード例 #14
0
 /// <summary>
 /// Remove a mutual connection between this node and another node.
 /// </summary>
 /// <param name="otherNode">The other node that this node is currently connected to.</param>
 public void RemoveMutualConnection(qpNode otherNode)
 {
     if (otherNode != null)
     {
         if (Contacts.Contains(otherNode))
         {
             Contacts.Remove(otherNode);
         }
         if (NonDiagonalContacts.Contains(otherNode))
         {
             NonDiagonalContacts.Remove(otherNode);
         }
         if (otherNode.Contacts.Contains(this))
         {
             otherNode.Contacts.Remove(this);
         }
         if (otherNode.NonDiagonalContacts.Contains(this))
         {
             otherNode.NonDiagonalContacts.Add(this);
         }
     }
 }
コード例 #15
0
ファイル: qpManager.cs プロジェクト: corhal/Tactics
 /// <summary>
 /// Registers a single node(normally send from qp(qpPointNode)
 /// </summary>
 /// <param name="selection"></param>
 public void RegisterNode(qpNode selection)
 {
     selection.outdated = false;
     nodes.Add(selection);
 }
コード例 #16
0
ファイル: qpMoveObject.cs プロジェクト: corhal/Tactics
 /// <summary>
 /// Finds the closest node to the object
 /// </summary>
 public void FindClosestNode()
 {
     PreviousNode = qpManager.Instance.FindNodeClosestTo(this.transform.position);
 }
コード例 #17
0
ファイル: qpMoveObject.cs プロジェクト: corhal/Tactics
    /// <summary>
    /// Performs an A* algorithm
    /// </summary>
    /// <param name="start">Starting node</param>
    /// <param name="end">Destination Node</param>
    /// <returns>The fastest path from start node to the end node</returns>
    protected List <qpNode> AStar(qpNode start, qpNode end)
    {
        List <qpNode> path       = new List <qpNode> ();                           // will hold the final path
        bool          complete   = (end == null || start == null) ? true : false;  // Regulates the main while loop of the algorithm
        List <qpNode> closedList = new List <qpNode> ();                           // Closed list for the best candidates.
        List <qpNode> openList   = new List <qpNode> ();                           // Open list for all candidates(A home for all).
        qpNode        candidate  = start;                                          // The current node candidate which is being analyzed in the algorithm.

        openList.Add(start);                                                       // Start node is added to the openlist
        if (start == null || end == null)
        {
            return(null);                                                              // algorithm cannot be executed if either start or end node are null.
        }

        int astarSteps = 0;

        while (openList.Count > 0 && !complete)                                    // ALGORITHM STARTS HERE.
        {
            astarSteps++;
            if (candidate == end)                                                      // If current candidate is end, the algorithm has been completed and the path can be built.
            {
                DestinationNode = end;
                complete        = true;
                bool   pathComplete = false;
                qpNode node         = end;
                while (!pathComplete)
                {
                    path.Add(node);
                    if (node == start)
                    {
                        pathComplete = true;
                    }
                    node = node.Parent;
                }
            }

            List <qpNode> allNodes       = (DiagonalMovement ? candidate.Contacts : candidate.NonDiagonalContacts);
            List <qpNode> potentialNodes = new List <qpNode> ();
            foreach (qpNode n in allNodes)
            {
                if (n.traverseable)
                {
                    potentialNodes.Add(n);
                }
            }
            foreach (qpNode n in potentialNodes)
            {
                bool inClosed = closedList.Contains(n);
                bool inOpen   = openList.Contains(n);
                //Mark candidate as parent if not in open nor closed.
                if (!inClosed && !inOpen)
                {
                    n.Parent = candidate;
                    openList.Add(n);
                }
                //But if in open, then calculate which is the better parent: Candidate or current parent.
                else if (inOpen)
                {
                    float math2 = n.Parent.G;
                    float math1 = candidate.G;
                    if (math2 > math1)
                    {
                        //candidate is the better parent as it has a lower combined g value.
                        n.Parent = candidate;
                    }
                }
            }

            //Calculate h, g and total
            if (openList.Count == 0)
            {
                break;
            }
            openList.RemoveAt(0);
            if (openList.Count == 0)
            {
                break;
            }
            //the below for loop,if conditional and method call updates all nodes in openlist.
            for (int i = 0; i < openList.Count; i++)
            {
                openList [i].CalculateTotal(/*start,*/ end);
            }
            openList.Sort(delegate(qpNode node1, qpNode node2) {
                return(node1.Total.CompareTo(node2.Total));
            });

            candidate = openList [0];
            closedList.Add(candidate);
        }
        Debug.Log("astar completed in " + astarSteps + " steps. Path found:" + complete);
        path.Reverse();
        return(path);
    }
コード例 #18
0
 /// <summary>
 /// Used for A*. Calculates _g - distance between current and parent nodes.
 /// </summary>
 public float CalculateG(qpNode parent)
 {
     return(Vector3.Distance(_coordinate, parent.Coordinate));
 }
コード例 #19
0
 /// <summary>
 /// Used for A*. Calculates _h - distance between current and end nodes.
 /// </summary>
 public float CalculateH(qpNode end)
 {
     return(Vector3.Distance(_coordinate, end.Coordinate));
 }
コード例 #20
0
    public bool CanConnectTo(qpNode candidate)
    {
        int   steps        = (int)(Vector3.Distance(candidate.Coordinate, _coordinate) * 2);
        float castDistance = Mathf.Abs((candidate.Coordinate - _coordinate).y) + 4;

        if (qpManager.Instance.KnownUpDirection == qpGrid.Axis.Z)
        {
            castDistance = Mathf.Abs((candidate.Coordinate - _coordinate).z) + 4;
        }

        Vector3    difference = (candidate.Coordinate - _coordinate) / steps;
        RaycastHit info;
        Vector3    upDirection      = qpManager.Instance.UpVector;
        Vector3    downDirection    = -upDirection;
        Vector3    myCoordinate     = _coordinate + (upDirection / 5);  // ...why?
        Vector3    destinationPoint = candidate.Coordinate - difference + (upDirection / 5);

        if (Physics.Linecast(myCoordinate, destinationPoint, out info))            // обскурная херня, без которой образуются лишние связи
        {
            return(false);
        }

        //Ray cast downward along the previously casted straight line
        for (int i = 1; i < steps; i++)
        {
            int          ignoreHits = 0;
            RaycastHit[] hits;

            Vector3 rayCastPositionStart = new Vector3(myCoordinate.x + (difference.x * i), myCoordinate.y + (castDistance / 2), myCoordinate.z + (difference.z * i));
            if (upDirection == new Vector3(0, 0, 1))
            {
                rayCastPositionStart.y = myCoordinate.y + (difference.y * i);
                rayCastPositionStart.z = myCoordinate.z + (castDistance / 2);
            }
            ScanRayCasts.Add(rayCastPositionStart);

            hits = Physics.RaycastAll(rayCastPositionStart, downDirection, castDistance);
            if (hits.Length == 0)
            {
                return(false);
            }
            List <float> heightPoints = new List <float> ();
            foreach (RaycastHit hit in hits)
            {
                if (qpManager.Instance.disallowedTags.Contains(hit.collider.gameObject.tag))
                {
                    return(false);
                }
                else if (qpManager.Instance.ignoreTags.Contains(hit.collider.gameObject.tag))
                {
                    ignoreHits++;
                }
                else
                {
                    if (qpManager.Instance.KnownUpDirection == qpGrid.Axis.Y)
                    {
                        heightPoints.Add(hit.point.y);
                    }
                    else if (qpManager.Instance.KnownUpDirection == qpGrid.Axis.Z)
                    {
                        heightPoints.Add(hit.point.z);
                    }
                }
            }
            if (hits.Length == ignoreHits)
            {
                return(false);
            }
        }
        return(true);
    }
コード例 #21
0
 /// <summary>
 /// Used for A*
 /// </summary>
 public void SetParent(qpNode parent)
 {
     _parent = parent;
 }
コード例 #22
0
    /// <summary>
    /// Update is called once per frame
    /// </summary>
    protected void Update()
    {
        if (Target != null)
        {
            bool ShouldChase = false;
            if (Vector3.Distance(Target.transform.position, this.transform.position) < AgroRadius)
            {
                Vector3 myOffset     = this.transform.position;
                Vector3 targetOffset = Target.transform.position;
                myOffset.y     += .2f;
                targetOffset.y += .2f;
                if (UseLineOfSight)
                {
                    RaycastHit hit;

                    if (Physics.Linecast(myOffset, targetOffset, out hit))
                    {
                        if (hit.collider.gameObject.tag != this.gameObject.tag && hit.collider.gameObject.tag != Target.gameObject.tag)
                        {
                            //Inside agro, but not in Line of Sight
                        }
                        else
                        {
                            //inside agro, and in LineOFSight-LineCast collides only with ignored tags, making path towards target
                            ShouldChase = true;
                        }
                    }
                    else if (this.PreviousNode != qpManager.Instance.FindNodeClosestTo(Target.transform.position))
                    {
                        //inside agro, and in line of sight, making path towards target
                        ShouldChase = true;
                    }

                    if (DrawLineOfSightLineInEditor)
                    {
                        Debug.DrawLine(myOffset, hit.point);
                    }
                }
                else
                {
                    //Not using line of sight, and inside agro, making path towards player.
                    ShouldChase = true;
                }
            }

            if (ShouldChase)
            {
                if (lastSeenTargetNode != qpManager.Instance.FindNodeClosestTo(Target.transform.position))
                {
                    if (Moving)
                    {
                        List <qpNode> prePath = AStar(PreviousNode, lastSeenTargetNode);
                        for (int i = prePath.Count; i > 0; i--)
                        {
                            if (prePath[i - 1] == NextNode)
                            {
                                prePath.RemoveRange(0, i - 1);
                                break;
                            }
                        }
                        SetPath(prePath);
                    }
                    else
                    {
                        MakePath(Target.transform.position);
                    }
                }
                lastSeenTargetNode = qpManager.Instance.FindNodeClosestTo(Target.transform.position);
                if (DrawLineOfSightLineInEditor)
                {
                    Debug.DrawLine(this.transform.position, Target.transform.position, Color.magenta, 5f, true);
                }
            }
        }
    }
コード例 #23
0
ファイル: qpMoveObject.cs プロジェクト: corhal/Tactics
 /// <summary>
 /// Creates a path to the desired node, and begins walking the path
 /// </summary>
 /// <param name="destination">Desired desination node</param>
 public void MakePath(qpNode destination)
 {
     SetPath(AStar(_nearNode(), destination));
 }
コード例 #24
0
 /// <summary>
 /// Registers a single node(normally send from qp(qpPointNode)
 /// </summary>
 /// <param name="selection"></param>
 public void RegisterNode(qpNode selection)
 {
     nodes.Add(selection);
 }
コード例 #25
0
 /// <summary>
 /// Deregisters a single node
 /// </summary>
 /// <param name="node"></param>
 public void DelistNode(qpNode node)
 {
     node.outdated = true;
     nodes.Remove(node);
 }