示例#1
0
    //we reached the end of the path
    internal IEnumerator ReachedEnd()
    {
        //we differ between all looptypes, because each one has a specific property
        switch (looptype)
        {
            //LoopType.none means there will be no repeat,
            //so we just discard the tweener and return
            case LoopType.none:

                tween.Kill();
                tween = null;
                PlayIdle();
                yield break;

            //in a loop we set our position indicator back to zero and start from the beginning
            case LoopType.loop:

                //additional option: if the path was closed, we move our object
                //from the last to the first waypoint instead of just "appearing" there
                if (closePath)
                {
                    tween.Play();
                    PlayWalk();
                    yield return StartCoroutine(tween.UsePartialPath(currentPoint, -1).WaitForCompletion());
                }
                currentPoint = 0;
                break;

            //on LoopType.pingPong, we decrease our location indicator till it reaches zero again
            //to start from the beginning - to achieve that, and differ between back and forth,
            //we use the boolean "repeat" here and in NextWaypoint()
            case LoopType.pingPong:

                //discard tweener as it only moved us forwards or backwards
                tween.Kill();
                tween = null;

                //we moved till the end of the path
                if (!repeat)
                {
                    //enable repeat mode
                    repeat = true;
                    //update waypoint positions backwards
                    for (int i = 0; i < wpPos.Length; i++)
                    {
                        wpPos[i] = waypoints[waypoints.Length - 1 - i].position + new Vector3(0, sizeToAdd, 0);
                    }
                }
                else
                {
                    //we are at the first waypoint again,
                    //reinitialize original waypoint positions
                    //and disable repeating mode
                    InitWaypoints();
                    repeat = false;
                }

                //create tweener for next iteration
                CreateTween();
                break;

            //on LoopType.random, we calculate a random order between all waypoints
            //and loop through them, for this case we use the Fisher-Yates algorithm
            case LoopType.random:
                //reset random index, because we calculate a new order
                rndIndex = 0;
                //reinitialize original waypoint positions
                InitWaypoints();

                //discard tweener for new order
                if (tween != null)
                {
                    tween.Kill();
                    tween = null;
                }

                //create array with ongoing index numbers to keep them in mind,
                //this gets shuffled with all waypoint positions at the next step 
                rndArray = new int[wpPos.Length];
                for (int i = 0; i < rndArray.Length; i++)
                {
                    rndArray[i] = i;
                }

                //get total array length
                int n = wpPos.Length;
                //shuffle wpPos and rndArray
                while (n > 1)
                {
                    int k = rand.Next(n--);
                    Vector3 temp = wpPos[n];
                    wpPos[n] = wpPos[k];
                    wpPos[k] = temp;

                    int tmpI = rndArray[n];
                    rndArray[n] = rndArray[k];
                    rndArray[k] = tmpI;
                }

                //since all waypoints are shuffled the first waypoint does not
                //correspond with the actual current position, so we have to
                //swap the first waypoint with the actual waypoint
                //start by caching the first waypoint position and number
                Vector3 first = wpPos[0];
                int rndFirst = rndArray[0];
                //loop through wpPos array and find corresponding waypoint
                for (int i = 0; i < wpPos.Length; i++)
                {
                    //currentPoint is equal to this waypoint number
                    if (rndArray[i] == currentPoint)
                    {
                        //swap rnd index number and waypoint positions
                        rndArray[i] = rndFirst;
                        wpPos[0] = wpPos[i];
                        wpPos[i] = first;
                    }
                }
                //set current rnd index number to the actual current point
                rndArray[0] = currentPoint;

                //create tween with random order
                CreateTween();
                break;
        }

        //start moving to the next iteration
        StartCoroutine(NextWaypoint());
    }