I started off with a basic enemie's AI, but now I have a problem. I want it to be like that:
1. I am in enemie's sight and it starts following me
2. I run behind a wall or object
3. Enemy continues following me by finding the nearest way to me
I can't find any way to make a pawn think of the nearest way. I only know the way to make them move randomly left or right when they have an obstacle on their way until they see me.
Is it possible to do it somehow?
Just in case, I post my script too:
Code: Select all
{
IDLE [idle] // idle animation
WALK [walk] // walk animation
DIE [die] // die animation
SHOOT [shoot] // shoot animation
MISC1 [slump] // misc1 animation
GROUP [enemy]
HOSTILEPLAYER [true] // hostile to player
HOSTILESAME [false] // hostile to same Pawn group
HEALTHATTRIBUTE [enemy_health] // name of pawns health attribute
HEALTH [100] // initial pawn health
DAMAGEATTRIBUTE [health] // attribute damaged by attack
FOV [220] // enemies field of view angle
PROJECTILE [pistol_shell] // enemy shoots that projectile
FIREJOINT [Joint18] // enemy shoots from this bone
BOUNDINGBOXWIDTH [40] // bounding box width
BOUNDINGBOXHEIGHT [90] // bounding box height
SIGHTDIST [600] // while idleing enemy sees you at that distance
SHOOTDIST [300] // in that range enemy shoots
FOLLOWAFTERSIGHTED [1500] // when enemy is following sight distance increases
RUNSPEED [200] // enemy runs towards you with that speed
ROTATESPEED [200] // enemy rotates at you with that speed
Spawn[()
{
Console(true);
BoxWidth(BOUNDINGBOXWIDTH);
BoxHeight(BOUNDINGBOXHEIGHT);
SetFOV(FOV);
AddCollisionOrder("rotate");
AddPainOrder("Alert", 100);
AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Die");
FindTargetOrder(SIGHTDIST, "Alert", "health");
PlayerDistOrder(SHOOTDIST, "rotate");
NewOrder("Start");
}]
Start[()
{
PlayAnimation(IDLE, true, "");
RestartOrder();
}]
Alert[()
{
AnimateStop(SHOOT, 0, "pump.wav");
if(self.player_range < SHOOTDIST) // IT SEES ME AND IM CLOSER THAN 300
{
LowLevel("start_shooting"); // IT STARTS SHOOTING ME...
}
else // IT SEES ME BUT I AM FURTHER THAN 300
{
NewOrder("MoveToPlayer"); // IT STARTS FOLLOWING ME
RestartOrder();
}
}]
LostTarget[()
{
FindTargetOrder(SIGHTDIST, "Alert", "health");
PlayAnimation(IDLE, true, "");
RestartOrder();
}]
PlayerKilled[()
{
PlayAnimation(IDLE, true, "");
RestartOrder();
}]
Die[()
{
SetNoCollision();
AnimateStop(DIE, 3, "die1.wav");
FadeOut(3, 0);
Remove(true);
}]
//MOVEMENT
MoveToPlayer[()
{
LowLevel("start_following");
}]
start_following[()
{
Animate("walk");
self.ThinkTime = 0;
self.ideal_yaw = self.enemy_yaw;
self.yaw_speed = RUNSPEED;
self.think = "follow";
}]
follow[()
{
self.ThinkTime = 0;
if(self.health <= 0)
{
HighLevel("Die");
return 0;
}
if(self.player_range > FOLLOWAFTERSIGHTED)
{
HighLevel("LostTarget");
return 0;
}
if (self.player_range < SHOOTDIST)
{
self.think = "start_shooting";
return 0;
}
if(self.enemy_vis = true)
{
self.ideal_yaw = self.enemy_yaw;
ChangeYaw();
}
else
{
HighLevel("LostTarget");
return 0;
}
if(self.animate_at_end = false)
{
walkmove(self.ideal_yaw, RUNSPEED);
}
}]
//END OF MOVEMENT
//ATTACK
//ENEMY SAW A PLAYER AND SHOOTS IT
start_shooting[()
{
if(EnemyExist("health") < 3)
{
HighLevel("PlayerKilled");
return 0;
}
self.yaw_speed = 150;
UpdateEnemyVis();
UpdateTarget();
if(self.enemy_vis = true)
{
self.ideal_yaw = self.enemy_yaw;
ChangeYaw();
Animate("shoot");
SetHoldAtEnd(true);
self.ThinkTime = 0.05;
self.think = "shooting";
}
else
{
HighLevel("LostTarget");
}
}]
shooting[()
{
if(self.health <= 0)
{
HighLevel("Die");
return 0;
}
self.ThinkTime = 0.4;
switch(random(0,4))
{
case 0
{
FireProjectile(PROJECTILE, FIREJOINT, 0, 30, 0, "health", "0.5");
}
case 1
{
FireProjectile(PROJECTILE, FIREJOINT, -10, 0, 0, "health", "1");
}
case 2
{
FireProjectile(PROJECTILE, FIREJOINT, -5, 0, 0, "health", "0.8");
}
case 3
{
FireProjectile(PROJECTILE, FIREJOINT, 5, 0, 0, "health", "0.1");
}
case 4
{
FireProjectile(PROJECTILE, FIREJOINT, 10, 30, 0, "health", "0.9");
}
}
self.think = "rotation_and_start_shooting";
}]
rotation_and_start_shooting[()
{
HighLevel("rotate");
}]
rotate[()
{
RotateToPlayer(IDLE, ROTATESPEED, false, "");
if(self.player_range > SHOOTDIST)
{
NewOrder("MoveToPlayer");
}
else
{
LowLevel("start_shooting");
}
}]
//END OF ATTACK
}