- Home /
InvokeRepeating repeating too often with OnTriggerEnter
hey all,
Two unit objects (shooting butterflies in this case) both have sphere colliders with isTrigger checked. Let's call them BF A and BF B.
When BF B collides with the sphere trigger for BF A, BF A runs some code to instantiate a homing missile aimed at BF B and send it towards it.
I am using Invoke Repeating to allow BF A to repeatedly instantiate projectiles at BF B until B is destroyed or exits the trigger sphere.
I am using the time and repeatRate variables in InvokeRepeating to try to control the fire rate. Instead, the unit firing fires off many, many projectiles in rapid succession. I am assuming that InvokeRepeating is getting restarted due to the trigger collision but am not sure quite how that's happening. I am managing the collisions with layers so I don't think there is unwanted collision happening but that might be an issue. Finally, here is the code for the shooter:
public var projectile:Transform;
public var projectileSpeed:float = 0.0;
public var delay:float = 0.0;
public var fireRate:float = 1.0;
public var myLayer: int;
public var myColorTag: String;
public var alreadyFiring: boolean;
//private var projectileCount:int = 0;
// Current player variable
private var target:GameObject = null;
function OnTriggerEnter(other:Collider)
{
if(other.gameObject.tag != myColorTag && other.gameObject.tag != "environment" && other.gameObject.tag != "explosion" && other.gameObject.tag != "Resource" && other.gameObject.tag != "projectile")
{
if (alreadyFiring == true)
{ CancelInvoke("Shoot"); alreadyFiring = false; }
if (alreadyFiring == false) {
InvokeRepeating("Shoot", delay, fireRate);
}
// Store current player
// NB this assume that you have only one player because it will overwrite second player
target = other.gameObject;
InvokeRepeating("Shoot", delay, fireRate);
}
}
function OnTriggerExit(other:Collider)
{
if(other.gameObject.tag != myColorTag && other.gameObject.tag != "environment" && other.gameObject.tag != "explosion" && other.gameObject.tag != "Resource" && other.gameObject.tag != "projectile")
// print ("tested true for tag to shoot. mycolortag: " + myColorTag);
{
// Remove reference
target = null;
CancelInvoke("Shoot");
}
}
function Shoot()
{
alreadyFiring = true;
var shootClone = Instantiate(projectile, transform.position, transform.rotation);
// Set projectile velocity
shootClone.gameObject.layer = myLayer;
var setLayerScript = shootClone.GetComponent(spawnDamageExplosion);
if(setLayerScript) setLayerScript.myLayerForExplosion = myLayer;
// print ("spawned missile and initialized explosion layer to" + myLayer);
shootClone.rigidbody.velocity = (target.transform.position - transform.position).normalized * projectileSpeed;
}
Answer by Sparrowfc · Nov 19, 2013 at 06:42 AM
The problem is InvokeRepeating isn't getting restarted due to the trigger collision. Instead, it 'instance a new function call' once u call it. Line 31 in your script cause u invoke a new 'function instance' each time on trigger enter. That's why your script firing so many missles.
Usually I used StartCoroutine instead of InvokeRepeating to avoid the situation that I forgot to cancel the invoke or invoke a method multiple times. such as
IEnumerator StarFireMissle(float timeInterval)
{
while(firing)
{
FireTarget();
yield return new WaitForSeconds(timeInterval);
}
}
Thank you! I had an intuition that I might be creating many copies of the function. I've used startcoroutine before and will rewrite with that. Appreciate your taking the time!
Your answer
![](https://koobas.hobune.stream/wayback/20220613122158im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
C# Instant OnTriggerEnter Detection 0 Answers
A node in a childnode? 1 Answer
Player lives script help 1 Answer
Access to the script variable from a script. Javascript 0 Answers