Ok...I'll go through and explain the match/process here for ya hype
Step1: Getting the box to roll properly around its Y-Axis
BEFORE YOU DO ANYTHING!!!....Center the pivot of the box to the box itself, and align the pivot to the world. Also, make sure that the box's LENGTH, WIDTH, and HEIGHT are all the same!!!
Ok...we're going to assume that we want our box to roll properly, back and forth along its X-Axis. Thus, it will need to rotate along its Y-Axis.
The first thing to do is to give your box's Y-Rotation a Float Script controller.
Once the float script dialog pops up, under the "Create Variable" parameters, type in "self" and click "Create". You'll notice the new variable will appear in the list of script variables.
The next thing to do, is select "self" in the list and then click the "Assign Node" button. Choose the box (the one we're rolling) as the node to assign to the "self" variable.
Next, in the "expression" section of the Float Script window, replace the zero ("0") with this code:
- Code: Select All Code
boxRad = self.length/2
rad = sqrt(boxRad*boxRad + boxRad*boxRad)
pi = 3.141592
circ = 2*rad*pi
mult = 360/circ
degtorad(self.pos.x)*mult
Click "Evaluate" in the script window.
Here is a breakdown of what the code is doing:
boxRad = self.length/2 -- assuming the box has equal proportions on all sides, this gets the radius by dividing the length of the box by 2. This is therefore the value of the box's minimum radius
rad = sqrt(boxRad*boxRad + boxRad*boxRad) -- using the Pythagorean theorm, we get the length from the center of the box to any corner of the box (ie...the maximum radius of the box)
pi = 3.141592 -- we define the value of pi, to a good degree of accuracy
circ = 2*rad*pi -- we get the circumference of the entire box, by multiplying the diameter of the box (diameter = 2*radius) by pi
mult = 360/circ -- the 'mult' value tells us how many rotational degrees equal 1 unit of the box's circumference
degtorad(self.pos.x)*mult -- finally, we tell the Float Script how many radians to rotate our box, first by converting the box's X-Position to degrees, and then multiplying that value by the value of 'mult', to give us the correct ratio between distance travelled and rotational radians.
The box should now roll, if you drag it back and forth along the world X-Axis.
Step2: Getting the box to roll over its cornersNow that it's rolling, we need it to roll over its corners as a real box would, if you were to push it.
Luckily, this part is fairly simple, due to the fact that the Z-Position of a rolling box follows the pattern of simple harmonic motion.
Basically, we need the Z-Position of the box to move up and down in a coordinate system relative to that of the absolute value of a sine curve.
If you're not familiar with what that is...well, this is a sine curve (where y = sin[x]):
And this is what that curve looks like, if you take the absolute value of the original function (y = abs{sin[x]}):
So...the next step is incorporating this principle into our rolling box.
The first thing you'll need to do is give your box a Position List controller, and then in the "available" slot, set the controller to another Position XYZ controller. Then, assign the Z Position a Float Script controller, in the new Position XYZ controller of the Position List.
Using the same method described above for the Rotational Script we added to the box's Y Rotation, give your Z Position controller a new "self" variable (ie...add the self variable and assign the box node to it).
Then, in the expression section of the Float Script window, replace the zero ("0") with this code:
- Code: Select All Code
boxRad = self.length/2
rad = sqrt(boxRad*boxRad + boxRad*boxRad)
pi = 3.141592
circ = rad*2*pi
percent1 = (self.pos.x / circ) * 2 * pi * 2
value = sin(radtodeg(percent1)) * (rad - boxRad)
abs(value)
boxRad = self.length/2 -- once again, we get the minimum radius of the box
rad = sqrt(boxRad*boxRad + boxRad*boxRad) -- once again, we also get the maximum radius of the box
pi = 3.141592 -- pi is defined again
circ = rad*2*pi -- the circumference of the box, based on its maximum radius is found again
percent1 = (self.pos.x / circ) * 2 * pi * 2 -- here, we first find how many rotations the box has travelled, based on the ratio between the box's X-Position, and the box's circumference (a value of 1 means 1 rotation). Then, we multiply that value by 2pi to convert that percent to radians. Finally, we multiply that value by 2 again because we want the box to roll flat onto each side. If we didn't multiply the final value by 2, it would only roll flat onto every other side. If we divided the value by 2, it would only roll flat on one side. The reason for this, is because a sine curve has a slope of 0 at 2 points, so by multiplying the radian value by 2, we can effectively get the sine curve to have a slope of 0 at 4 points for each full rotation of the box, which therefore allows the box to land flat on each side once.
value = sin(radtodeg(percent1)) * (rad - boxRad) -- here is where we actually calculate the amplitude and frequency of the sine curve. First, we find the frequency of the sine curve by finding the sin value of the variable 'percent1' that we declared above. Then, we define the amplitude of the curve by multiplying the sin value by the distance between the maximum and minumum of our box
abs(value) -- in this last step, we send the ABSOLUTE value of the sin function to the Float Script, effectively causing our box to roll over its edges. If we did not take the absolute value of the sin function, and instead just gave the float script the original sin function, the box would not roll over its edges, instead, it would ossilate up and down over the ground which would clearly be an incorrect result
Click "Evaluate" in the script window.
That's it! Now you should be able to drag your box back and forth, and it should roll properly.