PYTHON: How to Get Sliding Text in Blender

This is Bob.

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:

No Rotation

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.

Radians ToDegrees

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.

I'm Bob

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

Hello I'm Bob

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
Advertisements
Tagged , , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: