- 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

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