AI to shoot other AI
Greetings community, I've been looking for this a while and I have not found a solution so I desperate ask for help. This is the situation, I have made a spawnable enemy that looks for another and attacks him (melee) wich works just great. But The other AI let's call it "PlayerAI" has to go to some navigation points and if it spots and enemy he has to shoot them. I used the base code of a shooter from unity's tutorial videos. anyway here's the code public class AIShooting : MonoBehaviour {
public int damagePerShot = 20; // The damage inflicted by each bullet.
public float timeBetweenBullets = 0.15f; // The time between each shot.
public float range = 100f; // The distance the gun can fire.
Vector3 Dist;
float distfrom;
GameObject[]enemies;
GameObject enemy=null;
public Transform player;
float timer; // A timer to determine when to fire.
Ray shootRay; // A ray from the gun end forwards.
RaycastHit shootHit; // A raycast hit to get information about what was hit.
int shootableMask; // A layer mask so the raycast only hits things on the shootable layer.
ParticleSystem gunParticles; // Reference to the particle system.
LineRenderer gunLine; // Reference to the line renderer.
Light gunLight; // Reference to the light component.
float effectsDisplayTime = 0.2f;
void Awake ()
{
// Create a layer mask for the Shootable layer.
shootableMask = LayerMask.GetMask ("Shootable");
enemies = GameObject.FindGameObjectsWithTag ("Enemy");
// Set up the references.
gunParticles = GetComponent<ParticleSystem> ();
gunLine = GetComponent <LineRenderer> ();
gunLight = GetComponent<Light> ();
}
void Update ()
{
// Add the time since Update was last called to the timer.
timer += Time.deltaTime;
// when we spot an enemy we should shot him
foreach (var enemy in enemies)
{
Dist=(enemy.transform.position -player.position);
Dist.y=0;
distfrom=Dist.magnitude;
Dist/=distfrom;
if ( distfrom<20 && timer >= timeBetweenBullets)
{
player.LookAt(enemy.transform.position);
Shoot();
}
}
// If the timer has exceeded the proportion of timeBetweenBullets that the effects should be displayed for...
if(timer >= timeBetweenBullets * effectsDisplayTime)
{
// ... disable the effects.
DisableEffects ();
}
}
public void DisableEffects ()
{
// Disable the line renderer and the light.
gunLine.enabled = false;
gunLight.enabled = false;
}
void Shoot ()
{
// Reset the timer.
timer = 0f;
// Play the gun shot audioclip.
// Enable the light.
gunLight.enabled = true;
// Stop the particles from playing if they were, then start the particles.
gunParticles.Stop ();
gunParticles.Play ();
// Enable the line renderer and set it's first position to be the end of the gun.
gunLine.enabled = true;
gunLine.SetPosition (0, transform.position);
// Set the shootRay so that it starts at the end of the gun and points forward from the barrel.
shootRay.origin = transform.position;
shootRay.direction = transform.forward;
// Perform the raycast against gameobjects on the shootable layer and if it hits something...
if(Physics.Raycast (shootRay, out shootHit, range, shootableMask))
{
// Try and find an EnemyHealth script on the gameobject hit.
EnemyHealth enemyHealth = shootHit.collider.GetComponent <EnemyHealth> ();
// If the EnemyHealth component exist...
if(enemyHealth != null)
{
// ... the enemy should take damage.
enemyHealth.TakeDamage (damagePerShot, shootHit.point);
}
// Set the second position of the line renderer to the point the raycast hit.
gunLine.SetPosition (1, shootHit.point);
}
// If the raycast didn't hit anything on the shootable layer...
else
{
// ... set the second position of the line renderer to the fullest extent of the gun's range.
gunLine.SetPosition (1, shootRay.origin + shootRay.direction * range);
}
}
}
Fine. I tried to create a public gameobject of the enemy prefab and drag it to the box of the script, it Works just fine just tweaking the code to shoot only that object, when I try to find the object by tag I get a really simple error which I think is the only issue is a bad instantiation. Because the script is disabled when I run the game and this message pops in the console : NullReferenceException: Object reference not set to an instance of an object AIShooting.Update () (at Assets/Sripts/AIShooting.cs:44)
May be it's a way simple error but I could use some help. what are your thoughts and suggestions?
Answer by Khamul777 · Mar 02, 2016 at 03:35 PM
Manage to solve it, fairly simple but uneficient. Thing is that in the scene there are no enemies with the tag I'm looking for which is enemies so the array never finds information. and so it never shoots anything because it's null. I moved the array GetComponent to the Update Function and it's resized every frame. Really bad code but gets the job done, I'll leave this question open so I could read suggestions on optimizing that small piece of code. Thanks.
Your answer
Follow this Question
Related Questions
Assigning to array give NullReferenceExecption!?!! 0 Answers
Can't access public static array from another class 1 Answer
My Script Won't Let Me Castle C# Chess 0 Answers
Named array assigned to new array, named array returns null on all subsequent calls 0 Answers
Null reference exception in an if statement that checks for it. 1 Answer