- Home /
Zombies keep stopping in mid chase
I am trying the totally original idea of making a zombie game. I have a script to control the zombies, but they will constantly stop while they are attacking you. They pause for about a second, and then resume chasing you. It's probably something obvious, but this is my first project, so go easy. Here's my code:
var walkSpeed = 3.0;
var rotateSpeed = 30.0;
var attackSpeed = 8.0;
var attackRotateSpeed = 80.0;
var damage = 10.0;
var viewAngle = 20.0;
var attackRadius = 2.5;
var attackTurnTime = 1.0;
var attackPosition = new Vector3 (0, 1, 0);
var directionTravelTime = 2.0;
var idleTime = 1.5;
var attackDistance = 15.0;
private var isAttacking = false;
private var lastAttackTime = 0.0;
private var nextPauseTime = 0.0;
private var distanceToPlayer;
private var timeToNewDirection = 0.0;
var target : Transform;
private var characterController : CharacterController;
characterController = GetComponent(CharacterController);
function Start ()
{
if(!target)
target = GameObject.FindWithTag("Player").transform;
yield WaitForSeconds(idleTime);
while (true)
{
yield Idle();
yield Attack();
}
}
function Idle()
{
while (true)
{ if (Time.time > timeToNewDirection)
{
yield WaitForSeconds(idleTime);
var RandomDirection = Random.value;
if(Random.value > 5)
transform.Rotate(Vector3(0,20,0), rotateSpeed);
else
transform.Rotate(Vector3(0,-20,0), rotateSpeed);
timeToNewDirection = Time.time + directionTravelTime;
}
var walkForward = transform.TransformDirection(Vector3.forward);
characterController.SimpleMove(walkForward * walkSpeed);
distanceToPlayer = transform.position - target.position;
if (distanceToPlayer.magnitude < attackDistance)
return;
yield;
}
}
function Attack()
{
isattacking = true;
var angle = 0.0;
var time = 0.0;
while (angle > viewAngle || time < attackTurnTime)
{
time += Time.deltaTime;
angle = Mathf.Abs(FacePlayer(target.position, attackRotateSpeed));
move = Mathf.Clamp01((90 - angle) / 90);
direction = transform.TransformDirection(Vector3.forward * attackSpeed * move);
characterController.SimpleMove(direction);
yield;
}
var lostSight = false;
while(!lostSight)
{
angle = FacePlayer(target.position, attackRotateSpeed);
if(Mathf.Abs(angle)> viewAngle)
lostSight = true;
if (lostSight)
break;
var location = transform.TransformPoint(attackPosition) - target.position;
if(Time.time > lastAttackTime + 1.0 && location.magnitude < attackRadius)
{
target.SendMessage("ApplyDamage", damage);
lastAttackTime = Time.time;
}
if(location.magnitude > attackRadius)
break;
if (characterController.velocity.magnitude < attackSpeed * 0.3)
break;
yield ;
}
isAttacking = false;
}
function FacePlayer(targetLocation : Vector3, rotateSpeed : float) : float
{
var relativeLocation = transform.InverseTransformPoint(targetLocation);
var angle = Mathf.Atan2 (relativeLocation.x,
relativeLocation.z) * Mathf.Rad2Deg;
var maxRotation = rotateSpeed * Time.deltaTime;
var clampedAngle = Mathf.Clamp(angle, -maxRotation, maxRotation);
transform.Rotate(0, clampedAngle, 0);
return angle;
}
Answer by creighcl · Aug 05, 2013 at 05:46 PM
At a glance, I notice that you're calling Idle and Attack over and over in your start function. Your idle time is 1.5 seconds, so you would Idle for 1.5 seconds then run through the attack routine for the attack turn time which is set to 1.0. So he stops for 1.5, chases for 1, right?
Not sure what you want it to do, but I would suggest instead of looping in the Start method to alternate back and forth between these, maybe you constantly check to see if the player is in attack range and in the update function say if (inRange){ attack(); } else { idle(); }
Really depends on how your game is meant to work :-)