Director Tutorials


Character Control

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.

1. Open the movie and create a pause frame behavior in frame 2 of the scripting channel.

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 =
  -- 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:

on createLight

  -- 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.
  pCharacter.addChild(p3Dmember.light \
("Bulb Light"),#preserveParent)


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:

on keyDown

  -- 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.

on keyUp
  -- 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:
put member("scene").model("character").transform.position

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:

on resetCharacter
  pCharacter.transform.position = \
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.