Page 1234 - Kitab3DsMax
P. 1234
Part XII: MAXScript and Plug-Ins
Next, you created some more variables. You use zadd to tell Max how much to move the fish in the
Z-direction at each step. (You don’t want our fish to always swim at the same level.) tailFlapOffset
and tailFlapRate are two variables used to control the tail flapping. (I explain this when you get to the
part of the script that uses them.)
Inside the for loop, notice that you’ve overridden the fish’s Z-position and replaced it with just the relative
Z-position, so that each fish swims at its own depth and not the dummy object’s depth. Then, at each step,
you add zadd to the Z-position so that the fish changes depth slowly. You have to be careful, or your fish
will continue to climb out of the scene or run into the ground, so at each step you also choose a random
number between 1 and 100 with the function (random 1 100). If the random number that Max picks is
greater than 90, you flip the sign of zadd so that the fish starts moving in the other direction. This is a
fancy way of saying, “There’s a 90 percent chance that the fish will continue moving in the same direction
and a 10 percent chance that it will switch directions.”
In the next part, you again access the tail’s bend modifier, this time to set the bend angle. To get a nice
back-and-forth motion for the tail, you use the sin function. In case you’ve forgotten all that math from
when you were in school, a sine wave oscillates from 1 to –1 to 1 over and over again. By multiplying the
function by 50, you get values that oscillate between 50 and –50 (pretty good values to use for your bend
angle). You use tailFlapOffset to shift the sine wave so that the tail flapping of additional fish is out of
synch slightly with this one (remember, you’re trying to get at least a little realism here) and tailFl-
apRate to make each fish flap its tail at a slightly different speed.
The only thing left for you to do is to make the fish “follow” the path; that is, rotate its body so that it’s fac-
ing the direction it’s moving. The simplest way to do this is to use the following MAXScript (split into two
lines to make it easier to read):
newRt = (in coordsys pathObj pathObj.rotation.z_rotation)
fishObj.rotation.z_rotation = newRt
The in coordsys construct tells Max to give you a value from the point of view of a particular coordinate
system. Instead of pathObj, you could have asked for the Z-rotation in the world, local, screen, or parent
coordinate system, too. In this case, you want to rotate the fish in the same coordinate system as the dummy
object. To randomize the direction of the fish a little, you’ve made the rotation a little more complex:
oldRt = fishObj.rotation.z_rotation
newRt = (in coordsys pathObj pathObj.rotation.z_rotation)
if ((random 1 100) > 85) then
(
fishObj.rotation.z_rotation += (newRt - oldRt) *
(random 0.5 1.5)
)
First, you save the old Z-rotation in oldRt, and then you put the new rotation in newRt. Again, you pick a
random number to decide whether you’ll do something; in this case you’re saying, “There’s an 85 percent
chance I won’t change directions at all.” If your random number does fall in that other 15 percent, however,
you adjust the fish’s rotation a little. You take the difference between the new rotation and the old rotation
and multiply it by a random number between 0.5 and 1.5, which means you adjust the rotation by any-
where from 50 percent to 150 percent of the difference between the two rotations. So any fish will basically
follow the same path, but with a little variation here and there.
1186