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 factors

This lets you read where an object is — even when that position is the result of physics, animation, or a user action.

Open In Jupyter K-12

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.

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)

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]  # z

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