- Home /
sucking in particles
is there a way to make an object suck up particles within a certain range? i have a black hole i made and using a wind zone it can suck up particles within a certain range but the problem is they just pass through the black hole to the other side of the wind zone. how can i make it so once they reach the black hole they either dissipate or get sucked into it until they dissipate themselves
Answer by Stratosome · Jul 10, 2018 at 12:11 AM
Ooo, that sounds pretty cool. I haven't fully explored Unity's particle system, however, unless I am mistaken, this is sounding like a task for some code. Here is a quick script showing the idea of how to grab particles from a ParticleSystem component and modify them to put custom behaviors on them:
[SerializeField] private Transform blackHole;
private ParticleSystem ps;
private ParticleSystem.Particle[] modifiedParticles;
void Start() {
ps = GetComponent<ParticleSystem>();
modifiedParticles= new ParticleSystem.Particle[1000];
}
void Update() {
if (!ps)
return;
Vector3 vecToTarget = blackHole.position - transform.position;
float mag = vecToTarget.magnitude;
// Gets current particles from ParticleSystem and puts them into our particles array
int length = ps.GetParticles(modifiedParticles);
for (var i = 0; i < length; i++) {
// Modify the properties of the particles in modifiedParticles
// ...
modifiedParticles[i].velocity += vecToTarget;
}
// Put the modified particles back in the ParticleSystem
ps.SetParticles(modifiedParticles, length);
}
So, with this idea, you can apply a velocity to your particles towards the black hole to hopefully give the desired effect. I haven't tested this exact code, but I pulled parts of some of my old code that worked, so hopefully it is at least pretty close to working.
So, you could let your wind zone apply the forces and then, inside of the loop here, check to see if it is inside the black hole. If so, kill the particle (some how) or zero its velocity. Somethin' like that. OR, you could skip the wind zone and have more control over the motion of the particles with the script here. Either way I think will work. Here is the documentation of Unity's particle so you can see what you can modify on them: ParticleSystem.Particle
A local variable named vecToTarget' cannot be declared in this scope because it would give a different meaning to
vecToTarget', which is already used in a `parent or current' scope to denote something else
I'm getting this error
Oops, I made a tiny mistake. There are two variables there named vecToTarget. They are conflicting. Remove the vecToTarget in the loop and it should work. And you don't even need the variable unless you want to use it. It was just a little example of a variable that could be useful for the black hole thing.
im also getting an error on the two named particles
The example code in your answer goes in the right direction, however you have inconsistent na$$anonymous$$g of your variables. Specifically "modifiedParticles" and "particles" which look like they should be the same.
btw: To erase a particle, just remove it from the array. To do this you would just replace the particle you want to get rid of with the last particle (length-1) and then reduce "length" by 1. So when setting the particles back you only set the particles you want to keep:
// length = 10
// index: 0 1 2 3 4 5 6 7 8 9 10 11
// particle: P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 X X ....
To remove particle 2 you would just move P9(the last one) to index 2 and decrease length by 1
// length = 9
// index: 0 1 2 3 4 5 6 7 8 9 10 11
// particle: P0 P1 P9 P3 P4 P5 P6 P7 P8 X X X ....
if you also want to remove particle 5 do the same again:
// length = 8
// index: 0 1 2 3 4 5 6 7 8 9 10 11
// particle: P0 P1 P9 P3 P4 P8 P6 P7 X X X X ....
It doesn't matter where in the array a certain particle is located. Note the "X" just indicates an "unused" array element. So a generic "remove" method would be something like this:
public static void RemoveParticle(ParticleSystem.Particle[] aParticles, ref int aLength, int aIndex)
{
if (aLength <= 0 || aIndex < 0 || aIndex >=aLength)
return;
aLength--;
if (aIndex < aLength)
aParticles[aIndex] = aParticles[aLength];
}
ok so im a bit confused, so when the particles collide with an object how do u get it to switch with the last in the array?
Well, if you have an actual collider you may just want to turn on particle collisions. Just watch this video. $$anonymous$$ake sure you follow the first 2 $$anonymous$$utes carefully.
Hah, yeah, I made the correction to my code above now. I've kind of been hacking together as I go. Been busy and a tad distracted. But yeah, your solution to removing particles makes sense. Cool.
Answer by SpiralConDave · Jul 10, 2018 at 12:18 AM
Maybe this? https://assetstore.unity.com/packages/vfx/particles/black-hole-47962
It seems there was some particle system on the Asset Store that did this, not sure what it was called.
Answer by midgardweller · May 15, 2019 at 09:42 PM
I've achieved this effect in the past by adding a collider to the center of the Wind Zone. Then enable collision in your particle system and set Dampen to 1, Bounce to 0, and Lifetime Loss to 1. This way as soon as a particle collides with the Wind Zone, it stops it in its tracks and kills it off. I also have a specific Wind Zone layer that I use just for that and tell the particle system to only collide with that layer.
No code required!
Your answer
Follow this Question
Related Questions
pulling objects across a collider 0 Answers
pulling in objects one end, and releasing out the other 0 Answers
My object can't move left and right but only jump? 1 Answer
adding force 1 Answer
adding Up force 0 Answers