Exemple #1
0
    // 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?
        }
    }