Make Floating Rocks with the Power of Math™! (Part 1)

14 minute read

So, you thought to yourself, “Man, wouldn’t it be cool if I could add some floating rocks to my level?” Well, I heard those thoughts you were thinking, so here’s a quick tutorial for how to do that kind of stuff pretty simply with blueprints!

This tutorial assumes you know at least the basics of how to use UE4 Blueprints – I’m more concerned with showing you the why’s and how’s of the math, and the thinking behind these things. If you have any questions, feel free to use any of the social media methods linked above, or just post a comment!

The thing we’re going to build

I just built this tool here yesterday for a scene my friend Jon Riley is making (all meshes and textures used here are made by him!), and we’ll use it as an example to show some things you can do to make those stones float nicely:

It’s pretty simple, really! Let’s look at the big stone at the top first. As you can see below, it does some very slow undulating rotations and a bit of bobbing.

Normal speed:

Here’s the same thing at 8x speed, so you can see it better:

Let’s pick it apart then, shall we? 🙂 As you can see in the sped-up version of the video, the rotation of that rock is basically a swivel motion, combined with some vertical bobbing. The swiveling is more interesting, so let’s tackle that first!

Swivel those rocks!

Swiveling is defined as “turning around a point”, though in this case it makes more sense to think of it as rotating around an axis. Here’s a visual illustration of the math we’re going to use:

To get started with that, let’s first create the swivel vector in our blueprint’s construction script. If you paid attention in the video at the start of this post, you’ll have noticed that the user control for this is not a vector input, but just a float to specify the swivel angle. To get a swivel vector from that, we have to do our first bit of math!

I added some squiggly notes so that you can hopefully better understand what does what. The Swivel Cone X/Y float variables are editable variables that your level designer can use to tweak how exaggerated the swiveling should be. Swivel Axis X/Y are our blue vector above, for the X and Y axis respectively. We’ll rotate those around the local space X/Y axes on every frame by a little bit, in order to get that nice undulating swivel motion.

It’s no Sine to enjoy maths!

Now, I assume that you already know at least the basics about what sine waves are, but just in case, here’s a quick refresher in the form of an image I shamelessly stole from a Google image search:

Wave-Terminology

The other input (besides the swivel cone angle) that level designers get with this tool is the rotation period. As the diagram above so helpfully illustrates, that means: the time it takes to perform one full cycle. I decided to use period, because it’s the most human-relatable number, even if it makes the math we’re doing a little bit more complex. Always plan for user-friendliness! The less you have to explain how the tools you build work, the more time you can spend actually building your tools 🙂

Here’s the math that creates the swivel motion:

SwivelProgress

Alright now, don’t get intimidated! This is actually quite simple. Let’s pick it apart bit by bit!

On Ticks and the illusion of smooth movement

First of all, what’s a “Tick”? Does it bite? No, Tick is an Event that gets called by the engine on every single frame that is rendered. It’s a common misconception that somehow things in a game are happening smoothly and gradually. The truth is that things happen in steps. Very small steps, yes, but still. For example, if your game renders at 60 FPS, that means there are 60 steps to everything, every second. Game engines generally work like this: First, all the logic is executed. For example, every moving object has its position and rotation updated by whatever drives it, projectiles fly forward, player input is received and handled, and so on. Next, the engine takes all that information and gives the relevant parts of it to the renderer, so that it can produce the image that you see on screen. And then it goes back to the first step, forever repeating until someone presses Alt+F4.

So, games really only give the illusion of things moving smoothly. Just like films! Although… am I the only one thinking that 24FPS for films is really just not enough? I hope the glorious future of VR movies changes that habit…

ANYWAY. Back to the math. Let’s just look at one of those parts in isolation.

SwivelProgress2

Delta Seconds“, by the way, is the real-world time that has elapsed between the last Tick and this one. It’s great if you want things to move at the same speed, regardless of framerate! Which you should always want. Here, the first bit of math that we do is to multiply delta seconds with 360 so that one second equals 360° of rotation. Then we divide that by the Swivel Period, which, you guessed it, is the period (see that sine wave terminology graph above) for one full cycle. The result: we get the amount of degrees that something should rotate in this tick, if it has the rotation period we specified!

The next bit is pretty common too: we take that result, and add it to our Current Swivel variable. We want this value to continually count upwards, so to do that, we have to take the rotation of this frame, and add it to our current rotation. That way it continually counts upwards, and in a framerate-independent way! Neat, huh?

Now you might wonder what that node with the percentage sign is for. That’s a “modulo” node. If you remember your elementary school math, when you had to do divisions by hand, whenever a dividend wasn’t a full multiple of the divisor, you always got a result, and a remainder. Modulo is basically that: it divides input A by input B, but instead of returning the result, it returns the remainder. So, for example… 13 modulo 10 equals 3.

In this case, we’re using it so that the rotation “loops” when it reaches 360°. This won’t be noticable in game, but it’s a good practice because if numbers get too high, at some point you might run into float precision errors. Let’s not get into that right now though!

