//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()); }