import scene3d
scene = scene3d.Scene()
scene.set_sky('#1a1a2e')
scene.set_ground(length=12, width=12)
sphere = scene3d.Shapes.Sphere(diameter=1, segments=16)
sphere.set_color('#e94560')
sphere.set_position(2, 4, -1)
scene.add(sphere)
pos = sphere.get_position()
shadow = scene3d.Shapes.Sphere(diameter=0.9, segments=10)
shadow.set_color('#111111')
shadow.set_scale(1, 0.12, 1)
shadow.set_position(pos[0], 0.05, pos[2])
scene.add(shadow)
ctx = scene.get_context('2d')
ctx.fill_style = '#ffffff'
ctx.font = '20px sans-serif'
ctx.fill_text(f'get_position() returned: x={pos[0]}, y={pos[1]}, z={pos[2]}', 10, 30)Getters — Reading Object Properties
So far you’ve only written to objects — set_position, set_color, set_scale. But every mesh also remembers what it was given, and you can read that back at any time.
Methods that start with get_ return the current value of a property:
pos = sphere.get_position() # returns (x, y, z)
rot = sphere.get_rotation() # returns (x, y, z) in degrees
scl = sphere.get_scale() # returns (x, y, z) scale factorsThis lets you read where an object is — even when that position is the result of physics, animation, or a user action.
Reading Position to Place a Second Object
Here’s a case where a getter is immediately useful: you place a sphere somewhere in 3D space and want to add a flat shadow directly beneath it on the ground — at the same x and z, but y = 0.
Instead of typing those coordinates twice (and risking them getting out of sync), you read them back with get_position() and use the values directly.
What Getters Return
Each getter returns a tuple — three values packed together, one for each axis:
pos = sphere.get_position() # e.g. (2, 4, -1)
pos[0] # x
pos[1] # y
pos[2] # zYou index into the tuple with [0], [1], [2] to get each component. Python also lets you unpack all three at once:
x, y, z = sphere.get_position()| Getter | Returns | Index |
|---|---|---|
get_position() |
Current x, y, z position | [0] [1] [2] |
get_rotation() |
Current x, y, z rotation in degrees | [0] [1] [2] |
get_scale() |
Current x, y, z scale factors | [0] [1] [2] |
{ “question_type”: “multiple_choice”, “question”: “If sphere.get_position() returns (3, 5, -2), what does pos[1] equal?”, “options”: [ { “key”: “a”, “text”: “3” }, { “key”: “b”, “text”: “5” }, { “key”: “-2”, “text”: “-2” }, { “key”: “d”, “text”: “(3, 5, -2)” } ], “answer”: “b”, “submitted_answer”: “” }
{ “question_type”: “true_false”, “question”: “get_position() returns the position you last set with set_position().”, “answer”: “True”, “submitted_answer”: “” }
Getters in Animation
Getters become especially powerful inside animation loops, where an object’s position is constantly changing and you need to read the current state to decide what to do next.
The scene below simulates a bouncing ball with gravity. Each frame, get_position() reads the ball’s current height, and an if statement decides whether to bounce it back up.
Click Stop (■) when you’ve watched a few bounces.
import scene3d
scene = scene3d.Scene()
scene.set_sky('#0f3460')
scene.set_ground(length=10, width=10)
ball = scene3d.Shapes.Sphere(diameter=0.8, segments=16)
ball.set_color('#e94560')
ball.set_position(0, 6, 0)
scene.add(ball)
ctx = scene.get_context('2d')
velocity = 0.0
@scene.on_frame
def animate(dt):
global velocity
velocity -= 9.8 * dt
x, y, z = ball.get_position()
y += velocity * dt
if y < 0.4:
y = 0.4
velocity = abs(velocity) * 0.75
ball.set_position(x, y, z)
ctx.clear()
ctx.fill_style = '#ffffff'
ctx.font = '20px sans-serif'
ctx.fill_text(f'y = {y:.2f} | velocity = {velocity:.2f}', 10, 28)
scene.run()Why Getters Make Animation Cleaner
Notice the line x, y, z = ball.get_position() in the animation. It reads back all three coordinates at once and unpacks them into separate variables.
This means: - You only track velocity as a separate variable — the position lives inside the mesh - You only modify y, then pass all three back to set_position unchanged for x and z - If you later move the ball sideways too, the same pattern still works — no extra variables needed
Getters let the mesh be the source of truth for its own state.
{ “question_type”: “multiple_choice”, “question”: “In the bouncing ball example, why is get_position() used inside the animation loop?”, “options”: [ { “key”: “a”, “text”: “To make the ball move faster” }, { “key”: “b”, “text”: “To read the ball’s current position before updating it” }, { “key”: “c”, “text”: “To set the ball’s color” }, { “key”: “d”, “text”: “get_position is required before every set_position call” } ], “answer”: “b”, “submitted_answer”: “” }
{ “question_type”: “freeform”, “question”: “Write one line of Python that reads the current scale of a mesh called ‘box’ and stores it in a variable called ‘scl’.”, “answer”: “scl = box.get_scale()”, “submitted_answer”: “” }
Try It Yourself
Use the sliders to set where the sphere starts. The shadow and the drop-line are placed automatically using get_position() — try different positions and watch them update without any extra code.
import scene3d
X = 2.0 #@param {type:"slider", min:-4, max:4, step:0.5}
Y = 3.0 #@param {type:"slider", min:0.5, max:6, step:0.5}
Z = 0.0 #@param {type:"slider", min:-4, max:4, step:0.5}
scene = scene3d.Scene()
scene.set_sky('#1a1a2e')
scene.set_ground(length=12, width=12)
sphere = scene3d.Shapes.Sphere(diameter=1, segments=16)
sphere.set_color('#e94560')
sphere.set_position(X, Y, Z)
scene.add(sphere)
pos = sphere.get_position()
shadow = scene3d.Shapes.Sphere(diameter=0.9, segments=10)
shadow.set_color('#111111')
shadow.set_scale(1, 0.12, 1)
shadow.set_position(pos[0], 0.05, pos[2])
scene.add(shadow)
drop_line = scene3d.Shapes.Cylinder(diameter=0.04, height=pos[1], tessellation=4)
drop_line.set_color('#ffffff')
drop_line.set_position(pos[0], pos[1] / 2, pos[2])
scene.add(drop_line)
ctx = scene.get_context('2d')
ctx.fill_style = '#ffffff'
ctx.font = '20px sans-serif'
ctx.fill_text(f'get_position() → x={pos[0]:.1f}, y={pos[1]:.1f}, z={pos[2]:.1f}', 10, 30)Think about a game or simulation where knowing an object’s current position is important — a character avoiding walls, a missile tracking a target, two cars about to collide.
Describe a scene where you’d need get_position() or another getter, and explain what decision you’d make based on the value you read.