- Home /
Turret Firing problem [C#]
Hi everybody ! I'm trying to make a turret that fire at enemies when there are in his collider. But the problem is that : InvokeRepeating don't work ... my turret fire only when a new mob enter in his collider ... I tried ifferents methods. The last was a state machine it didn't work too...
this is my script :
using UnityEngine;
using System.Collections;
public class Tower : MonoBehaviour {
private GameObject mob;
public GameObject bullet;
public GameObject gun;
public int power = 100;
private int State;
private bool isFiring;
void Start()
{
State = 0;
UpdateStateMachine();
isFiring = false;
}
void Update()
{
if(mob != null)
{
transform.LookAt(mob.transform.position);
}
}
void OnTriggerEnter (Collider col)
{
if(col.tag == "MobCol")
{
mob = col.gameObject.transform.parent.gameObject;
State = 1;
UpdateStateMachine();
}
}
void OnTriggerExit(Collider col)
{
State = 0;
UpdateStateMachine();
}
public void Fire()
{
GameObject towerBullet = (GameObject)Instantiate(bullet, gun.transform.position, Quaternion.identity);
towerBullet.GetComponent<Rigidbody>().AddForce(transform.forward * power);
}
public void UpdateStateMachine()
{
switch (State)
{
case 0:
CancelInvoke("Fire");
break;
case 1:
InvokeRepeating("Fire", 0f, 0.5f);
break;
}
}
}
Thank you ! Bye, xyHeat
so it only shoots once at the new mob, or only fires at that single mob repeatedly?
The turret fire when a mob enter in his collider, then it look at the mob and fire on him only if an other mob enter in his collider and if the first leave the fire range, the tower look at the other mob
Answer by TreyH · Mar 25, 2016 at 04:51 PM
Try this and see what happens:
using UnityEngine;
using System.Collections;
public class Tower : MonoBehaviour {
private GameObject mob;
public GameObject bullet;
public GameObject gun;
public int power = 100;
private bool isFiring;
private IEnumerator fireRoutine;
void Update()
{
if(mob != null)
{
transform.LookAt(mob.transform.position);
}
}
void OnTriggerEnter (Collider col)
{
if(col.tag == "MobCol")
{
mob = col.gameObject;
fireRoutine = FireRoutine();
StartCoroutine(fireRoutine);
}
}
void OnTriggerExit(Collider col)
{
// Make sure our initial mob should be removed
if(col.gameObject == mob)
{
if (fireRoutine != null)
{
StopCoroutine(fireRoutine);
}
mob = null;
}
}
public IEnumerator FireRoutine()
{
// Use a Coroutine for this
WaitForSeconds wait = new WaitForSeconds(0.2f);
// Keep ourselves from firing at nothing
while (mob != null)
{
Fire();
// Return our yield instance
yield return wait;
}
}
public void Fire()
{
GameObject towerBullet = (GameObject)Instantiate(bullet, gun.transform.position, Quaternion.identity);
towerBullet.GetComponent<Rigidbody>().AddForce(transform.forward * power);
}
}
Thank you, it work, i don't know why but i never use coroutine... Thank you again ! Bye, xyHeat
glad to help, keep in $$anonymous$$d that this will stop firing if two enemies enter and the active enemy leaves. You may want to adjust your script to fire at a List of enemies, or something similar.
Answer by Carlz · Mar 25, 2016 at 05:54 PM
Add a reference of every enemy that has entered the collider to a List and let the turret look only at the first Object in the List. Then start a coroutine that fires a projectile every x seconds to the position of this first item in the List. When this Item is destroyed you will have to update the list and a new enemy will be on position 1. I didn't test this but that is the way I would do it.