Sometimes, I get caught up coding something before I’ve even thought about what it should be. That’s what would have happened had I continued working on the pulse speed yesterday. I know I want to tie it to a body’s acceleration, but how should that work? I’ve done some thinking and have come up with rules to make the pulse look more natural:
- Body should pulse quickly during an abrupt stop and slowly while in motion
- Body should increase in size if the player’s hands start beneath a distance apart threshold and then move away from each other.
- Body should decrease in size if player’s hands move from a distance apart larger than the body’s diameter to a distance less than the body’s diameter.
The only one of those rules I can realistically work on implementing today is rule #1.
One reason I had trouble detecting changes in velocity yesterday is because the drag of all Rigidbodies in the scene is set to 0. This means that force added never dissipates, only getting countered by other added forces. Playing with drag now makes me think I really should have looked into using it as a natural way to add counter-force to the bodies. Whateva. If it aint broke…
I added a previousAcceleration float property to the player constructor because I intended to use jerk to control pulse speed. I’ll need to calculate acceleration and jerk for each body every frame.
I shouldn’t be controlling body pulse from inside my controller’s nested for-loop, whose content should only include functions relevant to body interaction with attractors. The way I see things, body pulse needs to be interaction-independent. Unfortunately, my pulse-controlling code was being called from within my scale function. I saved my controller script and incremented to a new version. It was time to make some more changes.
I renamed my ScaleObject() function to ScaleBody() for peace of mind. Then, I created a new function called ManageOrbitalBodies(). I intended for this function to get called within the nested for-loop so that I could separate the scaling-specific code to ScaleBody(), which I moved to the outer for-loop.
To separate the setting of a body’s pulse size from the setting of its scale, I added a pulseSize property to the player constructor, setting the property in a function SetPulseSize() that gets called in the outer for-loop. Now I needed merely to access the pulseSize from within ScaleObject().
I had a funny little bug pop up during all this—a body would only pulsate when merged with another body. To solve this issue, I needed to reorder some code. Inside ScaleBody(), I was setting a body’s unscaledSize as its current localScale minus its pulseSize whenever it had no orbiting bodies. Right below that code, I then set the body’s localScale to its unscaledSize plus its pulseSize plus its sizeScaler (calculated from its orbital bodies). In simple mathematical terms, this is what I was doing:
Running those two equations sequentially completely cancels out the pulseSize (Sₚ)! However, if I flip the order in which they execute, I can set unscaledSize without affecting the body’s scale. This is because setting localScale directly affects a value in the game window while setting unscaledSize does so indirectly.
To celebrate the squashing of that bug, I got a little fancy with NaughtyAttributes and organized my controller script:
After considering pulsation a bit more, I’ve decided that the pulsation implementation I’ve used thus far can be used as a general effect that runs regardless of a body’s acceleration. Instead, I’ll scale a player with a different method (not yet concocted) according to my rules above once forces from the player’s hands are implemented in my scene. For now, I’m going to complicate my existing pulsation effect to make it seem more varied. To do that, I’ll stack sine waves of different amplitudes and frequencies to generate a wave pattern that seems random.
Tags: gamedev unity vfx scripting physics debugging animation