2D Toolkit Forum
2D Toolkit => Support => Topic started by: narenskiDev on March 28, 2015, 09:00:19 am
-
Hi,
I'm trying to get world position of each character on tk2dTextmesh, in order to create one textmesh per character.
I have tried with GetEstimatedMeshBoundsForString, but i have this of reasuts(see the picture).
Have you any idea in order to do it ?
-
It will probably be easier to write a function to write out / modify the code to save the local position of each character as it creates it. tk2dTextMeshGeomGen SetTextMeshGeom is the function that fills the geometry buffer. You could modify that to save the position of each char
-
Hi,
I'm still a newbie in Unity3d, and i don't understand where the pos of the character are.
There's a vector3 of pos. But there's 4 positions stored for each character.
Have you any idea how retrieve the pos of each character ?
Thank you.
public static int SetTextMeshGeom(Vector3[] pos, Vector2[] uv, Vector2[] uv2, Color32[] color, int offset, GeomData geomData)
{
tk2dTextMeshData data = geomData.textMeshData;
tk2dFontData fontInst = geomData.fontInst;
string formattedText = geomData.formattedText;
meshTopColor = new Color32(255, 255, 255, 255);
meshBottomColor = new Color32(255, 255, 255, 255);
meshGradientTexU = (float)data.textureGradient / (float)((fontInst.gradientCount > 0) ? fontInst.gradientCount : 1);
curGradientCount = fontInst.gradientCount;
Vector2 dims = GetMeshDimensionsForString(geomData.formattedText, geomData);
float offsetY = GetYAnchorForHeight(dims.y, geomData);
float cursorX = 0.0f;
float cursorY = 0.0f;
int target = 0;
int alignStartTarget = 0;
for (int i = 0; i < formattedText.Length && target < data.maxChars; ++i)
{
int idx = formattedText;
tk2dFontChar chr;
bool inlineHatChar = (idx == '^');
if (fontInst.useDictionary)
{
if (!fontInst.charDict.ContainsKey(idx)) idx = 0;
chr = fontInst.charDict[idx];
}
else
{
if (idx >= fontInst.chars.Length) idx = 0; // should be space
chr = fontInst.chars[idx];
}
if (inlineHatChar) idx = '^';
if (idx == '\n')
{
float lineWidth = cursorX;
int alignEndTarget = target; // this is one after the last filled character
if (alignStartTarget != target)
{
float xOffset = GetXAnchorForWidth(lineWidth, geomData);
PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
}
alignStartTarget = target;
cursorX = 0.0f;
cursorY -= (fontInst.lineHeight + data.lineSpacing) * data.scale.y;
continue;
}
else if (data.inlineStyling)
{
if (idx == '^')
{
if (i + 1 < formattedText.Length && formattedText[i + 1] == '^') {
++i;
} else {
i += HandleStyleCommand(formattedText.Substring(i + 1));
continue;
}
}
}
pos[offset + target * 4 + 0] = new Vector3(cursorX + chr.p0.x * data.scale.x, offsetY + cursorY + chr.p0.y * data.scale.y, 0);
pos[offset + target * 4 + 1] = new Vector3(cursorX + chr.p1.x * data.scale.x, offsetY + cursorY + chr.p0.y * data.scale.y, 0);
pos[offset + target * 4 + 2] = new Vector3(cursorX + chr.p0.x * data.scale.x, offsetY + cursorY + chr.p1.y * data.scale.y, 0);
pos[offset + target * 4 + 3] = new Vector3(cursorX + chr.p1.x * data.scale.x, offsetY + cursorY + chr.p1.y * data.scale.y, 0);
if (chr.flipped)
{
uv[offset + target * 4 + 0] = new Vector2(chr.uv1.x, chr.uv1.y);
uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
uv[offset + target * 4 + 3] = new Vector2(chr.uv0.x, chr.uv0.y);
}
else
{
uv[offset + target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
uv[offset + target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);
}
if (fontInst.textureGradients)
{
uv2[offset + target * 4 + 0] = chr.gradientUv[0] + new Vector2(meshGradientTexU, 0);
uv2[offset + target * 4 + 1] = chr.gradientUv[1] + new Vector2(meshGradientTexU, 0);
uv2[offset + target * 4 + 2] = chr.gradientUv[2] + new Vector2(meshGradientTexU, 0);
uv2[offset + target * 4 + 3] = chr.gradientUv[3] + new Vector2(meshGradientTexU, 0);
}
if (fontInst.isPacked)
{
Color32 c = channelSelectColors[chr.channel];
color[offset + target * 4 + 0] = c;
color[offset + target * 4 + 1] = c;
color[offset + target * 4 + 2] = c;
color[offset + target * 4 + 3] = c;
}
else {
color[offset + target * 4 + 0] = meshTopColor;
color[offset + target * 4 + 1] = meshTopColor;
color[offset + target * 4 + 2] = meshBottomColor;
color[offset + target * 4 + 3] = meshBottomColor;
}
cursorX += (chr.advance + data.spacing) * data.scale.x;
if (data.kerning && i < formattedText.Length - 1)
{
foreach (var k in fontInst.kerning)
{
if (k.c0 == formattedText && k.c1 == formattedText[i+1])
{
cursorX += k.amount * data.scale.x;
break;
}
}
}
++target;
}
if (alignStartTarget != target)
{
float lineWidth = cursorX;
int alignEndTarget = target;
float xOffset = GetXAnchorForWidth(lineWidth, geomData);
PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
}
for (int i = target; i < data.maxChars; ++i)
{
pos[offset + i * 4 + 0] = pos[offset + i * 4 + 1] = pos[offset + i * 4 + 2] = pos[offset + i * 4 + 3] = Vector3.zero;
uv[offset + i * 4 + 0] = uv[offset + i * 4 + 1] = uv[offset + i * 4 + 2] = uv[offset + i * 4 + 3] = Vector2.zero;
if (fontInst.textureGradients)
{
uv2[offset + i * 4 + 0] = uv2[offset + i * 4 + 1] = uv2[offset + i * 4 + 2] = uv2[offset + i * 4 + 3] = Vector2.zero;
}
if (!fontInst.isPacked)
{
color[offset + i * 4 + 0] = color[offset + i * 4 + 1] = meshTopColor;
color[offset + i * 4 + 2] = color[offset + i * 4 + 3] = meshBottomColor;
}
else
{
color[offset + i * 4 + 0] = color[offset + i * 4 + 1] = color[offset + i * 4 + 2] = color[offset + i * 4 + 3] = Color.clear;
}
}
return target;
}
-
cursorX, CursorY + offsetY is the position of each character.
The line -
pos[offset + target * 4 + 0]
is adding the geometry for the character, so you could save it just before it does it.