Need help with weapon firing particles

What I need to do is simple: when firing my gun, it emits a prefab particle once, repeating it every fire. Although it looks quite simple, it sounds nearly impossible to not do this without triggering an error. Below is what I already tried to do:

  • The particle autodestructs when its over, then is recreated on the
    next fire. I tried using Instantiate, Resources.Load, GetComponent and alike
    but I cant get a clue on what is wrong.
  • Create a second script for the particle, which receives data from
    the gun script saying when to emit
    and when to stop. Problem is I cant
    figure out how to get data from a
    different object’s script.
  • Get the exact time I should order my particle to stop emitting (also by scripting it). By far the most viable solution in my opinion, but certainly impractical.

A C# script would be appreciated.

Here’s what I’m using - the only part missing is “Get the exact time I should order my particle to stop emitting” so I’ll just add some additional information after the script.

This is only one of many possible permutations of this functionality:

//These are my class variables relating to firing a weapon
private float lastFire = -50;
public float fireCooldown = 0.1f;
public Rigidbody Laser;
public float BaseLaserSpeed = 200f;
    private GameObject gun1;
    private GameObject gun2;

//In the Start routine (which is called when the player object is created.)
gun1 = GameObject.Find("Gun1");
gun2 = GameObject.Find("Gun2");

//On each Update, I call a method with the following code:
	this.lastFire -= Time.deltaTime;		
	if(Input.GetMouseButton(0)){
		if(this.lastFire <= 0){
			this.lastFire = this.fireCooldown;
			Rigidbody laser = (Rigidbody) Instantiate(this.Laser, gun1.transform.position, gun1.transform.rotation);
			laser.velocity = laser.transform.forward * this.BaseLaserSpeed;
			
			laser = (Rigidbody) Instantiate(this.Laser, gun2.transform.position, gun1.transform.rotation);
			laser.velocity = laser.transform.forward * this.BaseLaserSpeed;
		}
	}

As for sending data to the object (like “when to emit” and “when to stop” - you can do that by making some public properties in the class definition for the other object.

After the Instantiate of your prefab:

Rigidbody laser = (Rigidbody) Instantiate(this.Laser, gun1.transform.position, gun1.transform.rotation);
  laser.velocity = laser.transform.forward * this.BaseLaserSpeed;

You can get the script object attached. (Let’s say it’s called “LaserBehavior” in the editor) - and let’s say you need to set StartTime

laser.GetComponent(LaserBehavior).StartTime = Time.realtimeSinceStartup;

In order to support this, the other script needs something like this:

public realtime StartTime { get; set; }

After having a look at the codes I made back on my XNA lessons and the other answer here, I finally solved this puzzle.

On the gun script, add a public static variable which will be used on other scripts. It will receive the countdown from the private variable, which is the one being worked:

public static float cooldown{get;set;}
float cooldownCounter;
bool isFiring

void Update()
{
  if(isFiring)
  {
    cooldownCounter++;
    if(cooldownCounter < maxTime) isFiring=false;
  }
  else if(Input.GetButton("Fire")
  {
    <code related to firing gun>
    isFiring=true;
  }
  cooldown = cooldownCounter;
}

Make sure the particle prefab has Emit turned off on the emitter. On the particle script, use the following code on Update to emit the particle when the counter starts and then turn it off after a certain time:

if(ShotgunFire.cooldown>0) particleEmitter.emit=true;
if(ShotgunFire.cooldown>10) particleEmitter.emit=false;

Not sure if this is how a “get set” protection is done, but at least it works.