public static fTextAreaGameObject CreateTextAreaGO( string sName, string sText, Colorf textColor, float fTextHeight, Vector2f areaDimensions, HorizontalAlignment alignment = HorizontalAlignment.Left, BoxPosition textOrigin = BoxPosition.TopLeft, float fOffsetZ = -0.01f) { GameObject textGO = new GameObject(sName); TextMeshProExt tm = textGO.AddComponent <TextMeshProExt>(); //tm.isOrthographic = false; switch (alignment) { case HorizontalAlignment.Left: tm.alignment = TextAlignmentOptions.TopLeft; break; case HorizontalAlignment.Center: tm.alignment = TextAlignmentOptions.Center; break; case HorizontalAlignment.Right: tm.alignment = TextAlignmentOptions.TopRight; break; } tm.enableWordWrapping = true; tm.autoSizeTextContainer = false; tm.fontSize = 16; tm.text = sText; tm.color = textColor; // ignore material changes when we add to GameObjectSet textGO.AddComponent <IgnoreMaterialChanges>(); textGO.AddComponent <TextMeshProAlphaMultiply>(); // use our textmesh material instead //MaterialUtil.SetTextMeshDefaultMaterial(tm); // convert TextContainerAnchor (which refers to TextContainer, that was deprecated) to // pivot point, which we will set on rectTransform Vector2f pivot = GetTextMeshProPivot(TextContainerAnchors.TopLeft); if (textOrigin != BoxPosition.TopLeft) { throw new Exception("fTextAreaGameObject: only TopLeft text origin is supported?"); } tm.rectTransform.pivot = pivot; tm.ForceMeshUpdate(); tm.fontSizeYScale = GetYScale(tm); tm.SetTextSizeFromHeight(fTextHeight); tm.SetFixedWidth(areaDimensions.x); tm.SetFixedHeight(areaDimensions.y); textGO.GetComponent <Renderer>().material.renderQueue = SceneGraphConfig.TextRendererQueue; return(new fTextAreaGameObject(textGO, new fText(tm, TextType.TextMeshPro), areaDimensions)); }
// [TODO] currently only allows for left-justified text. // Can support center/right, but the translate block needs to be rewritten // (can we generalize as target-center of 2D bbox?? public static fTextGameObject CreateTextMeshProGO( string sName, string sText, Colorf textColor, float fTextHeight, BoxPosition textOrigin = BoxPosition.Center, float fOffsetZ = -0.01f) { GameObject textGO = new GameObject(sName); TextMeshProExt tm = textGO.AddComponent <TextMeshProExt>(); //tm.isOrthographic = false; tm.alignment = TextAlignmentOptions.TopLeft; tm.enableWordWrapping = false; tm.autoSizeTextContainer = true; tm.fontSize = 16; tm.text = sText; tm.color = textColor; // ignore material changes when we add to GameObjectSet textGO.AddComponent <IgnoreMaterialChanges>(); textGO.AddComponent <TextMeshProAlphaMultiply>(); // use our textmesh material instead //MaterialUtil.SetTextMeshDefaultMaterial(tm); TextContainer container = textGO.GetComponent <TextContainer>(); container.isAutoFitting = true; container.anchorPosition = TextContainerAnchors.TopLeft; if (textOrigin == BoxPosition.Center) { container.anchorPosition = TextContainerAnchors.Middle; tm.alignment = TextAlignmentOptions.Center; } else if (textOrigin == BoxPosition.BottomLeft) { container.anchorPosition = TextContainerAnchors.BottomLeft; tm.alignment = TextAlignmentOptions.BottomLeft; } else if (textOrigin == BoxPosition.TopRight) { container.anchorPosition = TextContainerAnchors.TopRight; tm.alignment = TextAlignmentOptions.TopRight; } else if (textOrigin == BoxPosition.BottomRight) { container.anchorPosition = TextContainerAnchors.BottomRight; tm.alignment = TextAlignmentOptions.BottomRight; } else if (textOrigin == BoxPosition.CenterLeft) { container.anchorPosition = TextContainerAnchors.Left; tm.alignment = TextAlignmentOptions.Left; } else if (textOrigin == BoxPosition.CenterRight) { container.anchorPosition = TextContainerAnchors.Right; tm.alignment = TextAlignmentOptions.Right; } else if (textOrigin == BoxPosition.CenterTop) { container.anchorPosition = TextContainerAnchors.Top; tm.alignment = TextAlignmentOptions.Top; } else if (textOrigin == BoxPosition.CenterBottom) { container.anchorPosition = TextContainerAnchors.Bottom; tm.alignment = TextAlignmentOptions.Bottom; } tm.ForceMeshUpdate(); // set container width and height to just contain text AxisAlignedBox3f bounds = tm.bounds; Vector2f size = new Vector2f(bounds.Width, bounds.Height); container.width = size.x + 1; container.height = size.y + 1; // Now we want to scale text to hit our target height, but if we scale by size.y // then the scaling will vary by text height (eg "m" will get same height as "My"). // However: 1) size.y varies with tm.fontSize, but it's not clear how. // 2) fontInfo.LineHeight tells us the height we want but doesn't change w/ tm.fontSize // I tried a few values and the relationship is linear. It is in the ballpark // of just being 10x...actually closer to 11x. No other values in fontInfo have a nice // round-number relationship. But this value is probably font-dependent!! float t = tm.fontSize / tm.font.fontInfo.LineHeight; float magic_k = 10.929f; // [RMS] solve-for-x given a few different fontSize values float font_size_y = magic_k * t; tm.fontSizeYScale = 1 / font_size_y; tm.SetTextSizeFromHeight(fTextHeight); //float fScaleH = fTextHeight / font_size_y; //tm.transform.localScale = new Vector3f(fScaleH, fScaleH, fScaleH); float fTextWidth = tm.GetTextScaleForHeight(fTextHeight) * size.x; textGO.GetComponent <Renderer>().material.renderQueue = SceneGraphConfig.TextRendererQueue; return(new fTextGameObject(textGO, new fText(tm, TextType.TextMeshPro), new Vector2f(fTextWidth, fTextHeight))); }
// [TODO] currently only allows for left-justified text. // Can support center/right, but the translate block needs to be rewritten // (can we generalize as target-center of 2D bbox?? public static fTextGameObject CreateTextMeshProGO( string sName, string sText, Colorf textColor, float fTextHeight, BoxPosition textOrigin = BoxPosition.Center, float fOffsetZ = -0.01f) { GameObject textGO = new GameObject(sName); TextMeshProExt tm = textGO.AddComponent <TextMeshProExt>(); //tm.isOrthographic = false; tm.alignment = TextAlignmentOptions.TopLeft; tm.enableWordWrapping = false; tm.autoSizeTextContainer = true; tm.fontSize = 16; tm.text = sText; tm.color = textColor; // ignore material changes when we add to GameObjectSet textGO.AddComponent <IgnoreMaterialChanges>(); textGO.AddComponent <TextMeshProAlphaMultiply>(); // use our textmesh material instead //MaterialUtil.SetTextMeshDefaultMaterial(tm); // convert TextContainerAnchor (which refers to TextContainer, that was deprecated) to // pivot point, which we will set on rectTransform Vector2f pivot = GetTextMeshProPivot(TextContainerAnchors.TopLeft); if (textOrigin == BoxPosition.Center) { pivot = GetTextMeshProPivot(TextContainerAnchors.Middle); tm.alignment = TextAlignmentOptions.Center; } else if (textOrigin == BoxPosition.BottomLeft) { pivot = GetTextMeshProPivot(TextContainerAnchors.BottomLeft); tm.alignment = TextAlignmentOptions.BottomLeft; } else if (textOrigin == BoxPosition.TopRight) { pivot = GetTextMeshProPivot(TextContainerAnchors.TopRight); tm.alignment = TextAlignmentOptions.TopRight; } else if (textOrigin == BoxPosition.BottomRight) { pivot = GetTextMeshProPivot(TextContainerAnchors.BottomRight); tm.alignment = TextAlignmentOptions.BottomRight; } else if (textOrigin == BoxPosition.CenterLeft) { pivot = GetTextMeshProPivot(TextContainerAnchors.Left); tm.alignment = TextAlignmentOptions.Left; } else if (textOrigin == BoxPosition.CenterRight) { pivot = GetTextMeshProPivot(TextContainerAnchors.Right); tm.alignment = TextAlignmentOptions.Right; } else if (textOrigin == BoxPosition.CenterTop) { pivot = GetTextMeshProPivot(TextContainerAnchors.Top); tm.alignment = TextAlignmentOptions.Top; } else if (textOrigin == BoxPosition.CenterBottom) { pivot = GetTextMeshProPivot(TextContainerAnchors.Bottom); tm.alignment = TextAlignmentOptions.Bottom; } tm.rectTransform.pivot = pivot; tm.ForceMeshUpdate(); // read out bounds so we can know size (does this matter? why does fTextGO have size field?) AxisAlignedBox3f bounds = tm.bounds; Vector2f size = new Vector2f(bounds.Width, bounds.Height); tm.fontSizeYScale = GetYScale(tm); tm.SetTextSizeFromHeight(fTextHeight); float fScale = tm.GetTextScaleForHeight(fTextHeight); float fTextWidth = fScale * size.x; // set rendering queue (?) textGO.GetComponent <Renderer>().material.renderQueue = SceneGraphConfig.TextRendererQueue; fTextGameObject go = new fTextGameObject(textGO, new fText(tm, TextType.TextMeshPro), new Vector2f(fTextWidth, fTextHeight)); if (fOffsetZ != 0) { Vector3f pos = go.GetLocalPosition(); pos.z += fOffsetZ; go.SetLocalPosition(pos); } return(go); }