I am creating some physics animations in Blender and looking for a way to create subscript characters in text objects (for all the indices). The only way I figured out is to place two separate Text Objects close to each other, but that's rather uncomfortable as soon as they get animated, edited, moved around etc.

Is there any better way?


method 1

The answer here shows how to add extended unicode characters to the body of a Text Object

For the subscript digits it's this range.

import bpy

obj = bpy.data.objects['Text']

start_char = ord(u'\u2080')
end_char = ord(u'\u2089') + 1
subscript = ''.join([chr(i) for i in range(start_char, end_char)])
obj.data.body = 'Regular' + subscript

enter image description here

The above image uses a font called "Junicode". Support for the sub/super script characters depends on the font you pick. Blender's default font (Bfont) has limited extended characters. You can find many good unicode TrueType fonts with extensive extended character sets.

For more superscript and subscript unicode sequences see the tables here:
Unicode subscript and superscript block

method 2

Add a Driver to the offset_x parameter of the superscript text object, to tell it to update its value based on the obj.dimensions[0] component of the regular script text Object.

You'll have to enable Auto Run Python Scripts from UserPreferences > File

enter image description here

You tweak the superscript size an offset_y to look right, and you might also include some default spacing between the regular script and superscript, here I added 0.1 to the width of the regular script to avoid getting too cramped.

Reasons not to use parenting or drivers

In quality typefaces (fonts) a lot of effort is put into the spacing between letters to make all letter combinations look as good as possible. Adjacent letters should never be too close or too far apart. Find a good font where this is implemented and you'll save yourself a lot of work.

Valid reason to use parent or drivers

If you need superscript and subscript at the same time. Blender isn't a dedicated typesetting tool for notation like LaTeX, and provides no convenient syntax for it. The suggested work-arounds might be sufficient.

| improve this answer | |

enter image description here Method 01

Parent your superscript and subscript to the regular size text. Then animate the parent.

Select in this order Text2 (Superscript), then Text3 (Subscript) then Text1 (ValueName)

Keystroke [Control P] Parent. Menu Appears.

Of course you might combine the Superscript and Subscript into one text object with a carriage return if that suits you.

Method 02

Consider creating your text in some other program such as Gimp or free equation editor or free document editors. Saving them as in image. UV Map a plane and apply image as texture.

Assuming you are not emphasizing 3D Text. No extrusion for example.

Otherwise you might consider using the same image as a displacement texture.

| improve this answer | |

Starting from the idea of @Zeffii, you can use this script to determine the substripts and the superscripts too.

enter image description here

  1. Select the text object
  2. In the Properties Panel set 'Junicode' for Normal, Bold and Italic Font
  3. In Edit Mode, set the character Style (in the Tool Shelf T): BOLD for SUBSCRIPTS, ITALIC for SUPERSCRIPTS
  4. Run the script


import bpy

text = bpy.context.active_object
l = len(text.data.body)

def changeScripts(code, sub = True):
        inc = 8272
        inc = 8256
    result = code + inc

    # special cases:
    # 1 superscript
    if result == 8305:
        result = 185
    # 2 superscript
    elif result == 8306:
        result = 178
    # 3 superscript
    elif result == 8307:
        result = 179
    return result

def applyChanges():
    newBody = ''
    for i in range(0,l):
        char_format = text.data.body_format[i]
        char = text.data.body[i]  
        code = ord(char)
        #BOLD -> SUBSCRIPTS    
        if char_format.use_bold:
            code = changeScripts(code, True)
        elif char_format.use_italic:
            code = changeScripts(code, False)
        newBody += chr(code)
    text.data.body = newBody

| improve this answer | |

For subscript, you can always use "small caps" in the font tab (when editing). See the pic for an example.

Note that:

  • it does only caps, with respective scale
  • it works in edit mode in a limited way: you check small caps and then type, you cannot select a part and apply small caps. So it works if you type while it's on. (there are script workarounds)

enter image description here

There are also script/addon ways to do this, using same, with a bit more freedom, like changing such property after, not in edit mode, or like using a certain rule to automate such formatting.

If you need such, say so, to complete my answer with those. (They are probably worth only if you have lots of texts or if you need an automation of sorts. )

| improve this answer | |
  • $\begingroup$ nice solution, here's a script for that: gist.github.com/zeffii/9864fa22e8148c3b9e2b $\endgroup$ – zeffii Jan 28 '16 at 8:44
  • $\begingroup$ thanks :) precisely cause you cannot later select and apply such (edit mode is weird here) I made this github.com/JacquesLucke/animation_nodes/blob/master/nodes/text/… where you can also "select" (slice) the part you wanna change. That is why I said "if u need automation etc, say so". But probably, as the question goes, manual mode will suffice. $\endgroup$ – o.g. Jan 28 '16 at 9:45
  • $\begingroup$ yes, plenty of valid solutions $\endgroup$ – zeffii Jan 28 '16 at 10:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.