Interesting Enemy AI issue
So, I'm making a 3rd person shooter. I have this script for the Enemy AI which is attached to all enemy characters. The problem is they either all shoot at me fast at once, and kill me instantly. Or, they just follow me around and don't shoot at all. It works pretty crappy. Can any of you savvy chaps fix it?
This is it:
var projectile : Rigidbody;
var speed = 70;
var player : Transform;
var MoveSpeed = 1;
var MaxDist = 20;
var MinDist = 3;
private var timestamp = 0.0;
function Start() {
var rendum = Random.Range(1F,3F);
}
function Update ()
{
transform.LookAt(player);
if(Vector3.Distance(transform.position,player.position) >= MinDist){
transform.position += transform.forward*MoveSpeed*Time.deltaTime;
if(Vector3.Distance(transform.position,player.position) <= MaxDist && (Time.time > timestamp))
{clone = Instantiate(projectile, transform.position + new Vector3(0.0f, 1.5f, 0.0f), transform.rotation);
clone.velocity = transform.TransformDirection( Vector3 (0, 0, speed));
Destroy (clone.gameObject, 0.5);
timestamp = Time.time + timestamp;
}
}
}
Answer by LucasMars · Mar 10, 2016 at 06:08 PM
The way to get them to not fire all at once is to have a global counter that checks how many bullets have been fired. One way to do this is to have all bullets as a child of another blank gameObject, and then count all children.
Another way to get them to not all fire at once is making them have to aim shots. Give them a Random.Range value to wait, and it'll have to be in that position for a time until it can shoot. That will also probably sort out the overfiring problem. Pseudocode:
//declared at start:
var timer : float;
var amountOfBullets : int = 0;
//inside of firing function:
if(timer > Random.Range(3,5)&&amountOfBullets<5){
Fire();
timer = 0.0f;
}
timer += 1 * Time.deltaTime;
amountOfBullets_reset();
To get it to fire when it is bugging out is also going to need to be fixed. Rather than checking the distance of the object, use a RayCast to see whether the player is in the sight of the enemy. If it is, it can fire. If it isn't, then the player isn't in the sight of the enemy. Pseudocode:
var fwd = transform.TransformDirection (Vector3.forward); //raycast
var distance : float = 10.0f; //distance
if (Physics.Raycast (transform.position, fwd, distance)) { //raycast forward and see...
if(hit.transform.gameObject.name == "player"){ //whether it is a player...
Fire(); //if this runs, then the player is in the sight of the enemy!
}
}
Hope this helps :)
@Lucas$$anonymous$$ars You sir are my personal hero! :) Thank you so much!
I have replaced my original code with this. The only problem is that I'm getting these two errors. Not sure what's the best way to get around them.
var timer : float; var amountOfBullets : int = 0;
Assets/Scripts/EnemyAI.js(29,2): BCE0005: $$anonymous$$ identifier: 'amountofBullets_reset'.
You haven't declared any function for amountofBullets_reset(). I put that in as a function, though forgot to explain what the function did.
It would re-find all of the bullet gameObjects. Pseudocode:
var bullets_Array : gameObject[];
function amountofBullets_reset(){
bullets_Array = GameObject.FindGameObjectsWithTag("bullet");
amountOfBullets = bullets_Array.Length;
}
Something like that to test for the amount of bullets currently created.
@Lucas$$anonymous$$ars Did you mean var bullets_Array : GameObject[];
because if that's the case, I'm getting the same errors. If you actually meant var bullets_Array : gameObject[];
then I'm getting the error: BCE0018: The name 'gameObject' does not denote a valid type ('not found'). Did you mean 'UnityEditor.GameObjectUtility'?
Answer by weedmastersr · Mar 10, 2016 at 12:50 PM
So sorry to bother you again @LucasMars but nobody else seems to be able to offer any useful advice. How could I improve this script because it works pretty crappy right now?
Your answer
Follow this Question
Related Questions
Enemy AI for Shooting Game 1 Answer
Raycast Enemy AI shooting script 1 Answer
AI Problem. 0 Answers
How To Stop Enemy Movement During Its Attack Animation 1 Answer