Hello,
Where should I go to share some code I wrote to make it possible to write hide-able text to 3D cubes through a simple attachment of a C sharp script placed on the cube? What the user can do is attach this script to any cube, and since there is no “Font.texture” property (unfortunately), you have to put the texture on a separate object and assign that object to textObj.
direction can either be “Front”, “Right”, “Back”, “Left”, “Up” or “Down” (to tell what side of the cube to put the text on). offset tells how far off the cube (away from the center) to put the text and should be a small positive number. A negative value places the text inside the cube (toward the center). message tells what message to put on the cube. fontName is where in the Resource folder your downloaded font name is. shaderName is where in the Resource folder your shader name is. matName is where in the Resource folder your font material’s name is. Do not use extensions in these 3 variables. characterSize and fontSize controls the numbers in the TextMesh of a newly created object called object_name+“_sheet”. The newly created object makes itself a child object under the cube with the script attached to it. The ‘sheet’ object is what contains the text (written on the cube). MaxWidth (by default) should always be 1, (which is 1 times the size of the cube) in THIS circumstance, so that it does perfect word wrapping within the cube…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Writing : MonoBehaviour {
public GameObject textObj;
public string direction;
public float offset = 0.001f;
public string message;
public string fontName = "Fonts/magnificent/Magnificent";
public string shaderName = "Shaders/TextOneSided";
public string matName = "Materials/Font Materials/FontMaterial";
public float characterSize = 0.01f;
public int fontSize = 1;
public Color color;
private GameObject sheetObj;
#region public members.
public float m_maxWidth = 1.0f;
public bool m_disableWhilePlaying = true;
#endregion
#region private members.
private TextMesh m_textMesh = null;
private float m_lastMaxWidth = 0.0f;
private string m_wrappedText = "";
#endregion
#region getters/setters.
public float TextWidth
{
get {
if (m_textMesh != null)
{
return m_textMesh.GetComponent<Renderer>().bounds.extents.x * 2.0f;
} else
{
return -1;
}
}
}
public float TextHeight
{
get {
if (m_textMesh != null)
{
return m_textMesh.GetComponent<Renderer>().bounds.extents.y * 2.0f;
} else
{
return -1;
}
}
}
public float MaxWidth
{
get { return m_maxWidth * 2; }
}
#endregion
#region monobehavior methods.
public void Awake()
{
if (m_textMesh == null && sheetObj != null)
{
m_textMesh = sheetObj.GetComponent<TextMesh>();
}
//bool shouldDisable = m_disableWhilePlaying && !(Application.isEditor && !Application.isPlaying);
//this.enabled = !shouldDisable;
}
public void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawRay(GetInitPosition() + transform.up * 0.05f, transform.right * TextWidth);
Gizmos.color = Color.red;
Gizmos.DrawRay(GetInitPosition(), transform.right * MaxWidth);
}
#endregion
#region private methods.
private float GetSpaceWidth()
{
float totalWidth = -1;
if (m_textMesh != null)
{
string textTemp = m_textMesh.text;
m_textMesh.text = "x x";
totalWidth = m_textMesh.GetComponent<Renderer>().bounds.extents.x * 2.0f;
totalWidth -= GetWordWidth("xx");
m_textMesh.text = textTemp;
}
return totalWidth;
}
private float GetWordWidth(string word)
{
float totalWidth = -1;
if (m_textMesh != null)
{
string textTemp = m_textMesh.text;
m_textMesh.text = word;
totalWidth = m_textMesh.GetComponent<Renderer>().bounds.extents.x * 2.0f;
m_textMesh.text = textTemp;
}
return totalWidth;
}
private Vector3 GetInitPosition()
{
if (m_textMesh == null)
{
return new Vector3(-1, -1, -1);
}
// Find X.
float x = 0.0f;
switch (m_textMesh.anchor)
{
case TextAnchor.LowerLeft:
case TextAnchor.MiddleLeft:
case TextAnchor.UpperLeft:
x = transform.position.x;
break;
case TextAnchor.LowerRight:
case TextAnchor.MiddleRight:
case TextAnchor.UpperRight:
x = transform.position.x - TextWidth;
break;
case TextAnchor.LowerCenter:
case TextAnchor.MiddleCenter:
case TextAnchor.UpperCenter:
x = transform.position.x - TextWidth / 2.0f;
break;
}
// Find Y.
float y = 0.0f;
switch (m_textMesh.anchor)
{
case TextAnchor.LowerLeft:
case TextAnchor.LowerRight:
case TextAnchor.LowerCenter:
y = transform.position.y - TextHeight / 2.0f;
break;
case TextAnchor.MiddleRight:
case TextAnchor.MiddleLeft:
case TextAnchor.MiddleCenter:
y = transform.position.y + TextHeight / 2.0f;
break;
case TextAnchor.UpperLeft:
case TextAnchor.UpperRight:
case TextAnchor.UpperCenter:
y = transform.position.y;
break;
}
GameObject g = new GameObject();
g.transform.position = new Vector3(x, y, transform.position.z);
g.transform.eulerAngles = transform.eulerAngles;
g.transform.Translate(transform.localScale.x * -0.5f, 0, transform.localScale.z * 0.5f);
Vector3 pos = g.transform.position;
Destroy(g);
return pos;
}
#endregion
// Update is called once per frame
void Update () {
Vector3 rotation = transform.eulerAngles;
transform.eulerAngles = new Vector3(0, 0, 0);
if (m_textMesh == null && sheetObj != null)
{
m_textMesh = sheetObj.GetComponent<TextMesh>();
}
GameObject obj = null;
int cnt = 0;
foreach (Transform child in transform)
{
cnt++;
}
if (cnt == 0)
{
obj = new GameObject();
obj.transform.parent = transform;
obj.name = obj.transform.parent.name + "_writing";
obj.AddComponent<MeshRenderer>();
TextMesh objMesh = obj.AddComponent<TextMesh>();
sheetObj = obj;
}
if (cnt != 0 && sheetObj == null)
{
sheetObj = transform.Find(name+"_writing").gameObject;
}
if (direction == "Front")
{
if (obj != null)
{
obj.transform.localPosition = new Vector3(0, 0, 0.5f + (offset * (1.0f / transform.localScale.y)));
}
}
if (direction == "Right")
{
if (obj != null)
{
obj.transform.localPosition = new Vector3(-0.5f - (offset * (1.0f / transform.localScale.y)), 0, 0);
}
}
if (direction == "Back")
{
if (obj != null)
{
obj.transform.localPosition = new Vector3(0, 0, -0.5f - (offset * (1.0f / transform.localScale.y)));
}
}
if (direction == "Left")
{
if (obj != null)
{
obj.transform.localPosition = new Vector3(0.5f + (offset * (1.0f / transform.localScale.y)), 0, 0);
}
}
if (direction == "Up")
{
if (obj != null)
{
obj.transform.localPosition = new Vector3(0, 0.5f + (offset * (1.0f / transform.localScale.y)), 0);
}
}
if (direction == "Down")
{
if (obj != null)
{
obj.transform.localPosition = new Vector3(0, -0.5f - (offset * (1.0f / transform.localScale.y)), 0);
}
}
if (obj != null) {
obj.transform.LookAt(transform.position);
if (direction == "Front")
{
obj.transform.localPosition = new Vector3(0.5f, 0.5f, obj.transform.localPosition.z);
}
if (direction == "Right")
{
obj.transform.localPosition = new Vector3(obj.transform.localPosition.x, 0.5f, 0.5f);
}
if (direction == "Back")
{
obj.transform.localPosition = new Vector3(-0.5f, 0.5f, obj.transform.localPosition.z);
}
if (direction == "Left")
{
obj.transform.localPosition = new Vector3(obj.transform.localPosition.x, 0.5f, -0.5f);
}
if (direction == "Up")
{
obj.transform.localPosition = new Vector3(-0.5f, obj.transform.localPosition.y, 0.5f);
}
if (direction == "Down")
{
obj.transform.localPosition = new Vector3(-0.5f, obj.transform.localPosition.y, -0.5f);
}
obj.transform.localScale = new Vector3(1, 1, 0.0001f);
//obj.transform.Translate(-new Vector3(0.5f, -0.5f, 0));
Material mat = Resources.Load(matName) as Material;
mat.SetColor("_Color", color);
mat.shader = Resources.Load(shaderName) as Shader;
Font font = Resources.Load(fontName) as Font;
mat.SetTexture("_MainTex", textObj.GetComponent<MeshRenderer>().material.GetTexture("_MainTex"));
obj.GetComponent<TextMesh>().font = font;
obj.GetComponent<TextMesh>().text = message;
obj.GetComponent<TextMesh>().color = color;
obj.GetComponent<TextMesh>().characterSize = characterSize;
obj.GetComponent<TextMesh>().fontSize = fontSize;
obj.GetComponent<MeshRenderer>().material = mat;
}
if (sheetObj != null)
{
sheetObj.GetComponent<TextMesh>().characterSize = characterSize;
sheetObj.GetComponent<TextMesh>().fontSize = fontSize;
sheetObj.GetComponent<TextMesh>().text = message;
}
if (m_textMesh != null && (m_textMesh.text != m_wrappedText || MaxWidth != m_lastMaxWidth))
{
float widthSum = 0.0f;
m_wrappedText = "";
string line = "";
char[] separators = new char[] { ' ', '\n', '\t' };
string[] words = message.Split(separators);
for (int i = 0; i < words.Length; i++)
{
string word = words[i].Trim();
if (i == 0)
{
line = word;
widthSum = GetWordWidth(word);
}
else
{
// Concatenate the new word if there is still enough space.
if (widthSum + GetWordWidth(word) <= MaxWidth)
{
if (widthSum > 0.0f)
{
line += ' ';
widthSum += GetSpaceWidth();
}
line += word;
widthSum += GetWordWidth(word);
}
// New line.
else
{
if (m_wrappedText.Length > 0)
m_wrappedText += '\n';
m_wrappedText += line;
line = word;
widthSum = GetWordWidth(word);
}
}
}
if (widthSum > 0.0f)
{
if (m_wrappedText.Length > 0)
m_wrappedText += '\n';
m_wrappedText += line;
}
m_textMesh.text = m_wrappedText;
m_lastMaxWidth = MaxWidth;
}
transform.eulerAngles = rotation;
}
}