Obstacle Avoidance?

So I’m working on a little side project and it’s going really well, it’s a mini survival game, and I’m aiming for 20+ enemies on screen at once (vertices/tris aren’t a problem with the types of enemies I’m using, neither are draw calls). What I’m really wondering is what’s the fastest way (like what’s the best way with the least amount of performance impact to get the enemies to move around objects (barricades and stuff?). Right now I have a script that checks to see if theres something in front of the enemy and if so to randomly choose left or right and keep going until the raycast no longer returns the wall or object. Will raycasting be to slow? is there a better way? Thanks.

Sounds like what you want is pathfinding. AngryAnt is working on making his pathfinding library compatible on the iPhone, you might want to look at that.

Its hard to say if raycasting will be slow in your game, it depends on how you use it.

Always check your game’s framerate to see if your game is running slow, then turn on the built-in profiler to see where the bottleneck is; it might not even be where you expect it to be.

My game uses a lot of raycasting all the time and I get 10-12 fps on an iPod Touch 2nd Generation, though my bottleneck is in the physics collider/rigidbody system, not the raycasting.

Ok cool, I’ll stick with raycasting for now and see how it goes.

Ok so here’s my enemy ai code, with about 30 enemies on screen on my mac, the framerate went down to about 130, at it’s worst it went to about 90, is there something wrong with my code? or am I using raycasting wrong? any help would be great thanks.

var player : Transform;
var action : int;
var rechaseRange : float = 200.0;
var attackRange : float = 150.0;
var health : float = 20;
var speed : float = 5.0;
var raycastLength : float = 10.0;
var LRRaycast : float = 2.0;
var playerPos : Vector3;
var shoot : boolean = true;
var bullet : Transform;
var gun : Transform;
var bulletSpeed : float = 200.0;

function Update () {
playerPos = player.transform.position;
playerPos.y = transform.position.y;
var right = transform.TransformDirection(Vector3.right);
var left = transform.TransformDirection(Vector3.left);
var fwd = transform.TransformDirection(Vector3.forward);
var range = Vector3.Distance(transform.position, player.position);
var point : Vector3 = player.position;
var myPoint : Vector3 = transform.position;

if(range >= rechaseRange){
//if range is greater than chaseRange, action = 1.
action = 1;
}
else if(range <= rechaseRange){
if(range <= attackRange){
//if range is less than chaseRange, and if range is less than attack range, action = 2.
action = 2;
}
}
if(health <= 0){
//if health is less than or equal to 0, action = 3.
action = 3;
}

switch (action) {
case 1:
print("One Find");
if (!Physics.Raycast(transform.position, fwd, raycastLength)  
!Physics.Raycast(transform.position, right, LRRaycast)  
!Physics.Raycast(transform.position, left, LRRaycast)){
transform.LookAt(playerPos);
transform.Translate(Vector3.forward * speed);
}
else if (!Physics.Raycast(transform.position, fwd, raycastLength)) {
transform.Translate(Vector3.forward * speed);
}
else if (!Physics.Raycast(transform.position, right, LRRaycast)) {
transform.Translate(Vector3.zero);
transform.Rotate(0,30,0);
}
else if (!Physics.Raycast(transform.position, left, LRRaycast)) {
transform.Translate(Vector3.zero);
transform.Rotate(0,-30,0);
}
break;

case 2:
print("Two Attack");
transform.LookAt(playerPos);
transform.Translate(Vector3.zero);
if(shoot){
shoot = false;
Fire();
}
break;

case 3:
print("Three Die");
Destroy(this.gameObject);
break;

default:
print("None");
}
}

function Fire(){
var IBullet = Instantiate(bullet, gun.position, transform.rotation);
yield WaitForSeconds(1);
shoot = true;
}

You might want to stagger the raycasts that is rather than doing all 30 every frame only do 10 or so, I doubt they would need to be done every frame anyway.

How would I go about staggering them? or having them called only like every two - three frames?

put your raycast code in a separate function, then in your Start function, do this:

InvokeRepeating("RayCastFunction", 0.0, 0.5);

This will make the RaycastFunction() be called every 0.5 seconds.

I looked at your code, while you need to put the raycasts in a separate function, do keep the Transform.Translate functions in Update. Not doing so will make your character move only every 0.5 seconds too.

Ok thanks.

EDIT: Woah! calling print like every frame reduced my framerate to nearly half of what it was supposed to be. I’m going to add the raycast function thing in now and see how it works.

Not sure if this recent post helps you at all, but I just thought I’d point it out:

http://forum.unity3d.com/threads/40817-Unity-3d-Programming-Video-Tutorials?highlight=obstacle+avoidance