Open MatrixDev opened 3 weeks ago
Forgot to add, I'm running this on my M1 laptop. I don't think it is M1 related problem because example works for me.
@MatrixDev the way ribbons work is not intuitive. You have a single particle group, and no CloneModifier
. The RibbonModifier
works by chaining 1 "head" particle from group 0 with all associated "cloned" particles from group 1. Here you're not cloning anything so the ribbon has nothing to render (can't make a ribbon with 1 particle). And because it's present, the head particle itself doesn't render. You should look at the ribbon.rs
example. Basically for 1 ribbon you need to spawn 1 particle in the first group (0), and then N particles making up the ribbon in group 1. Then when you move the head particle of group 0 around, each frame the other particles in group 1 will get automatically updated to the previous position of the particle before them, which will create the ribbon.
hi @djeedai, thanks for answering. but I don't understand than how to make a particle in group 0 (tail particle) follow my entity? I can set SimulationSpace
to Local
but than whole ribbon will be in local space and I don't want it.
Is it possible to have group 0 in local space and group 1 in global?
ribbon.rs
doesn't really help me because entity position there doesn't matter, only calculations in expression. should I use properties to update group 0 position each time my entity position changes?
a particle in group 0 (tail particle)
Group 0 is the main group you control, where all init modifiers run, and which is driven by normal simulation, like if there was no ribbon. This works exactly as before ribbon existed.
Group 1 is the group of "tail" particles (the particles which follow the "head", and together form a ribbon; there's generally multiple tail particles per head particle). You have very little control over those. They're updated by cloning the head particles (for the first tail particle), or another tail particle (the one coming before in the chain). This is all done by the CloneModifier
. The init modifiers never run on those groups, because cloning happens during the update pass.
The RibbonModifier
only affects the rendering of all those particles. You can still make particles follow themselves in trails without using RibbonModifier
. The RibbonModifer
only creates a continuous curve between particles, as opposed to simply rendering each particle independently of the other.
how to make a particle [...] follow my entity?
This is a general question independent of ribbons. There are multiple approaches to this. If you have a single particle/ribbon, then you can just spawn that particle at a fixed point (for example the origin) and not apply any force. It will stay there and not move. Then you use local space simulation and move the Entity
around. This only works with a single particle/ribbon because there's only one Entity
per effect instance. If you have more than that, you can use properties; drive the Attribute::POSITION
of the particle with a property, and each frame set the property from CPU to the position you want to. That has the advantage of supporting any number of particles/ribbons. The (small) inconvenient is that you upload from CPU to GPU not only the Entity
transform but also all the properties you use, each frame. This is probably negligible unless you start using a lot. This is also a bit more involved to setup and update, since you have to manually update the property to the value of the position. This works both in local and global space simulation, although the calculation of the property value differs.
@djeedai, thanks a lot for your answer but... sorry, I still can't make it to work...
So I've modified ribbon.rs
example by (following your instructions):
.with_simulation_space(SimulationSpace::Local)
.update_groups(move_modifier, ParticleGroupSet::single(0))
so that head
particle only follows the entity instead of using expression.Everything else is the same in the example but the ribbon is still not rendered :(
What I think is happening is all particles (head and ribbon) are always set to Vec3::ZERO
position in the local space of the entity. Because of this nothing is drawing. Example modifies actual position of the head particle directly, so all cloned particles always have different position.
BTW yes, I meant "head" particle, not "tail" back there.
Hum... yes of course that suggestion was stupid, the RibbonModifier
only looks at the simulation space, and there the head particle doesn't move, so all cloned tail particles also don't move. Stupid me.
You probably need to drive the head particle with a property you setup and update manually, and use GlobalSpaceSimulation
. The spawn_on_command.rs
example shows how to use properties (it uses them to spawn the effect based on the collision normal that the CPU calculated).
@djeedai, yeap, it works with properties. but... it doesn't work with SizeOverLifetimeModifier
now.
I've just added this modifier in the example:
let render_size = SizeOverLifetimeModifier {
gradient: Gradient::linear(Vec2::splat(0.5), Vec2::ZERO),
screen_space_size: false,
};
// EffectAsset::new...
.render_groups(render_size, ParticleGroupSet::single(1))
Nobody ever tried that to be honest. I'm pretty sure it'll not work with RibbonModifier
because they both try to change the quad size and orientation, so whichever comes last wins. But I'm surprised it doesn't work without, because the render modifier should work on any group.
Oh, is that screenshot actually with the RibbonModifier
? I thought it was without. If so then that's exactly what I described, the SizeOverLifetimeModifier
comes last and undoes the work the RibbonModifier
did to chain particles together. I'll have to think about how to fix that without special casing this particular couple of modifiers too much.
@djeedai, it is original example with SizeOverLifetimeModifier
added. Is there maybe any other way of making ribbon shrink over lifetime (like using expressions or something)?
It looks like RibbonModifier
only changes the X size of particles, so I'm guessing whatever way (modifier or expression) changing the Y size should work. But it needs to be executed before the ribbon modifier. So you can try inserting the SizeOverLifetimeModifier
first, maybe that works already?
Crate versions
bevy
version:0.13
bevy_hanabi
version:0.11.0
(reproduces onmain
branch as well)Describe the bug In short nothing renders after adding
RibbonModifier
.I might misunderstood how to use
RibbonModifier
so this might not be a bug. My sample is simpler than what you have in examples folder but I still think it should still work. BTWmove_particle_effect
system doesn't do anything in that example (I've commented it out and everything is the same).Expected behavior
RibbonModifier
should work without using clone modifier from example.To Reproduce
Screenshots Everything renders without
RibbonModifier
: