chasing enemy

Hi:

I am trying to make an enemy chasing scene, and wondering if there is a simple way to turn the enemy AWAY from my camera all the time. It might be considered the opposite of the LookAt(target) function. I want the enemy move only when the camera is within a certain distance, so it should not be childed to the enemy.

Thanx in advance.

The simplest solution would probably be to use the LookAt() function, but to ‘look at’ a point in the direction opposite the player. Pseudocode:

Vector3 diff = enemy.position - camera.position;
Vector3 target = enemy.position + diff;
enemy.transform.LookAt(target);

This should work, but the enemy may ‘snap’ instantly to a new orientation when the camera comes near, which is somewhat unnatural. To work around that, you could have the enemy rotate smoothly towards the ‘goal direction’ instead.

That said, I’d recommend at least taking a look at steering behaviors, which will most likely give you better results than the ad hoc methods described above.

Thanx for the reply. Like you said when the enemy is close to the camera, it backs up to collide with the camera. So, I’m in need of a better solution. Your steering behavior link is full of great things to consider. Thanx again.

I’m glad the steering behaviors link looks like it might be helpful. However:

I’m not 100% sure what you mean by this, but the ‘LookAt’ method I suggested shouldn’t result in such behavior.

If you’d still like to get the LookAt method to work, but are having problems with it, perhaps you could post your code.

OK, here is the code. Setup wise, I have an enemy (fbx imported with character animation) the code is atached to it. Player is the default First Person Controller prefab game objects are correctly assigned in the inspector. enemySpeed = 4, playerSpeed = 6, thresholdDistance = 20.

var enemy: GameObject; 
var player: GameObject; 
var thresholdDistance: float; 
var enemyMoveSpeed: float; 
var charController : CharacterController ; 

function Start()
{
    charController = GetComponent (CharacterController);
    animation.wrapMode = WrapMode.Loop;
}

function Update () 
{      
var enemyOffset = enemy.transform.position -  player.transform.position; 
enemyOffset.y = 0;
var distance = enemyOffset.magnitude; 

if (distance < thresholdDistance ) 
{ 
var enemyMoveDir = enemyOffset/distance; 
animation.CrossFade("run");
var target : Vector3 =  enemy.transform.position + enemyOffset;
enemy.transform.LookAt( target);
enemy.transform.Translate(enemyMoveDir * enemyMoveSpeed * Time.deltaTime); 
}   
else
{
animation.CrossFade("idle");
}
}

If the player passes the enemy, the enemy backs up to collide with the player.

Hm, that’s odd - at first look at least, the code looks correct to me.

Are you sure that the value of enemyMoveSpeed is positive?

Yep, enemySpeed = +4.
I figure out the reason for the seemingly odd behavior: when either x or z component of the enemyOffset is negative, the code dictates the enemy move toward the player.
So, I need to look into the Evade algorithm from the link you provided.

The problem is that you’re applying the (world-space) translation vector in local space. Replace this:

enemy.transform.Translate(
    enemyMoveDir * enemyMoveSpeed * Time.deltaTime);

With this:

enemy.transform.Translate(
    enemyMoveDir * enemyMoveSpeed * Time.deltaTime, Space.World);

And it should work correctly.

It worked! Thank you very much Jesse. I learned a lot from you.