Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question What is the best way to implement a movement for a 2.5D enemy?

Discussion in 'Scripting' started by LazyGhost15, Dec 3, 2023.

  1. LazyGhost15

    LazyGhost15

    Joined:
    Feb 12, 2022
    Posts:
    108
    I have a 2D spider in a 3D world and I want it to chase the player, but if he is too far away from his spawn point he goes back to his territory to wonder. But I don't know how should I add the movement system
     
  2. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    594
    In development, you need to split your problem in smaller tasks and do one after another. In your case:

    1. Add a 2D spider GameObject to your scene.
    2. Create and attach a C# script to your spider (let's call it SpiderMovement.cs)

    Your spider has 2 states, "Chase the player", and "Return to territory", so you need 2 more steps + 1 shared step between the 2 "Get distance to player". We continue our steps list by adding those new 3 steps:

    3. Get distance to player: A simple
    Vector3.Distance(spider.transform.position, player.transform.position)
    is enough.

    4. Chase the player: If the distance (we got from step 3) is smaller or equals to chaseDistance (to be defined by you), we move the spider towards the player with a particular speed (again defined by you). A simple
    spider.transform.position = Vector3.MoveTowards(spider.transform.position, player.transform.position, speed * time.deltaTime)
    is enough.

    5. Return to territory: If the distance (we got from step 3) is bigger than chaseDistance, we move the spider back towards its territory (could be an empty GameObject you add to the scene). We do the same as step 4, but move the spider towards its territory rather than the player.

    Let's translate steps 3-5 into code:
    Code (CSharp):
    1. public class SpiderMovement : MonoBehaviour
    2. {
    3.     // Assign it from the Editor by drag-drop
    4.     public GameObject player;
    5.  
    6.     // Assign it from the Editor by drag-drop
    7.     public GameObject territory;
    8.  
    9.     public float speed = 1.0f;
    10.  
    11.     public float chaseDistance = 10.0f;
    12.  
    13.     // Combining steps 3-5
    14.     private void Update()
    15.     {
    16.         float distanceToPlayer = GetDistanceToPlayer();
    17.  
    18.         if (distanceToPlayer <= chaseDistance)
    19.         {
    20.             ChasePlayer();
    21.         }
    22.         else
    23.         {
    24.             ReturnToTerritory();
    25.         }
    26.     }
    27.  
    28.     // Step 3
    29.     private float GetDistanceToPlayer()
    30.     {
    31.         // this means "this spider"
    32.         return Vector3.Distance(player.transform.position, this.transform.position);
    33.     }
    34.  
    35.     // Step 4
    36.     private void ChasePlayer()
    37.     {
    38.         this.transform.position = Vector3.MoveTowards(this.transform.position, player.transform.position, speed * time.deltaTime);
    39.     }
    40.  
    41.     // Step 5
    42.     private void ReturnToTerritory()
    43.     {
    44.         this.transform.position = Vector3.MoveTowards(this.transform.position, territory.transform.position, speed * time.deltaTime);
    45.     }
    46. }
    As further improvement to your code, and since ChasePlayer() and ReturnToTerritory() do the same thing (except the spider destination), we can create a method MoveSpiderTowards() where we pass a GameObject as a destination:
    Code (CSharp):
    1. private void MoveSpiderTowards(GameObject destination)
    2. {
    3.     this.transform.position = Vector3.MoveTowards(this.transform.position, destination.transform.position, speed * time.deltaTime);
    4. }
    Then in our update, we get rid of ChasePlayer() and ReturnToTerritory() completely, and simply do:
    Code (CSharp):
    1. private void Update()
    2. {
    3.     float distanceToPlayer = GetDistanceToPlayer();
    4.  
    5.     if (distanceToPlayer <= chaseDistance)
    6.     {
    7.         MoveSpiderTowards(player);
    8.     }
    9.     else
    10.     {
    11.         MoveSpiderTowards(territory);
    12.     }
    13. }
    We can add more states, for example Attack, by adding a new condition that checks if the distance to the player is less than an attackRange float and trigger an Attack() method.
     
    Last edited: Dec 3, 2023
    LazyGhost15 likes this.