Modular 3D text


How to use

1.Right click in scene hierarchy, 3D Objects > Modular 3D Text > Anything

Important Note

All scripts are in namespace MText. So, don’t forget to add using MText on top of the script when referencing scripts on this asset.

There is a asset window in Tools menu where you can set default settings & have the option to apply them to all items in the scene.

Asset Window
Editor window options (6th June,2020)

Remember to save mesh as an asset on prefabs if you want the mesh to persist between instances of that prefab and not just the settings. The option is moved to advance settings if it isn’t a prefab.

No longer necessary after version 1.6.6

Performance Suggestions

  • Simply call UpdateText(“your string”);to update text. Auto create in play-mode checks for changes in Update(). It is better for performance to avoid unnecessary stuff in Update(). This setting can be found under advanced setting.

  • Turn on pooling if a lot of text is changed in play mode. This option is under advanced settings.

  • For best performance on texts that won’t be changed, combine the mesh, click “Optimize mesh” button found in advanced settings and remove the modular3DText script.

Assembly Definition

Put one in scripts and another in Editor folder.

Didn't include them because some users aren't used to them and it takes less than a minute to create for people who want them.

Asset Cleanup

This section is for people that want to clean up their project.

Example usage like the typewriter effect, countdown is separated to the Examples folder. This doesn't include the scripts. The scripts are inside Scripts/Examples folder. If you want to delete the examples, delete both examples folder.

You can delete the entire Sample Scene folder. This doesn't include the scripts. The scripts are inside Scripts/Sample Scene folder. If you want to delete them, delete both sample scene folder.

You can delete the Prefabs folder too. The asset will work just fine without those. They were only added because someone asked.

Materials folder is also unnecessary for the asset. Just assign your default own materials in Tools > Tiny Giant Studios > Modular 3D Text.


Press the Add New Module button to add modules and ‘x’ button besides a module to delete it.

  • Effects will only apply in play mode & if the text object is active/enabled.

  • Combined mesh can’t have effects. If you have a combined mesh in editor, in play mode after the first call to create text it will recreate the old texts as separate objects along with effect. Select don’t combine in the editor to avoid this. This option is found under Advanced settings in the inspector.

  • When pooling is turned on If you use “Add Gravity”/”Add rigidbody” in typing effects, use “Remove Gravity”/”Remove rigidbody” on deleting effects. This makes sure objects don’t have pre-added components when reusing them through the pool. When using custom modules that add components, use a module to remove that component to be suitable with pooling.

  • There are more settings in the Modules itself. Check them out. Example: You can add a bouncy physics material in the rigidbody module, a curve to choose how the scale change will happen.

Module Creation

Modules are scriptable objects.

To create a module, create a script like the example below, create an item for that module and assign the module in text to use.

Yes, you can create multiple modules with different parameters from a single script.

Modules can’t be run from disabled text object.

Example module script

