- Home /
Ai Alien Zombies get stuck on trees?
I have a not too bad AI script set up thanks to a boat load of help from many, many of you one here. :D But what happens is my Alien Zombies sometimes get stuck on trees or they will walk up to a rock and just keep walking against the rock, trees... whatever hapens to be in their way. They avoid most things but get stuck quite a bit. And I'm wondering how I can mod this to fix that.
EDIT I fixed some of their getting stuck on trees by removing the mesh collider and just giving the trees a capsule collider, that way they don't get all stuck on the folliage. But they sometimes still have problems getting around rocks?
I thought there was some way to make them change direction if they were stuck for a certain period of time??
Here is my Alien Zombie AI script in it latest incarnation:
var speed = 3.0; var rotationSpeed = 5.0; var attackRange = 30.0; var dontComeCloserRange = 5.0; var pickNextWaypointDistance = 2.0; var target : Transform; var modelAnimation : Animation; var attackSound : AudioClip; // Attack Player Sounds var tearingFlesh : AudioClip; // Attack Player Sounds var alienZombiePrefab : Transform; // Put the alive Alien Prefab here
private var hitTimmer = 1.0;
//////////////////////////////// Makes Alien Zombies Avoide Obstacles//////////////////// function Update (){
//The direction vector to our target
var dir = (target.position - transform.position).normalized;
var hit : RaycastHit;
// Check for forward raycast
if(Physics.Raycast(transform.position, transform.forward, hit, 20)){
if(hit.transform != transform){
Debug.DrawLine(transform.position, hit.point, Color.red);
dir += hit.normal * 50;
}
}
var leftR = transform.position; var rightR = transform.position;
leftR.x -= 2; rightR.x += 2;
if(Physics.Raycast(leftR, transform.forward, hit, 20)){ if(hit.transform != transform){ Debug.DrawLine(leftR, hit.point, Color.red); dir += hit.normal 50; } } if(Physics.Raycast(rightR, transform.forward, hit, 20)){ if(hit.transform != transform){ Debug.DrawLine(rightR, hit.point, Color.red); dir += hit.normal 50; } }
var rot = Quaternion.LookRotation(dir);
var sizeOfMonster = 2.5; var groundOffset = Vector3(0,2.2,0); var newPosition = transform.position + transform.forward 1 Time.deltaTime; if (!Physics.CheckSphere(newPosition+groundOffset, sizeOfMonster)){ transform.position = newPosition; }
transform.rotation = Quaternion.Slerp(transform.rotation, rot, Time.deltaTime);
}
function OnDrawGizmosSelected () { Gizmos.color = Color.red; var sizeOfMonster = 2.5; var groundOffset = Vector3(0,2.2,0); Gizmos.DrawWireSphere (transform.position+groundOffset, sizeOfMonster); }
///////////////////////////////////////////////////
// Make sure there is always a character controller @script RequireComponent (CharacterController)
function Start () { // Auto setup player as target through tags if (target == null && GameObject.FindWithTag("Player")) target = GameObject.FindWithTag("Player").transform;
Patrol();
}
function Patrol () { var curWayPoint = AutoWayPoint.FindClosest(transform.position); while (true) { var waypointPosition = curWayPoint.transform.position; // Are we close to a waypoint? -> pick the next one! if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance) curWayPoint = PickNextWaypoint (curWayPoint);
// Attack the player and wait until
// - player is killed
// - player is out of sight
if (CanSeeTarget ())
yield StartCoroutine("AttackPlayer");
// Move towards our target
MoveTowards(waypointPosition);
yield;
}
}
function CanSeeTarget () : boolean { if (Vector3.Distance(transform.position, target.position) > attackRange) return false;
var hit : RaycastHit;
Debug.DrawRay(transform.position, transform.forward * 30, Color.red);
if (Physics.Linecast (transform.position, target.position, hit))
return hit.transform == target;
return false;
}
function AttackPlayer () { var lastVisiblePlayerPosition = target.position; while (true) { //if (CanSeeTarget ()) { // Target is dead - stop hunting if (target == null) return;
// Target is too far away - give up
var distance = Vector3.Distance(transform.position, target.position);
if (distance > attackRange * 3)
return;
lastVisiblePlayerPosition = target.position;
if (distance > dontComeCloserRange)
MoveTowards (lastVisiblePlayerPosition);
else
RotateTowards(lastVisiblePlayerPosition);
//Attack player with "Attack" animation which is basically a clawing and biting animation
//this "Attack" is supposed to inflict damage to the FPS player
var forward = transform.TransformDirection(Vector3.forward);
var targetDirection = lastVisiblePlayerPosition - transform.position;
targetDirection.y = 0;
var angle = Vector3.Angle(targetDirection, forward);
if (distance < 3){
var damage = 10;
target.SendMessage("ApplyDamage", damage);
// you probably have some other script managing there
// animations but you'd typically at this point call
modelAnimation.Play("Attack");
// and you could have the attack animation on a higher
// layer than other animations to override them.
audio.PlayOneShot (attackSound);
yield WaitForSeconds(2.3);
// Play Attack Sounds when clwaing but don't play so often
if (Time.time > hitTimmer && attackSound && tearingFlesh){
audio.PlayOneShot(attackSound, 1.0 / audio.volume);
hitTimmer = Time.time + Random.Range(attackSound.length * 2, attackSound.length * 3);
}
else
{
// Play a tearing flesh sound
audio.PlayOneShot(tearingFlesh, 1.0 / audio.volume);
hitTimmer = Time.time + Random.Range(tearingFlesh.length * 2, tearingFlesh.length * 3);
}
}
yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
//Player not visible anymore - stop attacking
if (!CanSeeTarget())
return;
}
yield;
}
//}
function SearchPlayer (position : Vector3) { // Run towards the player but after 3 seconds timeout and go back to Patroling var timeout = 3.0;
while (timeout > 0.0)
{
MoveTowards(position);
// We found the player
if (CanSeeTarget ())
return;
timeout -= Time.deltaTime;
yield;
}
}
function RotateTowards (position : Vector3) { SendMessage("SetSpeed", 0.0);
var direction = position - transform.position;
direction.y = 0;
if (direction.magnitude < 0.1)
return;
// Rotate towards the target
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}
function MoveTowards (position : Vector3) { var direction = position - transform.position; direction.y = 0; if (direction.magnitude < 0.5) { SendMessage("SetSpeed", 0.0); return;
}
// Rotate towards the target
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
// Modify speed so we slow down when we are not facing the target
var forward = transform.TransformDirection(Vector3.forward);
var speedModifier = Vector3.Dot(forward, direction.normalized);
speedModifier = Mathf.Clamp01(speedModifier);
// Move the character
direction = forward * speed * speedModifier;
GetComponent (CharacterController).SimpleMove(direction);
SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}
function PickNextWaypoint (currentWaypoint : AutoWayPoint) { // We want to find the waypoint where the character has to turn the least // The direction in which we are walking var forward = transform.TransformDirection(Vector3.forward);
// The closer two vectors, the larger the dot product will be.
var best = currentWaypoint;
var bestDot = -10.0;
for (var cur : AutoWayPoint in currentWaypoint.connected) {
var direction = Vector3.Normalize(cur.transform.position - transform.position);
var dot = Vector3.Dot(direction, forward);
if (dot > bestDot && cur != currentWaypoint) {
bestDot = dot;
best = cur;
}
}
return best;
}
Your answer
Follow this Question
Related Questions
FPS Problem Help! 0 Answers
Hurting enemy when attacking status is equal to true and player is colliding with enemy object. 1 Answer
Object Avoidance for my enemies 1 Answer
Deal damage on collision 2 Answers
Why is this script causing a lot of lag? 2 Answers