Tank Rig Tutorial
< 1 2 3 4 5 6 >
Auto Slide Caterpillar
Before start creating the caterpillar we have to finish our wheel's set-up and then we'll clone it four times.
First we'll set up our Wheel's Control Object ("Control_Wheel_01"), as mentioned before in the first page, these control objects will be useful for Animator's adjustments and custom animation.
Basically we're gonna instance the transform controllers. Like instanced Objects, a change to the instance for any one controller will change all the others.
To do that, First unhide by name the "Control_Wheel_ 01", align it to the wheel (position and orientation) and make an offset in its position and orientation with the "Affect Object only" button pressed in the Hierarchy panel (take a look at the picture, both pivots must be in the same place).
Link the Control_Wheel to the "Helper_Attached_ 01". Since the transform controllers are respect to the Parent's transformation, we need to make sure that both objects have the same parent.
Next, Select the Wheel_01 and open the Track view (you can also open the Mini Curve Editor clicking the buttonin the Left-Bottom of the Screen). Navigate until you find the Wheel's transform controller, click it and then with the right button, select "Copy". Then, navigate until you find the Control_Wheel's transform controller, click it and right click it, this time select "Paste" and check "Instance" in the Paste DialogBox.
Now both objects, Wheel and Control_Wheel are transform-controller Instanced, you can check it out by moving the Control_Wheel.
First we'll set up our Wheel's Control Object ("Control_Wheel_01"), as mentioned before in the first page, these control objects will be useful for Animator's adjustments and custom animation.
Basically we're gonna instance the transform controllers. Like instanced Objects, a change to the instance for any one controller will change all the others.
To do that, First unhide by name the "Control_Wheel_ 01", align it to the wheel (position and orientation) and make an offset in its position and orientation with the "Affect Object only" button pressed in the Hierarchy panel (take a look at the picture, both pivots must be in the same place).
Link the Control_Wheel to the "Helper_Attached_ 01". Since the transform controllers are respect to the Parent's transformation, we need to make sure that both objects have the same parent.
Next, Select the Wheel_01 and open the Track view (you can also open the Mini Curve Editor clicking the buttonin the Left-Bottom of the Screen). Navigate until you find the Wheel's transform controller, click it and then with the right button, select "Copy". Then, navigate until you find the Control_Wheel's transform controller, click it and right click it, this time select "Paste" and check "Instance" in the Paste DialogBox.
Now both objects, Wheel and Control_Wheel are transform-controller Instanced, you can check it out by moving the Control_Wheel.
Cloning the Wheels
Double-click the Helper_Attached_01(it's easier if you do it in wireframe mode), it will select all the objects under its hierarchy, including itself. Clone them by pressing ctrl+v, select copy in both options (object and controller). If your cloned wheel has an orientation offset, you can fix it selecting by name the Helper_Attached_02 and rotating it.
Then, select by name the Helper_Attached_02 if you haven't, go to the motion panel in the Attachment Parameters rollout and decrease the Face number until you get the right position for the second wheel, this number could be 2 units less than the first wheel (if this rollout doesn't appear you need activate the position button in the PRS Parameters rollout). Do the same process three more times for the remaining wheels. For the last wheel you need to change the A and B values to fix its position (A=0, B=1) and set the face value to 1.
Then, select by name the Helper_Attached_02 if you haven't, go to the motion panel in the Attachment Parameters rollout and decrease the Face number until you get the right position for the second wheel, this number could be 2 units less than the first wheel (if this rollout doesn't appear you need activate the position button in the PRS Parameters rollout). Do the same process three more times for the remaining wheels. For the last wheel you need to change the A and B values to fix its position (A=0, B=1) and set the face value to 1.
Creating the Caterpillar
As mentioned in the first page, the caterpillar is based in several pieces slidding around a spline. So now, we'll create the spline.
Select the projectedPlane, in the Modify panel turn off its conform binding modifier by clicking the bulb and set its world position and rotation values to zero. This is temporal, it's to do the next steps more easily having the tank aligned to the viewport.
Select the projectedPlane, in the Modify panel turn off its conform binding modifier by clicking the bulb and set its world position and rotation values to zero. This is temporal, it's to do the next steps more easily having the tank aligned to the viewport.
To create the small wheels, double click the Helper_Attached_01 to select it with the wheel and the control object, clone them pressing ctrl+v, select copy in both options. We need to clone the wheel with the helper because we need a parent with the same orientation (the controllers are in respect to the parent's transform), select the Helper_Attached_06, in the motion panel select its Position list controller and replace it by a Position XYZ controller, doing this we're deleting the attachment constraint.
Fix its orientation by rotating it -90 degrees over its z-axis, and place it in the back-top side of the tank (see picture), Unhide the Frame and link the helper to it. Then select the wheel and decrease its radius value, like 0.373, you have to decrease it in the script controller too. To create the front small wheel, double clik the Helper_Attached_06, clone the objects, select by name the Helper_Attached_07 and place it at the front of the tank. |
From the left view start creating the spline adding vertices at the bottom of the wheels, one vertex per each wheel, continuing above the small wheels (see picture below). Finally make sure that all vertices are bezier type with tangents as large as shown in the picture (select vertices -> right click -> left-top quad -> bezier), these tangents will generate a smooth interpolation in the spline while being deformed over the ground's surface. From the top view move the line to the middle of the wheels. Name this spline as "CaterpillarSpline".
Next, we need to create one point helper for each spline's vertex. Use the Vertex snap tool for this operation and set a size of 0.2 for them. We're gonna use these helpers to deform the spline's vertices. Name them Helper_CaterpillarPoint_1, Helper_CaterpillarPoint_2 .... starting by the Helper in the first wheel. You could use the rename Objects tool in the tools menu.
Next, we need to create one point helper for each spline's vertex. Use the Vertex snap tool for this operation and set a size of 0.2 for them. We're gonna use these helpers to deform the spline's vertices. Name them Helper_CaterpillarPoint_1, Helper_CaterpillarPoint_2 .... starting by the Helper in the first wheel. You could use the rename Objects tool in the tools menu.
There are some methods to deform a spline using nodes, like the Spline IK Control modifier. But i didn't use it in this rig because in some tank's orientations the vertices didn't behave well, also, it has problems when you clone it. So, finally i decided to use the skin modifier. this modifier will affect the spline's vertices as it does with mesh vertices, it's not expensive for the pc (the spline has a very few vertices) and it doesn't have problems like the Spline IK Control does.
Add the skin modifier to the spline, and then, add all the Helper_CaterpillarPoints as bones. Modify the weight for each vertex and its tangents points in respect to their respective Helper, until you get the desired result. Now, link The bottom helper_CaterpillarPoints to their respective Helper_Attached points, doing this the spline will be attached to the ProjectedPlane too. Link the rest of the CaterpillarPoints to the Frame, and link the Frame to the ProjectedPlane (Do not forget do this). To make the helpers follow the wheel's position, we'll need a position constraint. Select the wheel_01 caterpillar helper add a position constraint to it selecting the wheel as target. We cannot use the "Keep Initial offset" option because it defines positions not relative to the tank, therefore in some tank's orientations this helper will have a wrong position. To place it where it was before assign a Position XYZ controller in the available controller of the position list and make it active in the position list Rollout, you can delete the first Poistion XYZ controller, it's useless now. Then place the helper where it was before (you can do it aligning it to the Helper_Attached object). Do the same process with the rest of the wheels. The upper caterpillar helpers need to be constrained to the small wheels. |
Caterpillar Pieces
The pieces will slide using a path constraint over the spline that we have created, then we'll add a script controller in its percent along path controller to define its slidding in respect to the distance traveled by the tank.
Unhide by name the Caterpillar_Piece_01, link to the Frame and add a path constraint to it using the CaterpillarSpline as target. In the motion panel in the path parameters rollout set the parameters as shown in the picture. The Allow Upside Down option will enable the piece to have the right orientation through the spline without any flipping. Then rotate the piece -90 degrees over its local x-axis and then -90 degrees over its local z-axis. |
Now, we'll add the script to the percent controller. In the motion panel -> Assign controller rollout (you can also do it in the track view) assign a float list controller in the percent controller, in the list's available controller assign a Bezier float controller, and in the First controller (Linear Float) assign a Float Script. We created a list of controllers to define an extra value with the second controller, so, in this way, we can define an offset to each caterpillar's piece having the same script controller for all of them. The script is almost the same than the wheel's spinning. But in this time we're not using a radius, instead, we'll be using the Caterpillar length. Start writting the first line of the previous script: SplineLength=curvelength Path |
Then add the next line after the first one:
CatLength=curvelength Caterpillar
In the last line replace radius by CatLength and place a minus at the beginning of this line:
-(Percent/100)*SplineLength/CatLength
And don't forget to create the variables and assigning their respective nodes or tracks. In the Caterpillar variable we need to assign the CaterpillarSpline as node.
In this case we're finding the number of the piece's turns along the caterpillar dividing the distance by the caterpillarLength (the perimeter).
This is what the controller handles, a value from 0 to 1, 1 as 100%, in this case as 1 turn along the spline.
CatLength=curvelength Caterpillar
In the last line replace radius by CatLength and place a minus at the beginning of this line:
-(Percent/100)*SplineLength/CatLength
And don't forget to create the variables and assigning their respective nodes or tracks. In the Caterpillar variable we need to assign the CaterpillarSpline as node.
In this case we're finding the number of the piece's turns along the caterpillar dividing the distance by the caterpillarLength (the perimeter).
This is what the controller handles, a value from 0 to 1, 1 as 100%, in this case as 1 turn along the spline.
Cloning the Pieces
To clone the pieces we need to do the same process 50 times!.
Fortunately, there is a method to do it very quickly, an iterative macro operation. As i said in the first page, it means to make a lot of repetitive tasks in a few lines of code.
Go to Maxscript Menu -> New Script. In the Text Field paste these lines of code:
Fortunately, there is a method to do it very quickly, an iterative macro operation. As i said in the first page, it means to make a lot of repetitive tasks in a few lines of code.
Go to Maxscript Menu -> New Script. In the Text Field paste these lines of code:
for i=1 to 49 do
(
newPiece=copy $Caterpillar_Piece_01
newPiece.position.controller[2].percent.controller[2].value=(i/50 as float)*100
newPiece.position.controller[2].percent.controller[1].controller=
$Caterpillar_Piece_01.position.controller[2].percent.controller[1].controller
)
How it works:
for i=1 to 49 do
First, we need to define the iteration range using the sentence "for", using the variable "i" we start defining the first number of the iteration, in this case we start from 1, and then defining the last number of the iteration, in this case 49, we'll be executing the same process 49 times. Inside the Iteration the current loop number is stored in the variable "i", we can use this number to set a percent offset in the current piece copy.
Between parenthesys we describe the process that we need to repeat 49 times.
newPiece=copy $Caterpillar_Piece_01
In this line of code we're creating the copy of the piece and storing it in the "newPiece" variable, we need to use the "$" character before the object's name to be able to use this object inside maxscript. If the object's name has any space on it, in maxscript we need to replace this space by the "_" character.
newPiece.position.controller[2].percent.controller[2].value=(i/50 as float)*100
In this line we're defining the percent offset. With the dot character (.) i'm accessing into a property, first accessing the newPiece's position property , then the second controller of the position, then its percent, then the second controller of this percent, and finally the value of this controller. I use the variable "i" (current loop) to find the right offset, if we divide this number by the total number of copies we get a value ranged from 0 to 1, multiplying it by 100 we get the percent respective to the current copy. i use "as float" to make sure the division will bring me a decimal number.
newPiece.position.controller[2].percent.controller[1].controller=
$Caterpillar_Piece_01.position.controller[2].percent.controller[1].controller
this is only one line actually, it was too long. Here, we're copying-instance the first percent controller, the script controller. If we'll need to make any configuration to this controller in the future, we'll need to make it only once. And also there's only one script controller executing only one time giving a value shared for all the pieces.
After you place the code in the Text Field of the maxscript editor go to File->Evaluate All. Now we got 50 pieces!.
This is just a very very tiny explanation of iterative macro operations, you could check the Maxscript reference for a lot of information about this. Also, you could use the Macro recorder to find the maxscript code for an operation in max, You can activate it in the Maxscript menu -> Macro recorder. It enables a pink Text Field in the Maxscript Listener (Maxscript Menu->Maxscript Listener). If you made an operation in max the script will appear in this text Field, unfortunatelly not all the max's operations appears there.
for i=1 to 49 do
First, we need to define the iteration range using the sentence "for", using the variable "i" we start defining the first number of the iteration, in this case we start from 1, and then defining the last number of the iteration, in this case 49, we'll be executing the same process 49 times. Inside the Iteration the current loop number is stored in the variable "i", we can use this number to set a percent offset in the current piece copy.
Between parenthesys we describe the process that we need to repeat 49 times.
newPiece=copy $Caterpillar_Piece_01
In this line of code we're creating the copy of the piece and storing it in the "newPiece" variable, we need to use the "$" character before the object's name to be able to use this object inside maxscript. If the object's name has any space on it, in maxscript we need to replace this space by the "_" character.
newPiece.position.controller[2].percent.controller[2].value=(i/50 as float)*100
In this line we're defining the percent offset. With the dot character (.) i'm accessing into a property, first accessing the newPiece's position property , then the second controller of the position, then its percent, then the second controller of this percent, and finally the value of this controller. I use the variable "i" (current loop) to find the right offset, if we divide this number by the total number of copies we get a value ranged from 0 to 1, multiplying it by 100 we get the percent respective to the current copy. i use "as float" to make sure the division will bring me a decimal number.
newPiece.position.controller[2].percent.controller[1].controller=
$Caterpillar_Piece_01.position.controller[2].percent.controller[1].controller
this is only one line actually, it was too long. Here, we're copying-instance the first percent controller, the script controller. If we'll need to make any configuration to this controller in the future, we'll need to make it only once. And also there's only one script controller executing only one time giving a value shared for all the pieces.
After you place the code in the Text Field of the maxscript editor go to File->Evaluate All. Now we got 50 pieces!.
This is just a very very tiny explanation of iterative macro operations, you could check the Maxscript reference for a lot of information about this. Also, you could use the Macro recorder to find the maxscript code for an operation in max, You can activate it in the Maxscript menu -> Macro recorder. It enables a pink Text Field in the Maxscript Listener (Maxscript Menu->Maxscript Listener). If you made an operation in max the script will appear in this text Field, unfortunatelly not all the max's operations appears there.