using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MText { [CreateAssetMenu(menuName = "Modular 3d Text/Modules/Your effect name goes here")] public class YourFileNameGoesHere : MText_Effect { public override IEnumerator ModuleRoutine(GameObject obj, float duration) { //enter your code here yield return null; } } }

Here, obj is the Gameobject of the character being typed and duration is passed from the individual Text.

After creating the script, right click in the project window, click “Create > Modular 3d Text > Modules > Your effect name goes here”.

3D UI System

One object with MText_UI_RaycastSelector script attached needs to be in the scene to select items with mouse/touch. You can disable it when not using a 3D UI. This is automatically added when you create a 3d UI item (except plain text).

If no camera is selected for MText_UI_RaycastSelector, Camera.Main is used to assign camera in Start(); If you delete camera, assign the appropriate camera for this to work properly.



  • The helper component updates the list automatically in Editor. In play-mode/build you need use UpdateList() method to do it manually. This is to improve performance.

  • All 8 types of lists are included in one component. Just pick one and you are ready to go.

  • Lock rotation freezes list item’s rotations to zero.

  • Don’t forget to turn on the keyboard control.

  • You can turn on/off each individual component

  • You can turn on/off each individual component

  • Ignore child toggle turns on/off child button modules to be used or not

  • While being clicked - calls the module over and over again while mouse is clicked


  • While Being Clicked Events/Modules continuously calls those events while mouse click is held down on it. This is called in Update(), which is every frame.

  • onSelectEvent is mouse hover or selected in a list. onUnselectEvent is the opposite

  • To disable button via code, set interactable = false; and call method DisabledButtonVisualUpdate();

  • Remember, the size of the Box-collider on the component itself determines if you are hovering/clicking on it, not the background size.


  • Toggle relies on Button to call Toggle() which is automatically added when creating toggle

  • Use the Set(bool) method to directly set the toggle instead of switching using Toggle()

3D Input Field

  • Auto focus focuses the input on game start. Focused = you can type in

  • Interactable includes touch/mouse both.

  • Difference between Select() and Focus() is select checks if the input field is in a list.

3D Slider

  • UpdateValue(int newValue)/ UpdateValue(float newValue) use these to update slider via code

Creating fonts

In Editor

(Video Tutorial:

‌[Supports only TTF file formats. Most fonts found online are in TTF format] Note: the asset doesn't support right to left/top to down languages yet

1. Go to Tools > Tiny Giant Studios > Modular 3D Text

‌2. Select Font Creation Tab and click Create Font

3. Select your font file from anywhere in the computer‌

4. Give a few seconds to process and then select location inside your project where your mesh/font will be saved.‌

5. Right click in the project window, Create > Modular 3d Text>New font.

6. Assign exported FBX file to the font. Click the create/recreate button.

Your font is ready to be used.

Remember, the ttf font must have the characters in the first place to create 3D version.

There is a limit of how many meshes unity can handle per asset. Although the limit is pretty high, it gets slow in editor when you select that object after about a thousand mesh. If you need more characters, I suggest separating them into smaller chunks and having them set as Fallback fonts.

For different Languages

(Video tutorial:

‌Before creating the font, Click the Get Character List Button which will take you to In character range, for your language, from the link , enter the first character and the last character. This will make the created font include every character inbetween them. Then, Click create font.

Using blender

(Video tutorial :

  1. Install blender if you don’t have it already.

  2. Open the font extractor folder inside the modular 3d text folder. (Unzip it)

  3. Open the blender file.

  4. Click run script.

  5. Select extract font from the left toolbar

  6. Select your font.

  7. Do any changes you want in this step, like retopology, optimization (Check for optimization tips below) according to your needs. Or just skip this step if you want.

  8. File>Export>Export as FBX to your project. Default export settings are fine.

  9. In unity, right click in the project window, Create > Modular 3d Text>New font.

  10. Assign exported FBX file to the font. Click the create/recreate button.

  11. Font is ready to use.


(To people who are knowledgeable about optimization, do your own thing. This is just a fast and simple way to do things, not perfect.) The font created in blender is not optimized. Didn't include auto-optimization in blender script because some fonts have very different geometry than expected from an average font which would result in losing details or not enough optimization. To reduce vertices. A fast but not the best way to optimize it would be,

  1. Select all objects (Press A in scene view).

  2. Press Tab to enter edit mode. (If you can't enter edit, select and deselect an object by left clicking one and then, an empty area, Select everything again (Press A) then Press Tab to enter edit mode)

  3. Go to the Mesh menu (on the top menus on view window)

  4. Cleanup > Limited Dissolve.

  5. Cleanup > Remove doubles.

This can reduce a lot of unnecessary vertex but sometimes result in few characters having strange geometry. You can Undo & deselect the objects with problematic geometry. If the font looks good enough, export and use.

Manual Slow way:

  • In unity, right click in the project window, Create>Modular 3d Text>New Font.

  • In the list you see after selecting the font, add a new item. Assign any object you want to that item and type a character for it besides it. Now when you type the character in, that object is used.

Fix positioning + Rotation + scaling for the font. You can fix it for all the characters at once by specifying it in the font file and + or you can assign a parent to the object, add “MText_Character.cs” component to the parent and fix transform for each character individually. That script shows the default expected scale and size.

Note that : The fonts use individual width to determine spacing, not kerning. Kerning requires too much processing power for 3D texts without the original fonts as reference. For something that was built for runtime, it isn't practical.

Currently working on a workaround. But some features like modules won't work with that. It will be an alternative script for people needing pixel perfect texts.

About the included examples

Speed and volume’s x and y value are the minimum and maximum value. Keep them the same if you don’t like them to fluctuate. A little randomization makes them feel natural.

StatusToolTip script: You can use one for the entire scene. The pool for it is separate from Text. Example usage: Status debuff/buff in RPG, damage UI Just call the method ShowToolTip()

Script references

All scripts are in namespace MText. So, don’t forget to add using MText on top of the script when referencing scripts on this asset.










Updates 3d text if any changes was made. This includes text, formatting and materials.

UpdateText(string newText)

UpdateText(int value)

UpdateText(float value)


Updates 3d text with new text



Automatically checks for changes and updates text runtime if turned on. Autocreate in playmode is better suited for cases like scoreboard where a value might be changing a LOT of time in a frame and instead of each change of score calling to change text multiple times in a frame, autocreate changes it every frame.



Automatically checks for changes and updates text in Editor if turned on



Enables/Disables the usage of pooling

EmptyEffect(List <effect> effectList)


To add new effects runtime, Call this method and pass it typingEffects or deletingEffects. This will create a new empty effect slot. Assign a Module and duration to it.

alignCenter, alignLeft, alignRight


Horizontal Alignment. Only one may be set to True to work correctly

alignMiddle, alignTop, alignBottom


Horizontal Alignment. Only one may be set to True to work correctly



Where the prefab is saved.

Is only used when prefab connection is broken via break prefab connection button in Advanced Settings to store the path to be used by reconnect prefab button



Resets button settings from Settings file

Modifiable attributes via script: material, characterSpacingInput for character spacing, lineSpacingInput for line spacing, height, length





RetrievePrefab(char c)


Returns prefab of the character. Returns null if nothing found



Mono space fonts are fonts with equal distance to each character. For example, the character ‘I’ will occupy same space as ‘A’.

Spacing(char c)


Returns the area (spacing) a character will occupy in non-mono spaced font.


List of


Each MText_Character has a character, prefab and spacing information



True = all characters are equal distance to each other



How large of an area should empty space be taking


If nothing is selected, the selectedItem int will return the size of the list or 0.






Repositions list items

Focus(bool enable)


Makes list active or deactive to keyboard controls.

Enabling focus has a one frame delay.This is to avoid pressing “Enter” in one list, enabling another list which also takes the “Enter” input and presses it’s button

Focus(bool enable, bool delay)


Makes list active or deactive to keyboard controls without delay if second parameter is set to false.

SelectItem (int i)


Selects i number child

UnSelectSpecific (MText_UI_Button button)


Unselects button graphic

UnselectEverything ()


Unselects everything






Input field string

Focus(bool enable)


Enables/Disables input. Enabling has a one frame delay

Focus(bool enable, bool delay)


Enables/Disables input. Enabling delay depends on second parameter.



Background. That’s all Folks!



Material assigned to background when input is active


Unity Event

Events are called when a new character is added,


Unity Event

Events are called when a character is removed


Unity Event

Called when input is complete. Dictated by Enter key



Completes input, invokes oninputEnd



Will touch/click enable it or selectable in a list



The text object for this input





Sets the visual style



Disables interaction



Enables interaction

UpdateText(), UpdateText(string), UpdateText(int), UpdateText(float)


Updates Text







Presses the button



Selects the button






Applies style to graphic only. No function change.



Disables interaction



Enables interaction



Resets button settings from Settings file

Some modifiable properties like normalBackgroundMaterial, pressedBackgroundMaterial, selectedBackgroundMaterial etc.





Set (bool)


Specificly set the toggle

Toggle ()


Toggles the toggle




Applies just the style

Toggle is controlled by button. Set button‘s interactable property to control toggle





Focus(bool enable)


Enables/Disables slider to mouse/touch control

UpdateValue(int newValue)

UpdateValue(float newValue)


Use it to update slider value






Updates the visual of the slider



Disables interaction



Enables interaction


(from examples)




ShowToolTip(string text, int style, Vector3 position, Quaternion rotation, bool worldPosition)


Shows tooltip -.-

ShowToolTip (string text, int style, Vector3 position, Quaternion rotation, bool worldPosition, float duration)


Shows tooltip

Note: Nothing in the MText.FontCreation namespace is meant to be used by anything other than what it does already. The code is quiet messy and hard to provide support for since I am not very knowledgeable about mesh genaration. So, wrapping it in a DLL. Will slowly organize stuff and move some pieces of them out of DLL one by one later. if I have the time. (Low priority). Update to 1.4.2: moved most code out of DLL. (mesh+obj exporter, different helper scripts) Just triangulation script is in DLL.

API Change-list

[This is not asset version change list. It is just api change. New/changed coding spaghetti]

From 1.5.01 to 1.5.03 (not live yet)

  1. Modular 3D Text: NewEffect(the list to add module to, new module); method ClearAllEffects();

  2. StatusToolTip script replaces DamageText script to be used in a real scenerio instead of just as a sample

From 1.4.01 to 1.4.02

  1. Few more scripts are out of DLL.

  2. In-editor font creator can export font as mesh instead of OBJ too and the scripts are out of DLL. They aren't really useful for anything outside of font creation. Not putting them in Scripting references to avoid clutter.

From 1.4.0 to 1.4.01

  1. Slider Value range events have been added

  2. Text has new bool activateChildObjects. This creates child characters as inactive.

From 1.3.23 to 1.4.0

  1. bool useUpperCaseLettersIfLowerCaseIsMissing added to Font class. Does what it says.

  2. Nothing in the MText.FontCreation namespace is meant to be used by anything other than what it does already. The code is quiet messy and hard to provide support for. So, wrapping it in a DLL. Will slowly organize stuff and move out of DLL one by one.

From 1.3.22 to 1.3.23

  1. Slider & Input string visual update methods now take style options from List just like buttons

  2. PressButtonDontCallList() is a new method to press a button without calling the parent list. Primarily used by List itself to avoid recursive calls by PressButton()

  3. InputField now has public UpdateText(), UpdateText(string), UpdateText(int), UpdateText(float)

  4. Modular3DText.cs && MText_UI_Button now has a LoadDefaultSettings() method that does what it says.

From 1.6.3 to 1.6.5

  1. UpdateText() now updates the text no matter what. Use UpdateTextWithCheck() if you want to update if change is made to the tracked properties.