- Home /
Trying to make the enemy fire
Im trying to get my enemy to fire fireballs.
I used ontriggerenter and a trigger box collider and it works but i need it to continue firing while the play is in the trigger. But when I sued ontriggerstay it goes nuts and fireballs are created every second.
FireblastManager code;
public PlayerHealth playerHealth;
public GameObject FireBlast;
public float spawnTime;
public Transform[] spawnPoints;
void Start ()
{
InvokeRepeating ("Spawn", spawnTime, spawnTime); //repeat every specificed time, spawn point, amount of time to wait before doing it, time to wait before repeating it
}
// Update is called once per frame
void Spawn ()
/*{
if (playerHealth.currentHealth <= 0f) {
Destroy (gameObject); //Addition
return;
}*/
{
int spawnPointIndex = Random.Range (0, spawnPoints.Length); //choose random spawn point
Instantiate (FireBlast, spawnPoints [spawnPointIndex].position, spawnPoints [spawnPointIndex].rotation); //taking the random spawnpoint from previous line and using it
}
void OnTriggerStay (Collider col)
{
if (col.gameObject.tag == "Player")
{
Spawn();
}
}
}
also when the fireball hits the player i get
NullReferenceException: Object reference not set to an instance of an object
Any suggestions?
Answer by TanselAltinel · May 25, 2018 at 10:58 PM
It is an expected behavior. From: https://docs.unity3d.com/ScriptReference/Collider.OnTriggerStay.html
OnTriggerStay is called almost all the frames for every Collider other that is touching the trigger. The function is on the physics timer so it won't necessarily run every frame.
So, what you can do is let enemy to spawn fireball at a time interval. Something like this could work:
public PlayerHealth playerHealth;
public GameObject FireBlast;
public float spawnTime;
public Transform[] spawnPoints;
private float spawnTime;
void Start ()
{
InvokeRepeating ("Spawn", spawnTime, spawnTime); //repeat every specificed time, spawn point, amount of time to wait before doing it, time to wait before repeating it
}
// Update is called once per frame
void Spawn ()
/*{
if (playerHealth.currentHealth <= 0f) {
Destroy (gameObject); //Addition
return;
}*/
{
if(Time.time - spawnTime > 3 /* this is for 3 seconds, you can change it for whatever you want*/) {
int spawnPointIndex = Random.Range (0, spawnPoints.Length); //choose random spawn point
Instantiate (FireBlast, spawnPoints [spawnPointIndex].position, spawnPoints [spawnPointIndex].rotation); //taking the random spawnpoint from previous line and using it
spawnTime = Time.time;
}
}
void OnTriggerStay (Collider col)
{
if (col.gameObject.tag == "Player")
{
Spawn();
}
}
Note that, this is for 3 seconds, meaning enemy can fire a fireball once in 3 seconds as long as OnTriggerStay is triggered.
Thanks for that, it's working now but unfortunately the player health is no longer being deducted when the first blast hit the player.
public PlayerHealth playerHealth;
private int currentHealth;
public int attackDamage;
float timer;
void OnTriggerEnter (Collider col)
{
if (col.gameObject.tag == "Player") {
Attack ();
Destroy (gameObject, 0.3f);
}
{
Debug.Log ("Player hit");
}
}
void Attack ()
{
if (playerHealth.currentHealth > 0) {
playerHealth.TakeDamage (attackDamage);
}
}
}
Its working right up to the Debug.Log ("Player hit"); and other damage scripts are working as they should
any suggestions as to why it's not calling up void Attack()?
try to remove the:
{
Debug.Log ("Player hit");
}
and put the
Debug.Log ("Player hit");
above the
Destroy (gameObject, 0.3f);
without the curly brackets
I did that and no change
I put a debug.log in Attack() and it works like this
void Attack () { Debug.Log ("confirmed"); if (playerHealth.currentHealth > 0) { playerHealth.TakeDamage (attackDamage); } }
but when i put it after if (playerHealth.currentHealth > 0) it doesn't register on the console.
That's a different problem though.
Like @henribo said, please put your debug log over the Destroy method to see if it actually registers.
$$anonymous$$ake sure either player or your fire projectile has Rigidbody component.
$$anonymous$$ake sure TakeDamage method is being called by placing another debug log in it.
Lastly, make sure your Player character is actually tagged as Player, and your attackDamage is actually set.
Your answer
Follow this Question
Related Questions
Check that an object is within the bounds of a trigger, but not touching them? 3 Answers
add waypoint to transform[] 2 Answers
Attacking more than one enemy with same tag, but unity only allows one enemy at a time? 2 Answers
How to make multiple gameobjects instantiate from one collider? 3 Answers
How to run what's inside OnTriggerEnter temporarily while the two objects are in contact? 1 Answer