Baldur's Gate, MechCommander, Neverwinter Nights, Dragon Age: Origins and Pillars of Eternity: games featuring squad-level real-time with pause tactical gameplay. Those beloved franchises balance a mix of RPG micromanagement and battlefield strategy, but there's a void.
As a fan of Car Wars, The Road Warrior, Spy Hunter and Death Race, I want to arm and armor a squad of post-apocalyptic muscle cars then send them into the wasteland to challenge gangs of jury-rigged monstrosities-on-wheels fighting over gasoline and spare parts.
Engines like Unreal (and Unity) are available for free and it's easier than ever for inexperienced developers to create games. With no eagerly anticipated announcements forthcoming, like any smug mature gamer with a programming background I thought, "How hard could it be?"
As we're going to find out, fairly hard.
"Simple" Vehicle Movement
The first feature to tackle is point-and-click movement. Instead of directly controlling a single vehicle, we want a squad of vehicles to drive themselves to a specified destination.
I assumed it would be as simple as importing a vehicle from one of the examples, build a Behavior Tree Task and send it a MoveTo.
Except that pawns using the WheeledVehicleMovement component don't respond to MoveTo. They respond to Throttle, Steering and Handbrake. So not only do we have to tell it where to go, but how to get there.
The typical approach to racing game AI is to pre-build waypoints into a circular track. That won't work for this game due to the open-world style maps. We need to tell a vehicle to move from anywhere to anywhere. Fortunately, we can still use Unreal's NavMesh intended for character pawns. The FindPathToLocationSynchronously function simply needs Start and End vectors. The result is a NavigationPath object, which includes an array of Path Point vectors.
Now we can build a short Behavior Tree Service that recalculates a path from the vehicle's location to its destination. Finally, have the vehicle always steer toward the next waypoint, NavPoints[1], and set the throttle to 1.0 (for now). Our logic so far looks like:
Here's what it looks like in-game:
Next time, we'll make the throttle smarter and make use of the handbrake.
As a fan of Car Wars, The Road Warrior, Spy Hunter and Death Race, I want to arm and armor a squad of post-apocalyptic muscle cars then send them into the wasteland to challenge gangs of jury-rigged monstrosities-on-wheels fighting over gasoline and spare parts.
Engines like Unreal (and Unity) are available for free and it's easier than ever for inexperienced developers to create games. With no eagerly anticipated announcements forthcoming, like any smug mature gamer with a programming background I thought, "How hard could it be?"
As we're going to find out, fairly hard.
"Simple" Vehicle Movement
The first feature to tackle is point-and-click movement. Instead of directly controlling a single vehicle, we want a squad of vehicles to drive themselves to a specified destination.
I assumed it would be as simple as importing a vehicle from one of the examples, build a Behavior Tree Task and send it a MoveTo.
Except that pawns using the WheeledVehicleMovement component don't respond to MoveTo. They respond to Throttle, Steering and Handbrake. So not only do we have to tell it where to go, but how to get there.
The typical approach to racing game AI is to pre-build waypoints into a circular track. That won't work for this game due to the open-world style maps. We need to tell a vehicle to move from anywhere to anywhere. Fortunately, we can still use Unreal's NavMesh intended for character pawns. The FindPathToLocationSynchronously function simply needs Start and End vectors. The result is a NavigationPath object, which includes an array of Path Point vectors.
Who says A* Pathfinding is complicated?
Now we can build a short Behavior Tree Service that recalculates a path from the vehicle's location to its destination. Finally, have the vehicle always steer toward the next waypoint, NavPoints[1], and set the throttle to 1.0 (for now). Our logic so far looks like:
I thought you said this was hard?
Next time, we'll make the throttle smarter and make use of the handbrake.