private IEnumerator PerformMovementCoroutine(bool ignoreMoveCosts, Action postMovementCallback) { Animator.SetTrigger("Moving Requested"); IHexCell startingCell = PositionCanon.GetOwnerOfPossession(this); IHexCell currentCell = startingCell; Vector3 currentLocation = Grid.PerformIntersectionWithTerrainSurface(currentCell.AbsolutePosition); Vector3 a, b, c = currentLocation; yield return(LookAt(CurrentPath.First().AbsolutePosition)); float t = Time.deltaTime * Config.TravelSpeedPerSecond; while ((ignoreMoveCosts || CurrentMovement > 0) && CurrentPath != null && CurrentPath.Count > 0) { var nextCell = CurrentPath.FirstOrDefault(); Vector3 nextLocation = Grid.PerformIntersectionWithTerrainSurface(nextCell.AbsolutePosition); if (!PositionCanon.CanChangeOwnerOfPossession(this, nextCell) || nextCell == null) { CurrentPath.Clear(); break; } if (!ignoreMoveCosts) { CurrentMovement = Math.Max(0, CurrentMovement - PositionCanon.GetTraversalCostForUnit(this, currentCell, nextCell, false) ); } PositionCanon.ChangeOwnerOfPossession(this, nextCell); CurrentPath.RemoveAt(0); a = c; b = currentLocation; c = (b + nextLocation) * 0.5f; for (; t < 1f; t += Time.deltaTime * Config.TravelSpeedPerSecond) { transform.position = BezierQuadratic.GetPoint(a, b, c, t); Vector3 d = BezierQuadratic.GetFirstDerivative(a, b, c, t); d.y = 0f; transform.localRotation = Quaternion.LookRotation(d); yield return(null); } t -= 1f; currentCell = nextCell; currentLocation = Grid.PerformIntersectionWithTerrainSurface(currentCell.AbsolutePosition); } if (currentCell != startingCell) { a = c; b = currentLocation; c = b; for (; t < 1f; t += Time.deltaTime * Config.TravelSpeedPerSecond) { transform.position = BezierQuadratic.GetPoint(a, b, c, t); Vector3 d = BezierQuadratic.GetFirstDerivative(a, b, c, t); d.y = 0f; transform.localRotation = Quaternion.LookRotation(d); yield return(null); } } postMovementCallback(); Animator.SetTrigger("Idling Requested"); }