// Update is called once per frame void Update() { if (isMoving) { // TODO: If a unit is blocked, but is "near enough" its destination, allow it to stop there // (i.e., for formation movement). Need to somehow consider whether a unit moved as part of the // same order has reached its destination already. if (unitIsBlocked && hasNextPosition) { Vector2Int nextPos2Int = MapController.Instance.WorldToCell(nextPosition); if (MapController.Instance.UpdateUnitPosition(this, nextPos2Int)) { unitIsBlocked = false; } } if (!hasNextPosition && navAgent.HasNextCell()) { Vector2Int nextPos2Int = navAgent.PopNextCell(); nextPosition = MapController.Instance.GetCellCenterWorld(nextPos2Int); hasNextPosition = true; // Immediately update the map position to the neighbouring square if (!MapController.Instance.UpdateUnitPosition(this, nextPos2Int) && !unitIsBlocked) { unitIsBlocked = true; // If the agent is blocked and the destination cell is not occupied, // calculate a new path. if (!MapController.Instance.mapModel.IsOccupied(navAgent.destination)) { navAgent.RecalculatePath(); hasNextPosition = false; } else if (onBlockedAction != null) { hasNextPosition = false; navAgent.SetDestination(onBlockedAction.Invoke()); } } } else if (!hasNextPosition && !navAgent.HasNextCell()) { isMoving = false; unitIsBlocked = false; } if (hasNextPosition && !unitIsBlocked) { transform.position = Vector2.MoveTowards(transform.position, nextPosition, Time.deltaTime * moveSpeed); if (Vector2.Distance(transform.position, nextPosition) == 0f) { hasNextPosition = false; if (!navAgent.HasNextCell() && onArriveAction != null) { // When unit arrives at destination, invoke onArriveAction onArriveAction.Invoke(); } } } } if (InputController.Instance.isSelecting && InputController.Instance.IsInSelectRect(this)) { // TODO: Visual indicator of tentative selection? } }