RTS game development - Week #1
Tags: csharp, unity3d, gamedev
Published: 2019-09-16 19:58:17

I'm going to make a RTS game in Unity3D. I would like to mark my development here. Hope you'll find it interesting. It is open source in this repository: https://gitlab.com/Kipash/rts-concept (it was, contact me if you are interested)

#Before (commit 3f31d24)#
First, I made the grid, but then I realized I want to use mesh-based pathfinding which is already build-in into Unity.

So I've created a simple capsule with the Nav agent. And a custom Unit script with minimal logic. Just the basics, like GoTo method, which commands the Nav agent to go to a world position.

```c#
public void GoTo(Vector3 worldPosition)
{
    print($"GoTo: {worldPosition}");
    agent.SetDestination(worldPosition);
    agent.isStopped = false;
}
```

Then I made the box selection, which I had no clue how to do and haven't tested the performance so far. 

Thanks to... {% user brianpeek %} ...and his GameDev news, I was able to read a bit about UI optimization [here](https://www.gamedev.net/articles/programming/general-and-gameplay-programming/unity-ui-the-gurus-ui-development-diagram-r5197/). I do recommend reading it as well. It's good for semi beginners and I generally enjoyed it and will use a couple of things which were pointed out there.

Back to UI, I focused on the box selection UI, I've never done that, so ... I was a bit lost with the way how to stretch an UI element between two points, drag start and drag end. But then it got me. If we set the pivot to (0, 1) then we are able to set the height and width to the difference between the drag start and end. Then just setting the position of the UI element to the drag start. After that conclusion it was a piece of cake.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/14mg6h36ihm2yvajltke.png)

```C#
Tuple<Vector2, Vector2> NormalizeDrag(Vector2 start, Vector2 end)
{
    Vector2 a = new Vector2(
        start.x > end.x ? end.x : start.x,
        start.y > end.y ? end.y : start.y
    );
    Vector2 b = new Vector2(
        start.x > end.x ? start.x : end.x,
        start.y > end.y ? start.y : end.y
    );
    return new Tuple<Vector2, Vector2>(a, b);
}
```

For the ones who don't know what Tuple is (google it tho), a neat way how to wrap more values/variables into an instance of a class, so you can return multiple types at once.

What I'm doing here is normalizing the drag, since you can have 4 different directions of drag (from top right to down left ... from bottom left to top right ... etc). And so this way the main implementation which checks if the unit is in the selection, can be implemented just for one type of drag direction because we make sure that it is normalized to this direction.

note: `unitManager.GetVisibleUnits()` does filter all units on screen. But not in our custom selection.

```c#
foreach (var unit in unitManager.GetVisibleUnits())
{
    Vector2 uPos = cam.WorldToScreenPoint(unit.transform.position);

    //Is in selection
    if (a.x - boxSelectBias < uPos.x && uPos.x < b.x + boxSelectBias &&
        a.y - boxSelectBias < uPos.y && uPos.y < b.y + boxSelectBias)
    {
        selectedUnits.Add(unit);
        print("yes");
    }
}
```

![RTS_before_week#1](https://cdn.discordapp.com/attachments/549030720480477189/613374197833400350/XJR60MDgiP.gif)

#Week #1 (commit 456a00c)#

So then I followed with a pool of Labels, which are positioned over selected units. Problem is with the UI elements are overlapping and that is visually unpleasant.

![RTS_week#1_1](https://media.giphy.com/media/PjrZ3qJd2SJvZnrPAd/giphy.gif)

Added formations, which first were a big challenge but eventually the vision was clear what to achieve and how to do it. By that I mean, its just a simple offset along 2 axes.

```c#
Vector3 destination = mouseclickPosition +
                      ( horizontalDir * colum * spacing) +
                      (-verticalDir   * row   * spacing);
```


Having a major problem with the sorting which unit should go to which spot. Currently, it's linear to the list of all units... so it creates long transitions in certain cases. 

```C#
selectedUnits[i].GoTo(destination);
```
So as you can see, I'm always telling the first unit in the list to go to the most upper left position every time I click. I would rather base the order on some kind of distance but haven't found a condition yet.

![RTS_week#1_2](https://media.giphy.com/media/kG3gexa79B6gbjWtXI/giphy.gif)

I played just a few RTSes but extensively. All of Age of Empires, StarCraft 1, Stronghold Crusader and Command and Conquer: Generals. I love how the unit grouping and destination visualisation is made in Stronghold. You select your units and wherever you clicked it will try to make a square shape formation. The destinations are visible for every unit. That means, you can deselect all, select just one and you'll see its destination.

For me, I feel the player should have more power over the shape of the group ... since with more massive battles ... real formations are better.

![Formation](https://thepracticaldev.s3.amazonaws.com/i/f45nmac9tcie11fhze74.jpg)

That's it, not sure how often per week I will release these updates but in general ... I really enjoy this and I hope I might say something valuable.