Make an enemy follow along a wall

I have a 3d tile based map. I am trying to get an enemy to follow the wall of a room (either the wall on it’s left or right consistently per enemy).

The yellow line above is only indicative of direction and movement, it should still move to the tiles and trace around the outer walls.

The code I have will turn around ok when it hits a wall, but will still cut across the room even if there is a path around the outside.

    void Update() {
        transform.LookAt(moveDestination);
        if(transform.position.x == moveDestination.x && transform.position.z == moveDestination.z) {
            isMoving = false;
        } else {
            isMoving = true;
        }
        if(isMoving == false) {
            RaycastHit hit;
            if(Physics.Raycast(transform.position,transform.forward,out hit,scale)) {
                if(Physics.Raycast(transform.position,-transform.right,out hit,scale)) {
                    transform.LookAt(transform.position + (-transform.right * scale));
                } else {
                    transform.LookAt(transform.position + (-transform.right * scale));
                }
            } else {
                moveDestination = transform.position + (transform.forward * scale);
            }
        }
    }

        void FixedUpdate() {
        transform.position = Vector3.MoveTowards(transform.position,moveDestination,moveSpeed * Time.deltaTime);
    }

The answer was if the left Raycast did not hit anything, perform a Raycast one tile behind the enemy. If that Raycast did hit something then turn to the left.

So simple but took a lot of working out.

Storing info about the level for AI is much more proficient than raycasting and handy as the game progresses. Run this in an empty scene to see what i’m talking about:

	public Vector2 [] directions = new Vector2[]{
		new Vector2(-1,0),
		new Vector2(0,1),
		new Vector2(1,0),
		new Vector2(0,-1)};
	int dir;
	public int direction{
		get{return dir;}
		set{int d  = value;
			if(value>directions.Length-1){d=0;}
			if(value<0){d=directions.Length-1;}
			dir = d;
		}

	}
	public int x = 50;
	public int y = 50;
	public int px = 25;
	public int py = 25;
	public int gotox = 25;
	public int gotoy = 25;
	public Vector3 tp;

	public bool[][] iswall;

	GameObject g;
	GameObject dude;
	bool foundwall;
	void Start () {
		direction = 1;

		// create a 2D array to store info about the level
		x=50;
		iswall = new bool[x][];
		while(x>0){x--;iswall[x]=new bool[50];}


		// generate a level for example purpose
		x=50;

		while(x>0){x--;
			y=50;
			while(y>0){y--;
				g=GameObject.CreatePrimitive(PrimitiveType.Cube);
				g.transform.position = new Vector3(x,y,0);

				int r =Random.Range(0,Mathf.Abs(25-x));
				if(x==0||y==0||x==49||y==49){r=50;}
				if(r>10){g.transform.renderer.material.color= Color.red;iswall[x][y]=true;}
				else{g.transform.renderer.material.color= Color.green; }

		}
	}
		dude=GameObject.CreatePrimitive(PrimitiveType.Cube);
		dude.transform.position = new Vector3 (px, py, .5f);
		dude.transform.localScale= new Vector3 (1, 1, 5);
		dude.transform.renderer.material.color = Color.black;
	}

	void Update () { // below is the AI movement section !!!
		Vector3 v = new Vector3 (gotox, gotoy, dude.transform.position.z);
		dude.transform.position=Vector3.MoveTowards(dude.transform.position,v,Time.deltaTime*5);
		Camera.main.transform.position = new Vector3(dude.transform.position.x,dude.transform.position.y,dude.transform.position.z-5);
		tp = dude.transform.position;
		if (dude.transform.position == v) {
			if(foundwall){direction = direction -1;}
			int check = 4;
			while(check>0){check--;

				if(!iswall[gotox+(int)directions[direction].x][gotoy+(int)directions[direction].y]){

				
					gotox=gotox+(int)directions[direction].x;
					gotoy=gotoy+(int)directions[direction].y;
					check = 0;
				}else{direction++;foundwall=true;}


	}
}
	}