Notifications
Clear all

[Closed] Text property not updating on rendering

I’m trying to get the text property of a text object to update when rendering but no luck on that.

I needed to animate numbers like a progress bar, so I used a script controller on a sphere object to change the text property of the text, but no matter what I do I can’t get the text to update when rendering. I tried many workarounds already…none worked…

What I need to do exactly? What would you guys do?

Any info is really appreciated…

Regards,

Jr.

6 Replies

MAXScript Reference > MAXScript FAQ > How do I change the text in a Text Shape dynamically?

Since the Help still uses an old example from pre-new scripted controller days, here is the updated version with custom variables instead of DependsOn (althrough both work and do about the same, this version is the way it should be done in Max 8, 9, 2008 and 2009).

b=box name:"ControlBox" wirecolor:blue
 t=text name:"ControlledText" wirecolor:red
 t.baseobject.renderable=true
 theCtrl = float_script()
 theCtrl.addNode "TheText" t
 theCtrl.addNode "TheBox" b
 theCtrl.SetExpression "TheText.text = TheBox.height as string
0" 
 t.kerning.controller=theCtrl
 animate on at time 100 b.height*=2 
--addModifier t (Mesh_Select()) --optional, if you want solid text instead of outline
 max tool zoomextents all 
 playAnimation()

Oh, never thought the answer was in max help. And many many thanks for the fast answer man! I’m in such a rush here and it was a real life saver.

What I was doing wrong was to not control the text property from an animatable property of the text itself. I kind of understand why but not completely yet. Why, say in an X_Position of a sphere for example, if I place a script controller that does something, and manipulate the text object from there? The script of the X_Position was updating at rendertime, but not the text…

Thanks once again Bobo…

Regards,

Jr.

Max has a concept of so-called Validity Intervals. A Validity Interval defines the time range in which an object is valid, in other words does not require an update. This is done for both viewports and rendering to speed things up. 

This has some severe implications when creating animation rigs though. 

When Max 1.0 was developed, there was no MAXScript so it was technically impossible to change the text property over time during rendering. So the Text Shape has by default a validity interval of "forever". When the renderer goes through all scene objects and asks them for their validity, the text shape is seen as "valid on any frame" and is updated just once, on the first frame of the segment to be rendered. Then it is cached and reused without ever updating again. If you would call render() once per frame in a loop though, the shape would update once for each render() call.

But if some text shape parameter is animated, it will cause the validity interval to return just the current frame as valid, and as the renderer advances through the frames to render, it will be forced to update the text shape stack again and again.

If you place a Script controller in a track of a Sphere and try to change the text at render time, the text property would be set by the script, but the renderer would still assume the text cannot possibly have changed because that's how the Text Shape was originally designed - the Text is NOT stored in an animation track and there is no dependency created between the Sphere and the Text that would break the Validity Interval of Forever to cause the shape to reevaluate on each rendered frame.

In other words, the Text Shape must tell the renderer that it is going to change from frame to frame for the renderer to evaluate it that way. Since the kerning property changes the final output of the Text Shape, it is a good place to put the script. Even though we return a constant value of 0 for the kerning itself, the renderer sees a script controller (which is sort of procedural and nobody can make any predictions what the return result might be on any frame), so it assumes the result will be different on each frame and handles it that way.

This is also the reason why placing script controllers in Helper objects can sometimes not work as expected - a Helper will only be evaluated by the renderer if some renderable object depends on its transformations! The Helper itself is not renderable and the renderer would completely ignore it unless some geometry or light or camera or spacewarp is linked to the helper, making the helper indirectly influence the rendered image...

Hope this helps.

Thanks for this extended explanation, Bobo. There’s nowhere else to get this kind of ground-up explanation of the app (unless I’m wrong?).

I often find that lack frustrating, since it’s the way I happen to learn things, and time-consuming in trial and error. So it’s great when this forum, and you in particular, come up with under-the-hood descriptions like this one.

Bobo, thank you very much for such explanation!

It’s amazing how your posts are always filled with lots of deep, very important and rare informations, the ones that you can’t find anywhere else. I can say I have a pretty good knowledge of how max works so far, and a lot of that is thanks to you and posts like this.

Regards,

Jr.