public FredWaypoint ConnectedWaypointClosestTo(FredWaypoint targetWaypoint, FredWaypoint lastFredWaypoint = null) { if (connectedWaypoints.Length == 1) { return(lastFredWaypoint); } else { float bestDist = 1000; FredWaypoint bestWaypoint = null; for (int i = 0; i < connectedWaypoints.Length; i++) { if (connectedWaypoints[i] == targetWaypoint) { return(connectedWaypoints[i]); } float dist = Vector3.Distance(connectedWaypoints[i].transform.position, targetWaypoint.transform.position); if (dist < bestDist && connectedWaypoints[i] != lastFredWaypoint) { bestDist = dist; bestWaypoint = connectedWaypoints[i]; } } return(bestWaypoint); } }
IEnumerator MovingToWaypoint(FredWaypoint targetWaypoint) { if (currentState == State.Wandering) { float startTurnTime = Time.time; //turn to look towards destination while (Time.time < startTurnTime + TurnTime) { transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(targetWaypoint.transform.position - transform.position), Time.deltaTime * turnSpeed); yield return(null); } //looking at target, start moving Vector3 moveDirection = transform.forward; float startAccelerationTime = Time.time; float distance = 1000; float speed = 0; FredAnims.SetBool("Flying", true); FredAnims.enabled = false; while (distance > distToReachWaypoint) { float currentSpeed = Mathf.Lerp(0, maxDistPerSec, AccelerationCurve.Evaluate((Time.time - startAccelerationTime) / AccelerationTime)); speed = currentSpeed; transform.Translate(transform.forward * currentSpeed * Time.deltaTime, Space.World); distance = Vector3.Distance(transform.position, targetWaypoint.transform.position); yield return(null); } //reached target, slow down and stop float startSlowTime = Time.time; FredAnims.enabled = true; FredAnims.SetBool("Flying", false); while (Time.time < startSlowTime + StoppingTime) { float currentSpeed = Mathf.Lerp(speed, 0, (Time.time - startSlowTime) / StoppingTime); transform.Translate(moveDirection * currentSpeed * Time.deltaTime, Space.World); yield return(null); } //reached waypoint, set as current, add to reached waypoints, and continue wandering. currentWaypoint = targetWaypoint; reachedWaypoints.Add(currentWaypoint); readyToMove = false; StartCoroutine(Wandering()); yield return(new WaitForSeconds(3f)); readyToMove = true; } else if (currentState == State.Fetching) { } yield break; }
IEnumerator Fetching() { while (GemsToCollect.Count > 0) { GemGroupScript currentTargetGem; //Choose gem to get if (GemsToCollect.Count == 1) { currentTargetGem = GemsToCollect[0]; } else { float bestDistance = 1000; GemGroupScript bestGemGroup = null; for (int i = 0; i < GemsToCollect.Count; i++) { float distance = Vector3.Distance(transform.position, GemsToCollect[i].transform.position); if (distance < bestDistance) { bestDistance = distance; bestGemGroup = GemsToCollect[i]; } } if (bestGemGroup == null) { yield break; } else { currentTargetGem = bestGemGroup; } } //Found Gem, Going to get it //If was already moving, keep momentum FredWaypoint nextWaypoint; float speed = 0; float startMoveTime = Time.time; float distanceToNextWaypoint = 100; float startTurnTime = Time.time; float startSpeed = 0; if (currentTargetWaypoint != null && currentSpeedMovingBetweenWaypoints > 0) { float startSlowTime = Time.time; while (Time.time < startSlowTime + 1.5f) { float currentSpeed = Mathf.Lerp(currentSpeedMovingBetweenWaypoints, 0, (Time.time - startSlowTime) / 1.5f); transform.Translate(transform.forward * currentSpeed * Time.deltaTime, Space.World); yield return(null); } nextWaypoint = null; currentTargetWaypoint = null; currentSpeedMovingBetweenWaypoints = 0; } else if (currentTargetGem.GemLocationWaypoint != currentWaypoint && currentWaypoint != null) { nextWaypoint = currentWaypoint.ConnectedWaypointClosestTo(currentTargetGem.GemLocationWaypoint); } else { //at target waypoint nextWaypoint = null; } Vector3 _waypointTarget = currentTargetGem.GemLocationWaypoint.transform.position; Vector3 _gemTarget = currentTargetGem.transform.position; _gemTarget.Set(_gemTarget.x, transform.position.y, _gemTarget.z); //if not already at target waypoint if (nextWaypoint != null) { //TurnBeforeMoving startTurnTime = Time.time; Quaternion startRotation = transform.rotation; while (Time.time < startTurnTime + (TurnTime / 2f)) { transform.rotation = Quaternion.Lerp(startRotation, Quaternion.LookRotation(nextWaypoint.transform.position - transform.position), (Time.time - startTurnTime) / (TurnTime / 2f)); yield return(null); } startMoveTime = Time.time; FredWaypoint _lastwaypoint = currentWaypoint; startRotation = transform.rotation; //while still finding target waypoint while (nextWaypoint != currentTargetGem.GemLocationWaypoint) { if (Time.time < startTurnTime + TurnTime) { transform.rotation = Quaternion.Lerp(startRotation, Quaternion.LookRotation(nextWaypoint.transform.position - transform.position), (Time.time - startTurnTime) / TurnTime); } speed = Mathf.Lerp(0, maxDistPerSec, AccelerationCurve.Evaluate((Time.time - startMoveTime) / AccelerationTime)); transform.Translate(transform.forward * speed * Time.deltaTime, Space.World); distanceToNextWaypoint = Vector3.Distance(transform.position, nextWaypoint.transform.position); if (distanceToNextWaypoint < turningDistFromWaypoint) { startTurnTime = Time.time; startRotation = transform.rotation; currentWaypoint = nextWaypoint; nextWaypoint = currentWaypoint.ConnectedWaypointClosestTo(currentTargetGem.GemLocationWaypoint, _lastwaypoint); _lastwaypoint = currentWaypoint; } yield return(null); } //found target waypoint, are at waypoint before it startSpeed = speed; startTurnTime = Time.time; Vector3 _turnTarget = _waypointTarget; startRotation = transform.rotation; while (true) { if (Time.time < startTurnTime + .75f) { transform.rotation = Quaternion.Lerp(startRotation, Quaternion.LookRotation(_gemTarget - transform.position), (Time.time - startTurnTime) / .75f); } speed = Mathf.Lerp(startSpeed, maxDistPerSec, AccelerationCurve.Evaluate((Time.time - startMoveTime) / AccelerationTime)); transform.Translate(transform.forward * speed * Time.deltaTime, Space.World); if (Vector3.Distance(transform.position, _gemTarget) < 3) { break; } yield return(null); } //Slow and Stop float startSlowTime = Time.time; FredAnims.enabled = true; FredAnims.SetBool("Flying", false); while (Time.time < startSlowTime + StoppingTime) { float currentSpeed = Mathf.Lerp(speed, 0, (Time.time - startSlowTime) / StoppingTime); transform.Translate(transform.forward * currentSpeed * Time.deltaTime, Space.World); yield return(null); } } else { //just turn and move to gems //turn startTurnTime = Time.time; Quaternion startRotation = transform.rotation; while (Time.time < startTurnTime + (TurnTime / 2f)) { transform.rotation = Quaternion.Lerp(startRotation, Quaternion.LookRotation(_gemTarget - transform.position), (Time.time - startTurnTime) / (TurnTime / 2f)); yield return(null); } float distanceToGems = Vector3.Distance(transform.position, _gemTarget); //Move To Gems if (distanceToGems > scanStopDistance) { Vector3 moveDirection = transform.forward; float startAccelerationTime = Time.time; //start moving to scan pos while (distanceToGems > scanStopDistance) { float currentSpeed = Mathf.Lerp(0, maxDistPerSec, AccelerationCurve.Evaluate((Time.time - startAccelerationTime) / AccelerationTime)); speed = currentSpeed; transform.Translate(transform.forward * currentSpeed * Time.deltaTime, Space.World); distanceToGems = Vector3.Distance(transform.position, _gemTarget); yield return(null); } //reached target, slow down and stop float startSlowTime = Time.time; FredAnims.enabled = true; FredAnims.SetBool("Flying", false); while (Time.time < startSlowTime + .3f) { float currentSpeed = Mathf.Lerp(speed, 0, (Time.time - startSlowTime) / .3f); transform.Translate(moveDirection * currentSpeed * Time.deltaTime, Space.World); yield return(null); } } } currentWaypoint = currentTargetGem.GemLocationWaypoint; //Collect Gems GemsToCollect.Remove(currentTargetGem); float startCollectTime = Time.time; TractorBeam.SetActive(true); currentTargetGem.FadeOutIcon(); while (Time.time < startCollectTime + gemPickUpTime) { for (int i = 0; i < currentTargetGem.spawnedGems.Length; i++) { Vector3 InForce = gemCollector.position - currentTargetGem.spawnedGems[i].transform.position; InForce.Set(InForce.x, 0, InForce.z); InForce.Normalize(); Vector3 force = (InForce * PickUpInForce) + (Vector3.up * PickUpUpForce); currentTargetGem.spawnedGems[i].GetComponent <Rigidbody>().AddForce(force * Time.fixedDeltaTime, ForceMode.Acceleration); } yield return(null); } TractorBeam.SetActive(false); playerManager.ScanData(true); //Destroy(currentTargetGem); if (GemsToCollect.Count == 0) { break; } yield return(null); } fetchingGems = false; yield return(new WaitForSeconds(1f)); currentState = State.Wandering; readyToMove = true; ScannerAnims.ResetTrigger("StopScanning"); StartCoroutine(Wandering()); }
IEnumerator Wandering() { //If don't have a current waypoint if (currentWaypoint == null) { FredWaypoint bestWaypoint = null; //if you have a last waypoint, go to that if (lastWaypoint != null) { bestWaypoint = lastWaypoint; } else { //find the closest waypoint and move to that float bestDist = 1000; foreach (Transform _waypoint in Waypoints) { float dist = Vector3.Distance(_waypoint.position, transform.position); if (dist < bestDist) { bestDist = dist; bestWaypoint = _waypoint.GetComponent <FredWaypoint>(); } } } if (bestWaypoint != null) { //Move to best Waypoint StartCoroutine(MovingToWaypoint(bestWaypoint)); yield break; } } else { //you already have a waypoint, so you're on track and ready to move if (!reachedWaypoints.Contains(currentWaypoint)) { reachedWaypoints.Add(currentWaypoint); } } //Wandering Update Loop while (true) { //If ready to move to next wandering waypoint if (readyToMove) { readyToMove = false; //find new waypoint by choosing from the waypoints connected to the current waypoint. Don't choose lastWaypoint, and weight reached waypoints as less weight. //find weight for each waypoint, and then add to total weight int[] weightedWaypoints = new int[currentWaypoint.connectedWaypoints.Length]; int weightedTotal = 0; for (int i = 0; i < weightedWaypoints.Length; i++) { FredWaypoint _potentialWaypoint = currentWaypoint.connectedWaypoints[i]; if (lastWaypoint != null && _potentialWaypoint == lastWaypoint) { //you were just there, low weight weightedWaypoints[i] = 3; } else if (reachedWaypoints.Contains(_potentialWaypoint)) { //you've been there, average weight weightedWaypoints[i] = 4; } else { //new place, highest weight weightedWaypoints[i] = 6; } weightedTotal = weightedTotal + weightedWaypoints[i]; } int randomWeight = Random.Range(0, weightedTotal); FredWaypoint targetWaypoint = null; //loop through weights until total is greater than randomweight, then select that waypoint int counter = 0; for (int i = 0; targetWaypoint == null; i++) { counter++; if (i == weightedWaypoints.Length) { i = 0; } int currentWeight = weightedWaypoints[i] + counter; if (currentWeight > randomWeight) { targetWaypoint = currentWaypoint.connectedWaypoints[i]; break; } } if (targetWaypoint != null) { //StartMovingToWaypoint and set readyToMove to false StartCoroutine(MovingToWaypoint(targetWaypoint)); readyToMove = false; yield break; } else { Debug.Log("no good points"); StartCoroutine(MovingToWaypoint(currentWaypoint.connectedWaypoints[Random.Range(0, currentWaypoint.connectedWaypoints.Length - 1)])); readyToMove = false; yield break; } } yield return(new WaitForSeconds(1)); } yield break; }