enter image description here

enter image description here

As a dice builder, I want to set Z rotation axis of the text which you see in the image to the face which I selected. But how ?

  • $\begingroup$ Do you mean manually, or automatically? If automatically, how do you want to define 'up'? $\endgroup$
    – Robin Betts
    Aug 5, 2023 at 13:36
  • $\begingroup$ The Z axis of the text will be facing towards the selected face. But orientation will be as "Normal". $\endgroup$ Aug 5, 2023 at 13:37

2 Answers 2


You can rotate this manually, to eye, by setting orientation to local or normal and hitting r z to rotate in its Z axis. Or, you can use constraints to orient the number automatically.

enter image description here

I've marked the top face, the one I want the numbers to track, by assigning its vertices to a vertex group. Then I can use a locked track constraint on the text object to locked track the location of that vertex group-- with these settings, to rotate about its Z axis to point its Y axis at that location.

Since I'm using constraints anyways, I'm using a shrinkwrap constraint to place the text on the face to begin with. You may have used snapping instead, which is fine.


You can easily achieve this with a script which I have prepared at the bottom of this post. Select any face in Edit Mode and then click Run Script. It will automatically add a Text object to the center of the face that is aligned perfectly to the Normal of that selected face.

enter image description here

If you want to rotate or reposition the text object, just select the text object and press either Shift+NumPad-7 or Ctrl+Shift+NumPad-7 (which correspond to View > Align View > Align View to Active > Top/Bottom) to get its Normal perfectly aligned to the camera. Then you can easily rotate or reposition the text while it's flat on the face.

enter image description here

Here's the Python script which you can paste into the Text Editor. It basically temporarily repositions the Z-Axis of the base object to face into the direction of the selected face normal and then positions the Cursor there and adds a text object. The text object is then aligned to face toward the same direction as the base object's Origin's z-axis.

import bpy

source_object = bpy.context.object
text = "A"

if bpy.context.active_object.mode != 'EDIT':
    raise RuntimeError("You must be in Edit Mode and have a selected face")

area_type = 'VIEW_3D'
areas  = [area for area in bpy.context.window.screen.areas if area.type == area_type]

if len(areas) <= 0:
    raise Exception(f"Make sure an Area of type {area_type} is open or visible in your screen!")

with bpy.context.temp_override(
    regions=[region for region in areas[0].regions if region.type == 'WINDOW'][0],
        raise RuntimeError("You must select a face!")
    transform_type = bpy.context.scene.transform_orientation_slots[0].type
    bpy.ops.transform.transform(mode='ALIGN', orient_type='Face', orient_matrix_type=transform_type, mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='ACTIVE', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False)
    bpy.ops.object.text_add(enter_editmode=False, align='CURSOR')
    text_object = bpy.context.active_object
    text_object.data.body = text
    text_object.data.extrude = 0.02
    bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
    bpy.context.scene.tool_settings.use_transform_data_origin = False
    text_object.rotation_euler = source_object.rotation_euler.to_matrix().to_euler()

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .