//--------------------------------------------------
        // Forward motion means moving from node A to node B,
        // B to A for backwards motion. Next segment is found
        // by matching the end node to the beginning node of
        // another segment
        //--------------------------------------------------

        public WPSegment GetNextSeg(WPSegment curSeg, bool reverse)
        {
            WPNode    curNode = (!reverse) ? curSeg.nodeB : curSeg.nodeA; // Cache the end node of the first segment
            WPSegment nextSeg = null;

            foreach (var s in segments)
            {
                if (!reverse)
                {
                    if (s.nodeA == curNode)
                    {
                        nextSeg = s;
                        break;
                    }
                }
                else
                {
                    if (s.nodeB == curNode)
                    {
                        nextSeg = s;
                        break;
                    }
                }
            }
            if (nextSeg == null)
            {
                Debug.Log("Next segment not found. Path is complete or destroyed.");
            }
            return(nextSeg);
        }
        //--------------------------------------------------
        // Get a new segment from the pool.
        //--------------------------------------------------

        public WPSegment GetSeg(WPNode nodeA, WPNode nodeB, Vector3[] subNodes)
        {
            WPSegment returnVal = null;

            for (int i = 0; i < pool.Count; ++i)
            {
                // If a segment with the same start and end node is found in the pool,
                // return that. No need to make a new object.
                if (pool[i].nodeA == nodeA && pool[i].nodeB == nodeB)
                {
                    returnVal = pool[i];
                    break;
                }
                // Otherwise, check to see if there is another pool object that's ready
                // to be recycled (dead) in the pool. If so, use that.
                if (pool[i].isDead)
                {
                    returnVal = pool[i];
                }
            }
            if (returnVal == null)  // Only if there are no matching or dead segments, create a new object.
            {
                returnVal = new WPSegment(nodeA, nodeB, subNodes);
                //Debug.Log("new segment created");
                pool.Add(returnVal);
            }
            else // Otherwise populate the recycled object with the desired values.
            {
                returnVal.nodeA    = nodeA;
                returnVal.nodeB    = nodeB;
                returnVal.subNodes = subNodes;
            }
            return(returnVal);
        }
Ejemplo n.º 3
0
        //--------------------------------------------------
        //  Main traversal loop
        //--------------------------------------------------

        void TraverseLoop()
        {
            if (curSeg == null)
            {
                return;
            }

            int     lastSubNode = curSeg.subNodes.Length - 1;
            Vector3 curPos      = (useRigidbody) ? rb.position : transform.position;

            bool willOvershoot = false;

            // Prevent unforseen endless loop
            float       failsafe     = 0.0f;
            const float failsafeTime = 0.5f;

            // if movement method returns that speed will overshoot,
            // keep running through segments until it no longer will.

            do
            {
                Vector3 dest = controller.transform.position + curSeg.subNodes[curSub];
                willOvershoot = MoveBySpeed(dest, moveSpeed, ref curPos);

                if (willOvershoot)
                {
                    curSub += (reverse) ? -1 : 1;
                }

                if (curSub < 0 || curSub > lastSubNode)
                {
                    WPNode curNode = (!reverse) ? curSeg.nodeB : curSeg.nodeA;
                    if (curNode.changeDirection)
                    {
                        reverse = !reverse; // if changing direction, no need to find new seg, just reset subnode
                    }
                    else
                    {
                        curSeg = controller.GetNextSeg(curSeg, reverse);
                    }
                    if (curSeg == null)
                    {
                        Debug.Log("Traversal complete: " + gameObject.name);
                        traversing = false;
                        return;
                    }
                    curSub = (reverse) ? lastSubNode - 1 : 1;
                }
                failsafe += Time.deltaTime;
            } while (willOvershoot && failsafe < failsafeTime);

            if (!willOvershoot)
            {
                if (useRigidbody)
                {
                    rb.MovePosition(curPos);
                }
                else
                {
                    transform.position = curPos;
                }
            }
        }
 public WPSegment(WPNode nodeA, WPNode nodeB, Vector3[] subNodes)
 {
     this.nodeA    = nodeA;
     this.nodeB    = nodeB;
     this.subNodes = subNodes;
 }