Search Unity

Not sure how to implement enemy movement for a roguelike game

Discussion in 'Scripting' started by Fruitfly08, Sep 25, 2021.

  1. Fruitfly08

    Fruitfly08

    Joined:
    Feb 5, 2021
    Posts:
    69
    I've been working on a turn based top-down style game, and I've been able to get everything working except for actually implementing enemy AI, I looked for examples and tutorials online, but unfortunately all the examples were either too specific to the example project that I couldn't use it for the game, or the AI wasn't actually that good, some examples were just how to get the enemy to move in a straight line towards the player in a turn based way, which doesn't make for good AI, right now I just would want the enemy to be able to use it's position and the player's position to calculate a path that would take the enemy the shortest way to the player, probably just through trying every possible path and picking the shortest one since I know it's really difficult to write an algorithm that can perfectly find the shortest path first try. It would also have to check for obstacles, such as walls, other enemies or the player, so the enemy doesn't just walk over that stuff. Would anyone know of good resources or a tutorial that handles this? or I guess if you know how to do this yourself that works too. Also, if you need to see any of my scripts, please let me know, I currently don't have much of an enemy AI script which is why I didn't post it.
     
  2. NocturnalWisp

    NocturnalWisp

    Joined:
    Oct 2, 2019
    Posts:
    62
    Hello!

    I've worked with a number of pathfinding algorithms, unfortunately Unity does not have a good implementation for 2D pathfinding. I first learnt about pathfinding by starting off with the basic algorithms and working my way up.

    This resource goes over the Dijkstra’s Algorithm pretty well: Pathfinding Algorithms. Please read me | by Chet Chopra | The Startup | Medium. Once you understand how the initial algorithm works you can move on to A* which tends to be the most efficient at finding the shortest path.

    For A* I am pretty partial to this explanation: A* Search Algorithm - GeeksforGeeks.

    If you just need the algorithm and don't want to do it yourself, there are loads of examples both paid and free of A* on the assets store.

    Often rogue-likes top-down style only implement the basic follow the player because the player and enemies are normally very close when they meet, however you can calculate the best path by determining if a space is occupied by something else or not.

    Hope this helps!
     
  3. Fruitfly08

    Fruitfly08

    Joined:
    Feb 5, 2021
    Posts:
    69
    Thank you!, this does help a lot, I'll be sure to try out that stuff, and I'll let you know how it goes later
     
  4. NocturnalWisp

    NocturnalWisp

    Joined:
    Oct 2, 2019
    Posts:
    62
    For sure! And of course, there are lots of different kinds of pathfinding algorithms. Do some exploring; it's a neat topic!

    Best of luck. :)
     
    Fruitfly08 likes this.
  5. Fruitfly08

    Fruitfly08

    Joined:
    Feb 5, 2021
    Posts:
    69
    I got started on writing the script, although, I've run into a weird issue, I'm currently just writing the part where enemy moves based off RNG when they would be in corridors or rooms without the player, I haven't gotten far with the script though because for some reason it will only call the chunk off the script that moves the enemy to side when the player moves
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class EnemyAI : MonoBehaviour
    4. {
    5.     public GameObject PlayerPosition;
    6.  
    7.     Vector3 currentPosition;
    8.     Vector3 desiredPosition;
    9.  
    10.     float CellSize = 1.0f;
    11.     float MoveSpeed = 5.0f;
    12.  
    13.     Vector3 SpawnPoint;
    14.  
    15.     void Start()
    16.     {
    17.         SpawnPoint = new Vector3(transform.position.x, transform.position.y, 0);
    18.     }
    19.  
    20.     void ReadInput()
    21.     {
    22.         if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.W) | Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.D))
    23.         {
    24.             int x = 0;
    25.             int y = 0;
    26.  
    27.             if (Random.value < 0.5f)
    28.             {
    29.                 //we move to the side
    30.                 if (Random.value < 0.5f)
    31.                 {
    32.                     // we move left
    33.                     x = -1;
    34.                     y = 0;
    35.                 }
    36.                 else
    37.                 {
    38.                     //we move right
    39.                     x = 1;
    40.                     y = 0;
    41.                 }
    42.             }
    43.             else
    44.             {
    45.                 //we move up or down
    46.                 if (Random.value < 0.5f)
    47.                 {
    48.                     // we move down
    49.                     y = -1;
    50.                     x = 0;
    51.                 }
    52.                 else
    53.                 {
    54.                     //we move up
    55.                     y = 1;
    56.                     x = 0;
    57.                 }
    58.             }
    59.  
    60.             if (x < -0.5f)
    61.             {
    62.                 desiredPosition += Vector3.left * CellSize;
    63.             }
    64.             if (x > 0.5f)
    65.             {
    66.                 desiredPosition += Vector3.right * CellSize;
    67.             }
    68.             if (y > 0.5f)
    69.             {
    70.                 desiredPosition += Vector3.forward * CellSize;
    71.             }
    72.             if (y < -0.5f)
    73.             {
    74.                 desiredPosition += Vector3.back * CellSize;
    75.             }
    76.         }
    77.     }
    78.  
    79.     bool Moving()
    80.     {
    81.         // move
    82.         currentPosition = Vector3.MoveTowards(currentPosition, desiredPosition, MoveSpeed * Time.deltaTime);
    83.  
    84.         // rotate
    85.         //currentRotation = Mathf.MoveTowardsAngle(currentRotation, desiredRotation, RotationSpeed * Time.deltaTime);
    86.  
    87.         // done?
    88.         Vector3 d = currentPosition - desiredPosition;
    89.         return d.magnitude > 0.01f;
    90.     }
    91.  
    92.     void DriveTransform()
    93.     {
    94.         transform.position = currentPosition + new Vector3(SpawnPoint.x, SpawnPoint.y, 0);
    95.     }
    96.  
    97.     void Update()
    98.     {
    99.         if (!Moving())
    100.         {
    101.             //if (!IsAttacking)
    102.             //{
    103.                 ReadInput();
    104.             //}
    105.         }
    106.  
    107.         DriveTransform();
    108.     }
    109. }
    right now the goal of this script is to have either up, down, left or right to be picked randomly and the enemy just moves that way, I haven't added checks for collision or the player yet since I'm just trying to get this part to work, do you have any suggetions for how to get this to work?
     
  6. NocturnalWisp

    NocturnalWisp

    Joined:
    Oct 2, 2019
    Posts:
    62
    It only moved when the player moves because of this line
    Code (CSharp):
    1. if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.W) | Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.D))
    You are checking for input from the player and running if the player input an action resulting in the enemy moving at the same time. Sound like you need some kind of turn system. The official unity tutorial on roguelikes implements a pretty good system: https://learn.unity.com/tutorial/unit-mechanics?uv=5.x&projectId=5c514a00edbc2a0020694718 That link should take you directly to unit mechanics which is the part it talks about turn based movement I believe.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
  8. NocturnalWisp

    NocturnalWisp

    Joined:
    Oct 2, 2019
    Posts:
    62
    I agree with that content! They also wrote game programming patterns. Very intelligent person.
     
    Kurt-Dekker likes this.
  9. Fruitfly08

    Fruitfly08

    Joined:
    Feb 5, 2021
    Posts:
    69
    Thanks everyone, I'll try that