I’ve happily gotten my game development hobby rolling again and now I’m exploring the ins and outs of the particle system.
I’m struggling with using a particle system as a gun. I want to emit 1 particle every time I click the mouse, but none of my attempts to do so have given me a satisfactory result. If I set the particle system to “One shot” it refuses to fire another particle until the last one has disappeared and if I don’t use “One shot” I may end up with 2 or more particles each time depending on my emission settings.
Basically the particle system seems to run its own timer, based on particle energy and emission speed I presume, which ruins my attempts at taking direct over it.
What I do is create an empty gameobject with a one-shot particle system with autodestruct enabled, make it a prefab, and then instantiate the prefab every time the player fires.
Probably I don’t notice a perceivable performance hit between instantiating and using emit, though, and I’m not targeting mobiles; YMMV.
In my case the muzzle flashes only last about 0.15 seconds, and the next is never instantiated before the previous is destroyed, I don’t think. Would that really result in multiple concurrent draw calls?
Anyway, when you say emit 1 particle, do you mean emit one burst of particles based on your emission settings, or literally one single particle?
I’ve been using instantiating with gameobjects and rigidbodies with great success before even when instantiating hundreds per second, but I just remembered that someone once told me to use a particle system instead, but now I’m starting to think that’s not even possible.
If I have a space battle sort of game and there’s 50 ships all firing lasers around then drawcalls will quickly get into the thousands if each shot counts. That’s why I decided to look at particles.
1 click of the mouse should fire as many particles as I want basically. Initially I want it to fire exactly 1 per click, but I can’t even get that to work.
My problem is that if I’m not controlling when the particle spawns how can I then trigger sounds etc. at the correct moment? Also, for the player it is extremely annoying to not have your ship fire when you click the mouse, but slightly after.
Well I’m not exactly sure, but I’m pretty sure that maxEnergy will always be the time in seconds it will take for one cycle of a one shot particle system to complete, so you could try using WaitForSeconds() to enable/disable emission for a duration equal to maxEnergy, like (not tested):
public var muzzleFlashEmitter : ParticleEmitter;
public var fireRate : float = 0.5;
private var nextFire : float = 0.0;
function Start(){
muzzleFlashEmitter.emit = false;
}
function Update(){
if(Input.GetButtonDown("Fire1") (Time.time > nextFire)){
StartCoroutine(FireOneShot());
}
}
function FireOneShot(){
nextFire = Time.time + fireRate;
muzzleFlashEmitter.emit = true;
yield WaitForSeconds(muzzleFlashEmitter.maxEnergy); //note that if fireRate is less than max energy, emissions could overlap
muzzleFlashEmitter.emit = false;
}
The code you’re showing here is as if taken from one of my attempts at this.
The problem with it however is the fact that I need to set the energy values fairly high to ensure the particle lives long enough to hit it’s target. So rapid fire and long particle life can’t coexist when using that approach, sadly.
Ahhh, yeah I was thinking in terms of short muzzle flashes, didn’t realize you were making a laser beam or something. At this point I would cop out and relegate back to instantiation but that’s me, hehe.
It’s on the shelf for now as I honestly don’t think it can work properly with the current particle system. There’s other things that are hard to do as well with particles. For instance there is no contact.point when a particle collides and I have to loop through all the particles in the system and guess that it’s the one with 0 velocity that collided so I can spawn an explosion on it.
Just found Simulate() as well which will help me with generating my stars.
For anyone finding this thread:
using UnityEngine;
using System.Collections;
public class Fire : MonoBehaviour {
public ParticleEmitter lazor;
public float fireRate = 0.5f;
private float nextFire = 0.0f;
// Update is called once per frame
void Update () {
if (Input.GetButton ("Fire1") Time.time > nextFire) {
nextFire = Time.time + fireRate;
lazor.Emit();
if (audio) {
audio.Play();
}
}
}
}
(replace “GetButton” with “GetButtonDown” if you want semi auto instead of full auto)
I’m not entirely sure how Emit() without passing it a number of particles is any different than emit, unless it is in effect the equivalent of telling a one-shot particle system to emit one “shot”? I’m guessing that is the case from your eureka post; if so, I will convert my silly instantiations over to this method pronto
I have 2 projects in Unity which I’ve spent an equal amount of time on, one which I haven’t shown to anyone and won’t show until it comes near my expectations. The other is my third person shooter.
I’m not really interested in working on the third person shooter at this moment so that will just have to wait until I decide what to do with it.
Then there’s this space game which is basically just to get me back into Unity again. WIll give it away at some point. Just have to finish my website which is what I’m primarily working on at the moment. Apart from the 80 hours of actual work a week, of course. Perhaps one day those hours are Unity hours.
Lastly there’s the mystery project which I think can become extremely cool once it goes from the idea/reference folder to Unity.