This is Bob. Bob is a gelatinous organism from outer space. He’s also a bit of a diva, so he requires that he be announced by text that drifts upwards in a graceful and organized fashion.
So that’s how I spent the first chunk of my long weekend—figuring out text objects in Blender. For the sliding script, just scroll to the bottom. For more description, keep reading below.
The line to add a text object to a Blender scene is:
bpy.ops.object.text_add()
You can change up the text by putting the text object into a variable and then plugging a string into data.body.
ob=bpy.context.object ob.data.body = "Test Text"
That’ll get you here:
Within that, there are location and rotation parameters that come in quite handy. Just remember that the rotation parameter operates in radians, not degrees. 90 degrees is approximately 1.57 radians. Here’s how that looks in Blender’s Top View.
Now, part of my frustration with Blender text is that you can’t manipulate the individual letters within the text object separately. Whatever you do to the text—it’ll change up the entire word or phrase in that object.
UNLESS. You use a Python script to write the individual letters into their own objects.
How Do You Do That?
Well, first off, we have to hack up the string into individual characters. An easy way to do that is to use list() to convert the string into a list that can be looped through.
import bpy string = "HELLO. I'M BOB." sl = list(string) x=0 tx=0 while x < len(sl): bpy.ops.object.text_add(location=(tx,0,0), rotation=(0, 0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .75 x+=1
The problem with this script is that the characters themselves are different sizes, so evenly spacing them looks off.
How Do You Fix It?
Well, one idea is you can customize the space between lettering depending on which letter is being populated, using elif() clauses. Like so.
import bpy string = "HELLO. I AM BOB." sl = list(string) x=0 tx=0 while x < len(sl): if (sl[x] == " ") or (sl[x] == "'") or (sl[x] == ","): bpy.ops.object.text_add(location=(tx,0,0), rotation=(0,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .25 x+=1 elif (sl[x] == "E") or (sl[x] == "B") or (sl[x] == "I") or (sl[x] =="L"): bpy.ops.object.text_add(location=(tx,0,0), rotation=(0,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .55 x+=1 elif (sl[x] == "A"): bpy.ops.object.text_add(location=(tx,0,0), rotation=(0,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .65 x+=1 else: bpy.ops.object.text_add(location=(tx,0,0), rotation=(0,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .75 x+=1
Better, right?
What’s the use in this again?
Now you can animate the letters independently by popping keyframes in at the end of each if clause. The variable f below controls how quickly the letters arrive—the smaller the number, the quicker the text moves. Note that the script below has the text rotated 90 degrees along the X axis to line up with Bob.
import bpy string = "HELLO. I AM BOB." sl = list(string) x=0 tx=0 f=3 while x < len(sl): if (sl[x] == " ") or (sl[x] == "'") or (sl[x] == ","): bpy.ops.object.text_add(location=(tx,0,-5), rotation=(1.57,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .25 x+=1 ob.keyframe_insert(data_path="location",frame=0) ob.location.z = 0 ob.keyframe_insert(data_path="location",frame=f) f+=3 elif (sl[x] == "E") or (sl[x] == "B") or (sl[x] == "I") or (sl[x] =="L"): bpy.ops.object.text_add(location=(tx,0,-5), rotation=(1.57,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .55 x+=1 ob.keyframe_insert(data_path="location",frame=0) ob.location.z = 0 ob.keyframe_insert(data_path="location",frame=f) f+=3 elif (sl[x] == "A"): bpy.ops.object.text_add(location=(tx,0,-5), rotation=(1.57,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .65 x+=1 ob.keyframe_insert(data_path="location",frame=0) ob.location.z = 0 ob.keyframe_insert(data_path="location",frame=f) f+=3 else: bpy.ops.object.text_add(location=(tx,0,-5), rotation=(1.57,0,0)) ob=bpy.context.object ob.data.body = sl[x] tx += .75 x+=1 ob.keyframe_insert(data_path="location",frame=0) ob.location.z = 0 ob.keyframe_insert(data_path="location",frame=f) f+=3
Well done tutorial. Thx man.
LikeLiked by 1 person