Onward:

Doing something with all this math stuff we so bravely calculated

SwivelProgress3

Doesn’t this look familiar to you? If not, check above! We already used the Rotate Vector Around Axis function in the Construction Script. Here, instead of using the straight-up coordinate axis as the In Vector, we use the rotated vector that we created from the cone angle earlier in the Construction Script, and rotate that around the local coordinate axis. That makes the vector swivel exactly like the one in the example with the two arrows above!

The next thing you might be wondering about: “Make Rot from XY.” UE4 has a whole number of “Make Rot from …” functions, and to understand what they do, you need to understand a little bit about Rotators and coordinate systems. If you already know all this stuff, just skip on to the next big section! 🙂

A few words about vectors, rotators and transforms

Let’s talk about Rotators first. In Blueprint, a Rotator (colored light blue, like the wire coming out of the Make Rot node in the screenshot up there) is composed of three components: Roll, Pitch, and Yaw. Roll is rotation around the X axis, pitch is rotation around the Y axis, and yaw is rotation around the Z axis.

By convention, UE4 considers the X axis as the forward direction, Y as right, and Z as up. Rotators are simply the amount of degrees that something needs to be rotated from the default rotation (facing forward down the X axis) on each axis, in order to reach the desired orientation.

“Why not just use vectors?”, you might wonder. There’s a simple explanation – allow me to illustrate! You all know this guy, right?

CharacterRot1

Think of that little blue arrow there as a vector that indicates the character’s forward direction. But is that enough information to exactly determine its rotation? Sadly not. Observe:

CharacterRot2

The character’s forward arrow still points exactly the same way, but we can all see that that’s not how it’s supposed to be rotated, right? Vectors are great for indicating locations or directions, but if you need more than that, it’s best to use a rotator instead.

This is why each and every actor and object that exists in the game world has what’s called a “Transform“. Transforms are totally neat and useful! In code, they’re usually represented by a 4×4 Matrix, which… stop, come back, don’t run away! Math just wants to be your friend! And don’t worry, in Blueprints it’s a lot simpler: Transforms are represented by Location, Rotation, and Scale. The neat thing about transforms is that you can use them to represent any transformation (a-ha!) from one spatial configuration to any other in one single operation, and you can even combine multiple transforms into a single one!

As a side-note, you may have already encountered mentions of “Relative” and “World” space. If it’s not obvious what that means, “relative” space is simply a coordinate system that is transformed so that it aligns with the Transform of whatever object its relative to – meaning that the relative X axis is the object’s forward axis, the relative Z axis is the object’s up axis, and so on.

Make Rot from what?

Alright, now that you know all that or have refreshed your knowledge, what do the Make Rot from … nodes do? Simply put, they let you specify one or two axis vectors, and create a Rotator based on that. Make Rot from X, when given an input vector, treats that vector as the Rotator’s target coordinate system’s forward vector. As we’ve established above though, one vector alone does not give you reliable results! While UE is smart and will try to guess what you mean (in the case of Make Rot from X, it assumes that the standard up vector – (0,0,1) – is your desired up vector, for example), you can get more precise control by supplying two vectors. Make Rot from XZ for example creates a Rotator that points forward down the supplied X input vector, and then rolls it (remember: roll is rotation around the X axis) so that the output Rotator’s up vector is as close to the Z input vector as possible. Make Rot from ZX does the opposite: it creates a Rotator where the Z input is guaranteed up, and then it’s rotated around that axis so that forward is in the direction of X.

Side-note: that means that the two input vectors don’t have to be perpendicular – the first one is taken as the guide, and the second one is approximated as closely as possible. Except it’s not approximation at all, but exact math – it’s all a bunch of trigonometry under the hood, but really, you don’t have to worry about it too much.

So, what are we doing here then? As a refresher, and so you don’t have to scroll up, this is what we were talking about:

SwivelProgress3

As we’ve already established above, the outputs of those two Rotate Vector Around Axis nodes – over time, i.e. over the duration of multiple ticks – describe two vectors that perform a swiveling motion in a cone, of whatever angle we’ve let our level designers define, around the X and Y axis respectively. Now we simply take those two axes, and make a Rotator out of them.

And since the speed and angle of the two swivel motions are different from each other, that gives us a nice, natural-looking and seemingly non-looping undulating rotation!

So now, all that’s left is connecting that Rotator output into a Set Relative Rotation function for the top rock mesh component, hit the big Play or Simulate button, and we can see it doing its thing! Neat, huh? 🙂

 

Well, that’s it for this first part, folks! Part 2 will deal with the big rock’s bobbing movement, and part 3 will explain how to make those neat little orbiting stones.

I hope you found this tutorial useful! If you have a moment, please feel free leave me some feedback in the comments – not sure if I went too in-depth here, or not in-depth enough… but I hope I managed to strike a good balance. If this tutorial taught you anything, you could also do me a solid and click one of those share buttons below!

Till next time!

Update: Part 2 is available! Read it here.

Updated: