How should I code units in an RTS game?

I think I’ve posted this question before, but I still am super confused.

I have a class “AUnit”, and I plan to extend that class to different units.

Ex, Unit->Soldier, Unit->Sniper

So I would have snipers and soldiers. They would be units.

The problem with this is that once I get all my units into an array, I can no longer use these units as sniper or soldier.

Hierarchy:

Actor->Pawn->Unit->Soldier/Sniper

If I get all units, then I can no longer use the class specific items I had. So specific hp/damage/movement speed all goes away.

Is there a way to get all Units and then decide what child class they belong to?

Or should I be doing this a completely different way?

You shouldn’t care about what type of unit they are. They should all share a common parent class, which would be “AUnit”. What you need to do is treat your AUnit class as an abstract class. Have methods that are pure virtual methods and for every class that inherits from AUnit, they will implement these pure virtual methods how they wish. You have an array or AUnit objects and you just let the polymorphism do its work.

class AUnit
{
public:
    virtual void MoveXDirection(float dir) = 0;
    virtual void MoveYDirection(float dir) = 0;
    virtual void Attack() = 0;
    virtual void UseSpecial() = 0;
}

class ASniperUnit : AUnit
{
    virtual void MoveXDirection(float dir)
    {
        // Look at the walkSpeed for this unit, among other vars, and decide 
        how this unit should move in the x-direction.
    }
    virtual void MoveYDirection(float dir)
    {
        // Look at the walkSpeed for this unit, among other vars, and decide 
        how this unit should move in the Y-direction.
    }
    virtual void Attack()
    {
        // Look at the damageVal for this unit, among other vars, and decide 
        how this unit should attack and the damage is should output (before
        external modifiers, maybe the other players armor)
    }
    virtual void UseSpecial()
    {
        // Look how the special move effects this unit.
    }
}

class ASoldierUnit : AUnit
{
    virtual void MoveXDirection(float dir)
    {
        // Look at the walkSpeed for this unit, among other vars, and decide 
        how this unit should move in the x-direction.
    }
    virtual void MoveYDirection(float dir)
    {
        // Look at the walkSpeed for this unit, among other vars, and decide 
        how this unit should move in the Y-direction.
    }
    virtual void Attack()
    {
        // Look at the damageVal for this unit, among other vars, and decide 
        how this unit should attack and the damage is should output (before
        external modifiers, maybe the other players armor)
    }
    virtual void UseSpecial()
    {
        // Look how the special move effects this unit.
    }
}

So you’re on the right track. You want to keep an array of your units that you have selected, or even if you are selecting one individually you would just have an array of 1. You will work on all of you units at the highest level possible (AUnit). Here is some sudo:

list<AUnit> selectedUnits;

void OnUnitsSelected()
{
    // populate your list
}

void OnMoveUnits(Vector2 direction)
{
    foreach AUnit in selectedUnits : myCurUnit
    {
        myCurUnit->MoveXDirection(direction.x);
        myCurUnit->MoveYDirection(direction.y);
    }
}

void OnAttack()
{
    foreach AUnit in selectedUnits : myCurUnit
    {
        myCurUnit->Attack();
    }
}

Use two arrays, before you add one unit to the array that holds all units (TArray) you add one item to the other array (TArray) that will hold the unit’s specific class. Or you could use bidimensional arrays (I never used it).

Did this ever work for you?

So I ended up creating a character class called AUnit, then making child classes of it for different types of units.

I have virtual functions in my AUnit class, so when I call functions they go down to my child classes to see what their form of that function is.

so like when I tell my active units to move, it calls a pure virtual function that only calls whatever their form of move is.

Is it safe to say, then, that you can accept my answer? :smiley: