# How to have enemies traverse level in 2D platformer

How would you program enemies to move in a 2D platformer? I’m trying to find ways to keep them from getting stuck on walls when chasing a player, falling into bottomless pits or moving towards the wrong platform when chasing the player. Below I have a code that works with having the enemy jump across platforms and while it’s not finished, I already know that the enemy wouldn’t be able to find it’s way around a more labyrinthine layout. I want to know if there’s a better way to make an enemy find it’s way through a level without getting itself stuck or killed and if there’s a better way to have the enemy know when it needs to jump.

``````var LeftBoundary : Transform;
var RightBoundary : Transform;
var raylength : float = 1;
var xmindistance:float;
var xmaxdistance:float;
var ymindistance:float;
var ymaxdistance:float;
var maxDistance:float=5;
var distance:float;
var speed:float;
var jump:float;
var JumpCounter:float=1;
var dir:int;
var jumped:boolean=false;

function OnCollisionEnter (other : Collision )
{

if(other.transform.tag=="Ground"  other.transform.position.y<transform.position.y)
{
JumpCounter=1;
}

}
function OnCollisionStay(other:Collision)
{
if(other.transform.tag=="Ground")
{
jumped=false;
}
}
function Update()
{
//rigidbody.velocity.x=speed;
var player = GameObject.FindGameObjectWithTag("Player");
var playerdistance = Vector3.Distance( player.transform.position, transform.position);
var hit : RaycastHit;
var raydir = transform.TransformDirection(Vector3(0,-1,0));
if(Physics.Raycast(LeftBoundary.position,raydir,hit,raylength) hit.transform.tag=="Ground" )
{
if ( playerdistance < maxDistance  )
{
var delta = player.transform.position - transform.position;
delta.Normalize();

var moveSpeed = speed * Time.deltaTime;
transform.position.x = transform.position.x + (delta.x * moveSpeed);
}
}
if(Physics.Raycast(RightBoundary.position,raydir,hit,raylength) hit.transform.tag=="Ground")
{
if ( playerdistance < maxDistance  )
{

transform.position.x = transform.position.x + (delta.x * moveSpeed);
}
}
if(Physics.Raycast(transform.position,transform.TransformDirection(Vector3(1,0,0)),hit,raylength) hit.transform.tag=="Ground")
{
dir=1;
}

if(Physics.Raycast(transform.position,transform.TransformDirection(Vector3(-1,0,0)),hit,raylength) hit.transform.tag=="Ground")
{
dir=-1;
}

if(!Physics.Raycast(RightBoundary.position,raydir,hit,raylength) player.transform.position.x>transform.position.x)
{
dir=1;
}

if(!Physics.Raycast(LeftBoundary.position,raydir,hit,raylength) player.transform.position.x<transform.position.x)
{
dir=-1;
}
Debug.DrawRay (LeftBoundary.position, (Vector3(0,-1,0))*raylength);
Debug.DrawRay (RightBoundary.position, (Vector3(0,-1,0))*raylength);
var taggedGameObjects = GameObject.FindGameObjectsWithTag("waypoint");
//var nearestObj : Transform = null;
// loop through each tagged object, remembering nearest one found
for (var obj : GameObject in taggedGameObjects)
{
var objectPos = obj.transform.position.x;
var distanceSqr = (objectPos - transform.position.x);
var heightdistance=(obj.transform.position.y-transform.position.y);
if(dir==1)
{
if (distanceSqr < xmaxdistance  distanceSqr>xmindistance  heightdistance<ymaxdistance)

{
if(JumpCounter>0){
rightplatform = obj.transform;}
//nearestDistanceSqr = distanceSqr;

var platformdistance=Vector2.Distance(transform.position,rightplatform.position);

if(platformdistance<distance)
{
if(JumpCounter>0)
{
rigidbody.velocity.y=jump;
JumpCounter-=1;
}
if(JumpCounter==0)
{
jumped=true;
}
if(jumped==true)
{
//rigidbody.velocity.x += distanceSqr;
//transform.position.x=Mathf.MoveTowards(transform.position.x, rightplatform.position.x, speed * Time.deltaTime);
var direction=( rightplatform.position - transform.position);
direction.Normalize();
transform.position.x=transform.position.x+(direction.x * speed * Time.deltaTime);
}
}
}
}
if(dir==-1)
{
if (distanceSqr > -xmaxdistance  distanceSqr<-xmindistance  heightdistance<ymaxdistance)

{
if(JumpCounter>0){
leftplatform = obj.transform;}
//nearestDistanceSqr = distanceSqr;

var leftdistance=Vector2.Distance(transform.position,leftplatform.position);

if(leftdistance<distance)
{
if(JumpCounter>0)
{
rigidbody.velocity.y=jump;
JumpCounter-=1;
}
if(JumpCounter==0)
{
jumped=true;
}
if(jumped==true)
{
//rigidbody.velocity.x += distanceSqr;
//transform.position.x=Mathf.MoveTowards(transform.position.x, rightplatform.position.x, speed * Time.deltaTime);
var leftdirection=( leftplatform.position - transform.position);
leftdirection.Normalize();
transform.position.x=transform.position.x+(leftdirection.x * speed * Time.deltaTime);
}
}
}
}
}
}
``````

bump

This may be more involved than what you’re looking for, but it sounds like you need a pathfinding system, e.g. one based on A*. Depending on how your levels are laid out, the graph representation of your level might consist of nodes, say, at the ends of platforms or other places that a character can jump, and graph edges would contain information about the type of movement involved (e.g. walking, jumping, climbing, etc.).

It wouldn’t be trivial to implement, but it would likely give your NPCs the degree of (apparent) intelligence that you’re after.