0
\$\begingroup\$

So I am making a 2d maze game where one of the enemies has to follow the player once it detects the player. I am currently using a steering method to steer the enemy towards the player and also when it detects a wall. I am not using any sort of path finding algorithm, just using steering to make a "dynamic" path finder. But I am having some trouble steering the enemy away from the walls and then resume moving towards the player.

This is what I am doing right now:

  • follow the player when it is detected
  • set the enemy's velocity towards the player.
  • use a raycast to detect if a wall is ahead
  • if raycast detects the wall, steer the enemy towards the direction it is moving in, then steer it towards the position of the player again. E.g if it is moving up while following the player and hits a wall on the left or right, it will steer up.

I am having a hard time steering the enemy away from the wall and then back towards the player again, because once it steers away from the wall and isn't hitting a wall anymore, it checks where the player is to resume it's pursuit, but then the player goes too far away from the enemy and so it doesn't know where to move towards.

Here is the code:

 void Update()
  {
     RaycastHit2D hit2D = Physics2D.Linecast(transform.position, player.transform.position, 1 << 8);
     if (hit2D)
     {
         string wallTag = hit2D.collider.tag;
         FindMovementDirection(ref wallTag);
         wallHit = true;
     }
     else
     {
         wallHit = false;
     }
  }
 void FindMovementDirection(ref string wallTag)
 {
     int len = 3;
     if (wallTag == "V_Wall")
     {
         if (currentVel.y <= 0) currentDirection.localPosition = new Vector3(0, -len, 0);
         else currentDirection.localPosition = new Vector3(0, len, 0);
     }
     else if (wallTag == "H_Wall")
     {
         if (currentVel.x <= 0) currentDirection.localPosition = new Vector3(-len, 0, 0);
         else currentDirection.localPosition = new Vector3(len, 0, 0);
     }
 }
 void seekSteer()
  {
     float maxForce = 0.8f;
     float maxSpeed = 6;
     if (wallHit)
     {
         desiredVel = currentDirection.position - transform.position;
     }
     else
     {
         desiredVel = player.transform.position - transform.position;
     }
     desiredVel.Normalize();
     desiredVel *= maxSpeed;
     steerVel = desiredVel - currentVel;
     if (steerVel.magnitude > maxForce)
     {
         steerVel.Normalize();
         steerVel *= maxForce;
     }
     currentVel += steerVel;
     if (currentVel.magnitude > maxSpeed)
     {
         currentVel.Normalize();
         currentVel *= maxSpeed;
     }
 }
 void FixedUpdate()
 {
     transform.position += currentVel * Time.fixedDeltaTime;
 }

Another thing that I would like to ask is that, should I be using a path finding algorithm? I am aware that I am not using one and that is because I want the enemy to find it's path dynamically. I also know that path finding and steering go hand in hand most of the time, so am I doing it wrong? Thanks.

\$\endgroup\$
  • \$\begingroup\$ Can you describe what you mean by "I want the enemy to find its path dynamically"? Is finding a path using a pathfinding algorithm not dynamic, in this sense? \$\endgroup\$ – DMGregory Aug 15 '17 at 12:15
  • \$\begingroup\$ what I mean to say is that I want the enemy to find the path to the player using the steering behavior and not some algorithm where it "finds" the path for the enemy \$\endgroup\$ – nz881 Aug 15 '17 at 12:18
  • \$\begingroup\$ I once tried to do something similar to you and never really succeeded; the enemies always didn't move correctly once the player was too far away or the maze got too complicated, so I ended up implementing a pathfinding algorithm. What if you did something pacman style: Let the enemies path-find their way to the player, but shortly before they reach him, the drift into another direction or something like that… if thats what you want, of course. \$\endgroup\$ – Ignatiamus Jan 10 '18 at 14:52
1
\$\begingroup\$

Save yourself some trouble. Since you are using Unity, you have access to NavMeshes. You specify a surface as walk-able (the floor of the maze), and then Unity will form a mesh from all its flat surfaces. In other words, all walls will be excluded from this mesh. Unity uses this to figure out how to get from any point on the floor to any other point on the floor. Then, you make the enemy a NavMesh Agent, assign it the NavMesh, and then make the player a target. That will take care of all the pathfinding, and even update the path as the target player moves. The tutorials are easy to follow and shouldn't take that long.

Your other options are to implement pathfinding yourself, which is rarely worth it and usually more buggy, or to have your simple navigation get your enemy trapped in a dead end or going in circles.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.