Moving objects in Shockwave 3D
Before you start, you will need to download the following Director movie - 3Denv.dir, which contains a 3DS Max created shockwave 3D cast member.
2. Create a new behavior attached to the 3D sprite as follows:
-- create properties for when arrow keys are pressed
-- properties will either be TRUE or FALSE values
property pLeftArrow, pRightArrow, pDownArrow, pUpArrow
property p3Dmember -- reference to 3D cast member
property pCharacter -- character in the 3D world
on beginSprite me
-- initiate properties and 3D world
p3Dmember = sprite(me.spriteNum).member
pCharacter = p3Dmember.model("character")
-- we must define pCharacter after we use the
-- resetWorld() command otherwise this variable
-- object will be deleted
The 3D Lingo statements above are similar to the last tutorial except for the creation of a few new property variables. pLeftArrow, pRightArrow, pDownArrow, pUpArrow will tell us when the arrow keys are being pressed (TRUE value) and when they are released (FALSE value). We created a variable reference to the 3D character in the world, making it easier to refer to this object throughout the script. You will note that I defined the pCharacter after the resetWorld() command. If I would have defined it before, then resetWorld() would have removed the variable from memory.
3. Continue the script as follows:
-- create a point 'bulb' type light
p3Dmember.newLight("Bulb Light", #point )
-- position the light
p3Dmember.light("Bulb Light").transform.position = \
-- Make the character model a parent of the light
-- Bulb Light becomes a child of pCharacter
-- This is done so that the light will always move
-- with the character.
Once again, the code is similar to the last tutorial but with an additional statement to create a parent-child relationship (explained in the comments). You can read more about parent-child relationship in 3D at my The make-up of shockwave 3D casts page.
4. Next we will create the keyboard control of the character.
Continue by adding the following to the same script:
-- check to see which key has been pressed
-- and set the property relating to that key to TRUE
-- 123 = left arrow key
if keypressed(123) then pLeftArrow = TRUE
-- 124 = right arrow key
if keypressed(124) then pRightArrow = TRUE
-- 125 = down arrow key
if keypressed(125) then pDownArrow = TRUE
-- 126 = up arrow key
if keypressed(126) then pUpArrow = TRUE
If you did my cubicVR tutorial, you will notice I am using different Lingo to do the same thing. Here, I am using if..then. In the other tutorial I used case. I am also using keypressed instead of the keycode. Look at both tutorials and use whichever you feel most comfortable with. Both work fine.
-- when the arrow keys are released,
-- set the properties to FALSE
pLeftArrow = FALSE
pRightArrow = FALSE
pUpArrow = FALSE
pDownArrow = FALSE
-- if the right arrow is pressed,
-- rotate the character 5 degrees about the z-axis
if pRightArrow then pCharacter.rotate(0,0,-5)
We could have rotated the character relative to its parent or world position. By not specifying a relativeTo parameter, the default of #self is used, which is relative to the node’s local co-ordinate system.
--if the right arrow is pressed,
-- rotate character -5 degrees about the z-axis
if pLeftArrow then pCharacter.rotate(0,0,5)
-- if the up arrow is pressed,
-- move the character 5 pixels along the y-axis
if pUpArrow then pCharacter.translate(0,5,0)
-- if the down arrow is pressed,
-- move the character -5 pixels along the y-axis
if pDownArrow then pCharacter.translate(0,-5,0)
5. Play the movie and use the arrow keys to move the character model around. Note what happens with the light.
6. Sometimes it is useful to be able to press a button to bring back your model to its original position in the 3D world. Now, we'll do just that. First, we have to find the starting location of the character. In the Message window type the following, then press ENTER:
I could not type p3Dmember.resetWorld() and make it work because p3Dmember is not a global variable but a property related the script.
In the Message window, type the following, then press ENTER:
This returns the vector location of the character, which we will now use.
7. In the keyDown handler, add the following before the end statement.
if keypressed("r") then resetCharacter
Create a new handler (perhaps after the keyUp handler) as follows:
pCharacter.transform.position = \
vector(26.5860, 27.4024, 41.8902)
A better way of scripting the above and avoid hard coding the vector starting location of the character, would be to create a variable in the beginSprite handler that stores the position before the character moves. Try do this on your own.
8. Play the movie and test what you just created.
You can download the completed movie from here.