 Congratulations, you've made a simple bouncy ball rig. However, while this rig was simple to create, it turns out that it's not ideal. This ball rig can do some pretty cool things, like bounce across the screen with some nice squashing and stretching. However, if we want it to roll while it's squashed or stretched, it really can't do that. And this is because the axis of squash and stretch is inexorably linked to the rotation of the ball. We can't rotate the ball without rotating the squash and stretch too. Clearly, this isn't optimal, but how do we unlink the squash and stretch from the rotation? As with many rigging problems, there are actually multiple ways to do this, but I'm going to focus on one in particular, because it also gives me a great opportunity to introduce one of the most basic rigging tools in 3D graphics, parent-child relationships. Right off the bat, when we hear the words parent and child, we think of two separate independent people who have a certain relationship to each other. But to explain what a parent-child relationship is in computer graphics, I think it's actually easier to think of it in terms of a pregnant woman who has yet to give birth. Which is to say that when you move the mother, you move the child as well, and if you drop a piano on the mother, squishing her, the child gets squished too. But the child can still move inside of the mother's womb as well. Mind you, I'm not intending to make any political statements here. It's an imperfect analogy anyway, but it's just to give you an idea. So let's actually test this out in Blender now. We already have a ball, so we just need one more object to be able to create a parent-child relationship. In this case, let's create a cube. And let's place the cube so that the ball is inside of it. And switch to wireframe view so that we can still see the ball. Okay, so now we can think of the ball as being the baby, the child. And we can think of the cube as being the parent, or the mother. But we have to explicitly tell Blender to create this relationship. And to do that, all you have to do is first select the ball, then the cube, and take control P. And then a menu will pop up with only one item in it. I'll explain why there's a menu at all later on in the series. And just click on that one item in the menu, confirming that you want to create the parent-child relationship. Now it doesn't look like anything much has actually changed, but let's select the cube and move it. Hey, look, the ball goes along with it. But what about moving the ball? Ah, the ball can still move independently as well. But what's really going on here? So what's going on is that the ball exists inside the quote, space of the cube. Similar to how a baby exists inside the space of its mother. What this means in 3D graphics terms is that the translation, rotation, and the scale of the ball are now all relative to the translation, rotation, and scale of the cube. To better illustrate this, let's try rotating the cube and then playing with the ball's translation axes. You'll notice now that when we change the ball's X position, it's actually moving along the X axis of the cube, not the X axis of the world. In essence, the cube is now the ball's world, but it gets even weirder. If we scale the cube on just one axis, not only does the ball squish as well, but the meaning of its translation axes squish too. So notice that it moves further on the long axis than on the short axis for the same value change. This is because the ball's very world, its parent, its mother that it is inside, has been squished. Just like a piano fell on her. But wait, there's more. What if we rotate the ball? My goodness, how cool is that? The ball can still rotate in this distorted space. And this, my friend, is exactly how we're going to accomplish our goal. However, before we do that, I just want to point out that parent-child relationships can also be multi-level. So if we create another object, we can give the ball a child as well. And it's at this point that the pregnant mother analogy kind of gets disturbing, because now there's a pregnant mother whose baby is also pregnant with another baby. So maybe I should drop that analogy now. Anyway, back to the ball rig. We now know that we can accomplish what we want by using parent-child relationships. However, using a cube really isn't ideal, because it obscures the ball. In fact, we really don't want the parent to be an object with any visible mesh at all. And this is where empties come in. Remember empties? They're objects that contain no mesh or, in fact, any other data at all. They're just transforms in space. And that's exactly what we need. So let's delete everything except the ball. And let's add an empty. Now, if we were to move the empty to the center of the ball as we want to, it would become hidden within the ball. And we don't want that. We still want to be able to see it. Fortunately, Blender allows us to change the appearance of empties. To do this, select the empty in question and go to the empty properties panel. This kind of sounds kind of funny. Empty properties panel. Like it's empty, but it's not empty, it's just properties panel. Anyway, click on the display dropdown menu and select cube. Yay, now it looks like a cube. And it's a cube that's large enough to be outside of the ball when they overlap. If it wasn't large enough, we could increase its display size using the size field below the display menu. So now clear the empties transforms to place it in the same position as the ball. And let's make the ball the child of the empty. Now the empty is going to be responsible for the squash and stretch and location of the ball. So let's set it up for that like we did with the ball. Lock the y translation axis and the x and y scale axes. And add the maintain volume constraint to the empty. And configure the constraint. The empty will also be rotating, however, to determine the direction of the squash and stretch. So let's also lock the x and z rotation axes. Now we can move, rotate, and scale the empty. And we can spin the ball. Much nicer. However, we also need to go and clean up the ball, because it's no longer responsible for translation or squash and stretch. So let's completely lock its translation and scale axes. And its maintain volume constraint is no longer necessary. So this is pretty cool now. We can spin the ball, even in its squash door stretched states. And that enables a lot more animation possibilities. However, there is still one last thing that can be improved. And that is to remove the need for the animator to counter animate. Wait, what? What do I mean by counter animate? OK, so counter animation is an issue that comes up in a lot of parent child rig setups. In this case, if the animator wants the ball's spin to remain stationary, but still wants to change the direction of the squash and stretch, she would have to first rotate the empty and then rotate the ball back to compensate. And over the course of an animation, the animator would have to do this over many frames compensating for or countering the rotations of the empty. That process is called counter animation, and it's bad. Bad, bad, bad. It is unnecessary work, and it distracts the animator from their job, which is making good animations. So we want to design and build our rigs to avoid this. In this case, what we want to do is find a way for the ball to follow the translation and scale of the empty, but not its rotation. Right off the bat, I want to let you know that there is a really easy way to do this if we were using bones. In fact, it's a simple check box that you just uncheck. But first of all, this option doesn't exist on objects. And second of all, even on bones, there are some pretty good reasons to avoid using it in favor of other methods. So let's figure out another way to do this. To get the thinking started, let's revisit what it is that the animators would do without this. Animators would, by hand, be rotating the ball in the reverse direction of the empty to compensate for the empty's rotation. So why not just think of this as a problem of automating that process, automating what the animator was gonna do anyway, just rotating the ball in reverse of the empty. And it turns out Blender has a great tool for exactly this sort of thing, which I briefly introduced in the last video. And that tool is called drivers. So what we want to do is create a link between the empty's rotation and the ball's rotation that drives the ball's rotation in reverse. Now, creating drivers is a little annoying, and it's gonna introduce a new component of Blender's UI called the graph editor, but I'll try to keep it simple for now and just explain the parts that are relevant to this problem. I'll get more in depth into the driver system later on. First, how and where do we add a driver? On a technical level, drivers are essentially just automated animation. So drivers exist on the property that's going to be automated, or in Blender's terminology, the property that's going to be driven. In this case, that's the ball's y rotation. To add a driver, you simply right click on the property you want to drive and select add single driver. Notice that the property changes color. This color indicates that the property is automated, that it has a driver on it. However, there is a problem now if we try to rotate the ball, which is that we can't rotate it. And this is because drivers completely take over the property that they are automating, but we still need the animator to be able to animate the ball's rotation. So how can we solve this? It turns out that this sort of situation is actually really common in rigging. You want to automate some aspect of an object's or control's motion, but you also still want the animator to be able to animate on top of that automation. This problem is really common in rigging, in fact. So it would be a good idea to first define a general solution for it. And it turns out there is in fact a very general solution for it. Parents! Remember that? Yeah. If an object has a parent, it exists in that parent's space. And therefore it moves with the parent, but it can still move independently as well. So whenever you run into this kind of situation where you want something to be automated, but you want to be able to animate on top of it as well, you can simply give the object a parent and use that parent to automate the motion. So let's add another empty to be that parent. And let's increase its display size so that the ball doesn't completely hide it. Let's now switch the ball's parent to be the empty we just added. Now the ball follows that empty instead of the main control empty. To make the ball still follow the main control empty as well, we can simply parent the new empty to the old one. Now you can see that if we want to compensate for the rotation of the main control empty, we can do it on this new empty. Okay, this is actually getting kind of complicated and all just for a 2D ball rig, but we're almost there. Worry not, worry not. Select the new empty and add a driver to its y rotation axis. By default, the driver isn't set up to do anything. We have to tell it how we want it to automate the property. To do that, we need to go to Blender's graph editor. Let's split the 3D view into two windows. Right click on the edge and select split area. Then move the mouse about halfway in the middle and left click. Now change the window type of left area by clicking this icon in the lower left and select graph editor from the menu that pops up. Not to get off track too much, but that's how you can customize your window layout in Blender. Okay, now that we have a graph editor visible, we need to change it to driver mode so we can see the drivers in our scene. Click on this menu here and select drivers. Now in the left pane of the graph editor here is our list of drivers. Currently, there's only one. Click on it to select it. To configure it, we need to see its properties which are in the graph editor's end panel. So press N on the keyboard to toggle it open. This looks really confusing and, well, it kind of is. But let's simplify. The only panel we care about in here is the driver's panel. So collapse everything else. Okay, that's better. So this shows us the properties of the currently selected driver. There are basically two parts to this panel. The bottom part here is where we tell the driver what other properties are used to automate this property. And we call those properties the variables of the driver. You can add as many variables as you want by clicking the add variable button. But in this case, we really only want one. There are also multiple variable types that you can choose from via this dropdown menu. But let's not get into that yet. For now, leave it as transform channel. Let's configure this variable to reference the y-axis rotation of the main control empty. First, we need to specify the object and in this case, it's the main control empty. The field here is where we do that. We can either type in the name of the object manually or we can treat the field as a dropdown menu and simply select the name of the object. Now all we need to do is select which transform channel we want to reference on the main control empty. In this case, we want the y-axis rotation. And that's all for the variables. But the driver still isn't gonna do anything yet. We need to configure how it's going to use the variable to automate our property. And that is what the top section of the driver panel is for. There are multiple different modes that a driver can be in which influences how it uses the variables. By default, it uses scripted expressions and we're just gonna stick with that for now. I'll explain the other modes later. In scripted expression mode, the driver evaluates the Python expression in this field. An expression is simply a math formula and we can use any of the variables we've created for the driver in that expression. In this case, we only have one variable and it's named var. We can change the name if we want, but I'm gonna leave it. What we want to do is have this driver do the opposite of what our variable here does. That way our new empty will rotate opposites of the main control empty. So the expression we're going to use is simply negative var. After changing in driver, it's a good idea to click updates dependencies just to make sure the changes take properly. Now if we rotate the main control empty, the new empty and ball appear to stay stationary. But let's take a look at the rotation values of the two empties. The main empty has a rotation of 30 degrees right now and the new empty has a rotation of negative 30 degrees, exactly the opposite. And that's why it appears to be remaining stationary because it's doing exactly the opposite of whatever the main control empty is doing. And because the ball is its child, it too remains stationary. And in this way, we have automated the counter animation process. Hooray! Since the new empty isn't a control that we want the animator to be using or that the animator in fact needs to use it all, let's move it to a hidden layer. Select the empty and press M on your keyboard. Click on this layer. Objects and bones that the animator doesn't need to use but only act to automate something are what I like to call mechanism objects or mechanism bones if it's a bone. It's like the internal parts of a car. The person driving the car never directly manipulates them but they're still part of how the car functions. Okay, and lastly, let's name the main control empty something other than empty. Perhaps main is a better name. And naming your objects and bones something recognizable and sensible is actually a really important part of rigging. So never forget to do that. Now we can finally play around with our rig.