Grid-based path-finding, similar to Legend of Grimrock/Eye of the Beholder...

I am working on an old-school grid-based first-person dungeon crawler and my prototype is almost complete. The only thing I have to work on is enemy path-finding. My enemy has a wander AI that is active when the FoundPlayer bool is false. He has a box collider that is stretched out really far in order to detect the player GameObject. As soon as I start scripting, I come to a halt. I am completely clueless how to lay this out.

Another thing you may spot is inefficient is the Random.Range to check when to move; however, I had to increase the value so as the enemy does not move as often. If you can suggest a more effective/efficient approach, I’m all ears :slight_smile:

Here is my enemy movement script:

using UnityEngine;
using System.Collections;

public class EnemyMovement : MonoBehaviour {
	
	public static bool CanMoveForward;

	public bool FoundPlayer;

	//Translation:
	float movSpeed = 4.0f;
	Vector3 pos;
	Transform tr ;
	public static bool moving = false;
	
	//Rotation:
	public static bool rotating = false;
	public float rotSpeed = 360f;
	float rotDegrees = 0f;
	Quaternion rotToAngle ;
	
	void Start () {  
		pos = transform.position;
		tr = transform;

		CanMoveForward = true;

		FoundPlayer = false;
	}
	
	// Update is called once per frame
	void Update () {

		int randomValue = Random.Range (1, 100);

		Debug.DrawRay(transform.position, transform.forward, Color.red);

		if (!moving && !rotating && !FoundPlayer) {

			if (randomValue == (1 | 2) && tr.position == pos && CanMoveForward) {
				pos += transform.forward;
				moving=true;
			}

			else if (randomValue == 5 && tr.position == pos) {
				rotDegrees -= 90f;
				rotToAngle = Quaternion.Euler(0, rotDegrees, 0);
				rotating = true;
			}

			else if (randomValue == 6 && tr.position == pos) {
				rotDegrees += 90f;
				rotToAngle = Quaternion.Euler(0, rotDegrees, 0);
				rotating = true;
			}

		} else if (FoundPlayer) {

		}
		
		
		
		//Translation:
		if (moving) {
			if (Vector3.Distance(transform.position,pos) <0.05f){
				transform.position = pos;
				moving=false;
				//				print ("FINISHED MOVE");
			} else {
				transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * movSpeed);
			}
		}
		
		//Rotation:
		if (rotating) {
			if (Quaternion.Angle(transform.rotation,rotToAngle) <10f) {
				transform.rotation = rotToAngle;
				rotating=false;
				//				print ("FINISHED TURN");
			} else {
				transform.rotation = Quaternion.RotateTowards(transform.rotation, rotToAngle, rotSpeed * Time.deltaTime);
			}
		}
	}
	
}

Thanks in advance!

For pathfinding you can use any of the existing pathfinding algorithms available like A*. Now A* is graph based algorithm but your grid can be converted to work with graph based algorithms. The article Grid pathfinding optimizations provides some insight on how to use A* or Dijkstra’s Algorithm for grid based pathfinding (This article has a link to another article link text which explains the process in detail) and optimizations. You might want to start with these algorithms for path finding.

Or you can even use NavMesh and translate the path to work with a grid based system. Here you need to convert the path based on your grid and then move your enemy using this newly constructed grid based path.

Another thing you may spot is
inefficient is the Random.Range to
check when to move; however, I had to
increase the value so as the enemy
does not move as often.

Rather than performing Random.Range in each Update you can decide a target position for your enemy and then check if your enemy has reached target position and then decide a new position for it to move to. Or you can use Coroutines to decide target position for your enemy after each set time interval.

I would like to put in another suggestion for an existing A* pathfinding solution: Astar Pathfinding project by Aron Granberg, it is available on the Asset store for free, with an advanced version that costs around $100 IIRC. The basic version will probably suffice for your needs and it comes with support for grid-based graphs.