top of page

Impulse: Player and AI Character Movement

Since my last post I have been researching, experimenting with and then finally implementing my in-combat movement system. In my first attempt, I created a system which used Unity's nav agent components to move a given character automatically to a location clicked on by the player and expend energy points based on the distance travelled. This worked ok but there was an issue. Energy points are a integer variable so that they can be displayed clearly to the player. Positions are, of course, vector variables, made up of three floats. As such, a character will nearly always move a non-integer distance such as 1.234 rather than 1, and so will expend a non-integer amount of energy. I could resolve this by making the energy a float but then each character will find it very hard to expend all of their energy on their turn and end up with some left over, making the player feel as though they are being sub-optimal. I may revisit this system at a later date but for now I have scrapped it and moved on.


I then attempted to use a tilemap system to generate a grid that characters could move on, expending one energy point for each grid space they move. After much trail and error though I decided that it was not worth my time to try and learn how to properly use the tilemap system in this way.


Finally I decided to effectively combine the two previous systems. The movement system I have settled on for now rounds my mouse position to the nearest whole unit and places a square sprite there. When the ground is clicked, the active character will move to the square's location using their nav agent component, if they have enough energy to do so, and they will expend energy equal to the number of units they have moved. This system does not require the use of tilemaps and yet ensures that characters only move integer distances and so only expend integer quantities of energy, allowing values to be clear and manageable for the player.


Here is the code in the update function used to select a location and move a character to it:

With my movement system in place, created a Turn system. When the battle starts, the first character in the Turn order (determined by their speed variable) is set as the active character, and marked as such. If their faction variable is set to "friendly" the player then has control over this character until they expend all of their energy performing actions. That character's Turn is then ended and the next character in the turn order becomes the active character. Once all characters have completed their Turn, the Round then ends. When a round ends, every character is restored to full energy and it becomes the first character's Turn again.


Start Battle Function:

round and turn functions:

I have also begun creating my AI to pilot the enemy characters. When the active character runs out of energy, their turn is ended and the next character in the turn order becomes the active character. If this character's faction variable is set to "enemy" rather than "friendly", the player's input is disabled and the enemySelectAction function is triggered. This randomly selects one of the actions stored in the character's actions list. As movement is the only action available to any character at the moment, this is always selected. Once the movement action is selected, a random integer from 0 to 3 is generated, this determines if the character will move up, down, left or right. A collision check is performed to ensure there is nothing blocking the space the character intends to move to and if it is empty then the character expends 1 energy and moves 1 space in the chosen direction. If something is in the way then the function loops until it finds a unoccupied space to move to. This process repeats until the character has expended all of their energy.


Here is the top half of the AI movement function, the rest is cut off for space. It works the same as this bit but for the other two directions:

Here is a video of everything in action:


Kommentare


bottom of page