+2 votes

I have really been trying to make the enemy follow the player for 2 weeks and is becoming, honestly, boring. This is not the ideal experience I wish to have when making my games, but there you go.

The game is top-down and there is only 4 way movement (e.g. -y, y, -x, x). One problem, is if I am diagonally from the enemy he walks diagonally. Could I use a tilemap to do this??

If you suggest using an area 2d, pls show advancements to my code which I have presented (I would also like to use a circular area2d, if possible)

EDIT: the walking is working but it is still choppy, like the enemy isn't following my character when I'm in range and it runs by itself with my being in range.
It is very likely that I've seen the tutorials if you present them. I have seen the gdscript one, as he's one of the first people I go to.

func _physics_process(delta):
velocity = move_and_slide(velocity)
if BEntered == player:
    if player.position.y < position.y:
        velocity.y = -speed 
    elif player.position.y > position.y:
        velocity.y = speed
    else:
        velocity.y = 0
if LEntered == player:
    if player.position.x < position.x:
        velocity.x = -speed
    elif player.position.x > position.x:
        velocity.x = speed
    else:
        velocity.x = 0
if nterd == player:
    if player.position.x < position.x:
        velocity.x = -speed
    elif player.position.x > position.x:
        velocity.x = speed

    if player.position.y < position.y:
        velocity.y = -speed 
    elif player.position.y > position.y:
        velocity.y = speed

    else:
        velocity = 0


func _on_DetectPlayer_body_entered(body):
    BEntered = player
func _on_DetectPlayer_body_exited(body):
    BEntered = null


func _on_DetectPlayer3_body_entered(body):
    LEntered = player
func _on_DetectPlayer3_body_exited(body):
    LEntered = null


func _on_Circle_body_entered(body):
    nterd = player
in Engine by (244 points)
edited by

Hey there! I can't really help you here, but I'd like to share with you a C# script from Unity that represents a basic enemy AI that will move toward the player and hover, while trying to avoid walls and the player. It does not have any pathfinding, it will move forever into a wall to get close to the player.

Again, it's the wrong code base and the wrong game engine, but it might help you see how to create such a thing, and it does work where it came from.

using UnityEngine;
using System.Collections;

public class SimpleAI : MonoBehaviour {
    public static GameObject player;  
    public float distanceFromPlayer;
    public Rigidbody rb;
    public float distanceToFloor;

    // Use this for initialization
    void Start()
  {
    player = GameObject.Find("Player");
    rb = GetComponent<Rigidbody>();
    }

  void CheckDistanceMove(float distanceFromPlayer)
  {
    if(distanceFromPlayer > 8.0f)
    {
      rb.AddForce(transform.forward * 8f);
      //now stabilize?
      //rb.velocity.x *= 0.99;
    }
    else //it is close enough so slow down
    {
      rb.AddForce(transform.forward * -8f);
      //Debug.Log(rb.velocity);
    }
  }


    void FixedUpdate() 
  {

    RaycastHit hit;
    //look where the player is looking
    //cast a ray from the player forward

    //look at the raycasthit.point

    transform.LookAt(player.transform);


    //check distance to player
    distanceFromPlayer = Vector3.Distance(transform.position, player.transform.position);

    //Debug.Log("Player y: " + player.transform.position.y);
    //Debug.Log("Bot y: " + transform.position.y);



    //push away from objects to the left and right
    Ray rightRay = new Ray(transform.position, Vector3.right);
    Ray leftRay = new Ray(transform.position, Vector3.left);

    //I am aware that left and right are weird here. Unity is weird.
    //check the right ray
    if (Physics.Raycast(rightRay, out hit))
    {
      float rightError = 2 - hit.distance;
      if(rightError > 0)
      {
        rb.AddForce(-3f * transform.right);
        Debug.Log("Pushing off right hit object");
      }
    }

    //check the wrong ray
    if (Physics.Raycast(leftRay, out hit))
    {
      float leftError = 2 - hit.distance;
      if(leftError > 0)
      {
        rb.AddForce(3f * transform.right);
        Debug.Log("Pushing off left hit object");
      }
    }

    //hover
    Ray downRay = new Ray(transform.position, -Vector3.up);
    if (Physics.Raycast(downRay, out hit)) 
    {
      //Debug.Log("Floor hit distance: " + hit.distance);
      float hoverError = 6 - hit.distance;
      if (hoverError > 0)
      {
        //Debug.Log("Hover error is: " + hoverError);
        rb.AddForce(11.0f * Vector3.up);
        CheckDistanceMove(distanceFromPlayer);
      }
      else if (player.transform.position.y > transform.position.y - 3) //if the player is elevated above the bot move up anyway
      {
        //Debug.Log("pushing bot up to match player!");
        rb.AddForce(11.0f * Vector3.up);
        CheckDistanceMove(distanceFromPlayer);
      }
    }
    }
}

1 Answer

0 votes

This seems overly complex for what you want. I suggest scrapping the code and replacing it by this:

var _player = null
const CHASE_SPEED= 200

func _physics_process(delta):
    if _player:
        var player_direction = (player.position - self.position).normalized()
        move_and_slide(SPEED * player_direction)

func _on_DetectPlayer_body_entered(body):
    if body.name == "Player":
        _player = body
func _on_DetectPlayer_body_exited(body):
    if body.name == "Player":
        _player = body
by (1,112 points)

I tried this already, but the enemy moves diagonally. Would you be able to suggest a form of 4 way movement?

Try this then:

func _physics_process(delta):
    if _player:
        var player_direction = player.position - self.position
        if player_direction.x > player_direction.y:
            player_direction.y = 0
        else:
            player_direction.x =0
        move_and_slide(SPEED * player_direction.normalized())
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.

Categories