I added a bit of cellular turbulence to the particles that have already collided with the sphere. This helps show the sphere’s shape during phases where its motion is minimal. I know I used turbulence at some point back in an earlier version of the project and assume the reason it wasn’t there anymore is because of its impact on performance. If this turns out to be too much of an issue again, I’ll disable it.
I found a pretty glaring mistake in my VFX graph logic that’s been hiding in plain sight. I was using my combined metaballs SDF as the bounce-generating collision shape in the Update Particles context. What made this an issue is that I was resizing the scale of the collision shape to be slightly smaller—my reason for doing this was that it allows the shape of the particle flow to better conform to the SDF attractor shape than when the collision surface is the same size or larger. However, the SDF attractor contains ALL metaballs in the scene; meaning that when scaled down, it scales from the origin rather than the position of the corresponding player’s sphere. This causes an offset between the SDF collision surface and SDF attractor shape, as shown below.

The fix was to swap the SDF collision shape to a simple sphere with the same position and (slightly smaller scale) as the corresponding player’s sphere.
It would be very nice if, when a player initializes their energy ball, it starts tiny and grows to full size. Unfortunately, I know that the metaballs start to lose their shape below a certain scale. My theory, however, is that the low fidelity shape won’t even be noticeable during the time it takes the metaball to scale back to size. Let’s see what Claude can do…
Absolutely beautiful! However, in a delicately built codebase such as this one, sometimes when you improve one thing, you make something else worse. I always forget to test one-handed states in my dummy scene.
With the metaball mesh enabled, it’s easier to see what’s happening.
Look closely. At the starting scale of the metaball radius animation, the mesh disappears completely.
Even after cranking up metaballRadiusAnimationStartSize, the metaball was still animating from 0. It turned out Claude hadn’t added the global setting properly. Luckily, I had a doc for that.
I changed things so that the only time the radius animation plays out is when shifting out of a state where both hands were closed. After accounting for all edge cases, I’m happy with the result! I even added an animation curve to interpolate the animation.
I noticed that the noise driving Add Position block in my Output Particle Quad wasn’t actually making the sphere look wavy. Swapping the Perlin Noise for Perlin Curl Noise fixed this. Like the SDF attractor gaff, I’m not sure how I overlooked this for so long.
Speaking of noise, a long-standing todo of mine has been to add directional noise based on the velocity vector of the particles. Using the particle velocity to drive the curl noise coordinates did not give me the results I’m seeking because the sphere’s velocity, rather than the particles’ velocities, is what I need to drive this noise. Essentially, I want to “squeeze” the overall shape of the particles based on the direction of the sphere they follow as a target. The closer the particles are to the target, the more they should “reach” toward it.
In order to make this effect happen, ChatGPT says I need to write the sphere’s target position in my VFX graph. While scouting for the proper location to add this code, I found a bug; bugs always take precedence over features. When I release the sphere with only one hand, its momentum shifts toward the midpoint between the hands. I need to fix this, but even more urgently, I need to eat some dinner.