Rolling a Ball: Harder Than You Thought (part 2)
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.
Part 2 – Force Is Actually Good… Sometimes
This is part two of a three part blog series on everything that I’ve discovered goes into making a ball roll well in Unreal Engine 4. Part one can be found here. To summarize the first part: you should be using torque to rotate your moving ball rather than force, because force is bad. In addition, using multiple spheres inside of each other can help aid in movement, which I have discussed in greater detail in my previous posting.
I’m am currently the lead programmer on a nine-person project at Almost Infinity Games LLC, looking to release a game named Rollossus in late February 2019. Two of my major tasks have been implementing our enemies and creating satisfying and tactile player movement. A large part of these tasks was to establish that using force to move the player ball was a bad idea. However, later in development it became clear that was not entirely correct. Let me explain…
Using force for all-purpose ball movement is bad, and leads to unsatisfying game-feel. However, instead of using force as a blunt hammer, we can use it as more of a precision tool. In particular, we can use it for rapidly changing the momentum of the ball.
The problem we were having with movement is that if the player wanted to change direction 180 degrees, they have to undo all of the speed they have going forward, and then rebuild that speed in a new direction. The effect is much less pronounced when changing at angles smaller than 90 degrees, but movement felt sluggish and the player didn’t feel like they had a high degree of control, and found it very unsatisfying to try and change directions.
Our solution to this was to implement a way to detect when they player was attempting to change direction, and then add an assisting force to make that change much more responsive, scaling to how drastic a direction change the player wanted to make. Thankfully we set up some architecture in the previous blog post about which helps us with this.
Before I get into the solution, remember that Rollossus uses a Visible Sphere and Invisible Sphere. Our inner, Invisible Sphere will always face wherever our input axes are facing (easy way to visualize this is where the joystick on a game pad is pointing, the exact math for this can be found in the previous post). The Invisible Sphere weighs nothing and stays central to the Visible Sphere. The Visible Sphere is the ‘real’ ball, and has the weight, physical material, etc. It will always roll in the direction of the forward vector of the Invisible Sphere.
Back to our implementation of force to aid turning. At a basic level, we’re just finding the cosine (in degrees) of a dot product and dividing by 180, and then multiplying the result (something between 0 and 1) by a big number. Another reason the Invisible Sphere is super useful is because whatever the forward vector is, is our Desired Vector (DV). The other important vector is the linear velocity of our Visible Sphere (where the ball is going), the Actual Vector (AV). First step is normalizing both of these vectors, and then finding the cosine of the dot product of them, then dividing by 180, shown below.
What this does is find the shortest angle between two vectors and then divides it by 180 (the furthest possible angle). We can take this number, which will be somewhere between 0 and 1, and multiply our Redirect Force by it. For example, if our desired angle was perpendicular to our movement angle (90 degrees difference), then our result would be 0.5 and we would only use half of the Redirect Force. Our RedirectForce number will likely be very large, I believe Rollossus’ is somewhere around 5 million, but depending on the weight of your ball, friction values, and gravity amount, you may have to have more/less.
The effect of this equation essentially gives the player the feeling of a high degree of control of their direction, without making acceleration some insanely high value (which feels bad). Since implementing this calculation, we’ve received great results in playtesting and it's allowed us to make much more dynamic obstacles in our game, because we have a more agile ball. Part three will be coming out in a week, where I address several small changes and tweaks you can make to round out the feel of your movement.Part 3 can be found here