hi All... me once more Trying to find a workaround to reading the Font materials Texture, so i can use it to draw each of the texture Characters to my own Texture2D... Code (csharp): public static void DrawText(this Texture2D tx, string sText, Font myFont ) { CharacterInfo ci; char[] cText = sText.ToCharArray(); Material fontMat = myFont.material; Texture2D fontTx = (Texture2D) fontMat.mainTexture; int x, y, w, h; int posX = 10; for( int i = 0; i < cText.Length; i++ ) { myFont.GetCharacterInfo( cText[i], out ci, 32 ); x = (int) ((float) fontTx.width * ci.uv.x); y = (int) ((float) fontTx.height * (ci.uv.y + ci.uv.height)); w = (int) ((float) fontTx.width * ci.uv.width); h = (int) ((float) fontTx.height * (-ci.uv.height)); Color[] cChar = fontTx.GetPixels( x, y, w, h ); tx.SetPixels( posX, 10, w, h, cChar ); posX += (int) ci.width; } } And calling it... Code (csharp): ... public Font myFont; void Start () { int texSize = 256; Texture2D tex = new Texture2D(texSize, texSize, TextureFormat.ARGB32, false, true); tex.alphaIsTransparency = true; tex.DrawText( "Hello World!", myFont); tex.Apply(); renderer.material.mainTexture = tex; } ... but i keep getting this Error: i dont think i can change it from the Inspector: So.... is there a workaround? note: I would really like to be able to use the Font Texture that Unity generates.... ...But i'm open to suggestions. thanks all, Izzy.
Too late in the day to test, but can't you just change isReadable? http://docs.unity3d.com/Documentation/ScriptReference/TextureImporter-isReadable.html you may need to make a copy of the texture, if the bitmap is somehow protected by being-part-of-a-font And/or http://docs.unity3d.com/Documentation/ScriptReference/TrueTypeFontImporter.GenerateEditableFont.html
Thank you for replying It seems .isReadable is part of the TextureImporter. I hope i dont have to write any kind of AssetPostprocessor.OnPostprocessTexture for the TrueTypeFontImporter... do i? :/ I dont recall seeing a TrueTypeFontImporter - PostProcessor option anywhere. But, your other hint helped some. http://answers.unity3d.com/questions/485695/truetypefontimportergenerateeditablefont-does-not.html That seems to exttact the Material and the Texture... but Erros out now in my version of Unity 4.3.1f1, says it failed to recognize the font type. Oh well.. at least it didnt error out before extracting the Texture
Sweet... I got the W to flip to the right. I got the 'y' to align to the base. and this is what it looks like so far. Alpha 8 i assume is black and white? with black being the alpha mask? Ok. I just need to composite the Color[] pixels for each letter with the Color[] pixels it will replace in the destination and it should look about right. Fingers crossed.
I got the Composting showing and the results look like this for each Update(): I know this isnt very good for performance, but I just wanted to see how fast (or slow) it performed. 33% CPU usage. 38 or so FPS. And i'm not even using Color32 yet. Not optimized.
Only out of curiosity. I've never done anything like this in Unity... testing! Anyways using SetPixels32 seems to run twice as fast on this PC. And i would like to see which is the best approach. I was thinking, a Multi-Material approach would work good. Ex: if i wanted to make a left to right scrolling text ticker for Breaking News? Material 1 would have the background texture. Material 2 would have the DrawText texture (called only once in a while) ... ... and scrolling would be animated using UV offset?! I have no clue if this will work, since this is new to me, but should work in theory.
Is everyone else wrapping their GUI controls like this too? Code (csharp): // ---- MyControl.cs ---- using UnityEngine; using System.Collections; [System.Serializable] public class MyControl : Object { private GUIContent _Content = new GUIContent(); private Rect _Content_Area = new Rect(0,0,0,0); private Rect _Content_Area_Previously = new Rect(0,0,0,0); private string _Content_Text = ""; private Texture _Content_Texture = null; private string _Content_Tooltip = ""; private string _Content_Style_Name = ""; private GUIStyle _Content_Style = null; private bool _Autofit = false; private int _ControlID = 0; private bool _IsDraggable; private Rect _DraggableArea; private EventType _EventType; private bool _Visible = true; private Vector2 _MouseDown_Offset = new Vector2( 0, 0 ); // Constructor public MyControl( ) { _Content = new GUIContent(); Init(); } // Constructor public MyControl( string label ) { _Content = new GUIContent( label ); Init(); } // Constructor public MyControl( Texture icon ) { _Content = new GUIContent( icon ); Init(); } // Constructor public MyControl( string label, Texture icon ) { _Content = new GUIContent( label, icon ); Init(); } // Constructor public MyControl( string label, Texture icon, string tooltip ) { _Content = new GUIContent( label, icon, tooltip ); Init(); } private void Init() { // ... } public void DrawButton() { if( _Visible == false ) return; CheckIfContentStyleWasCreated(); CheckIfContentSizeChangedViaUser(); HandleEvents(); //GUI.Button( _Content_Area, _Content, _Content_Style_Name ); } private void CheckIfContentSizeChangedViaUser() { bool bChanged = _Content_Area.width !=_Content_Area_Previously.width || _Content_Area.height !=_Content_Area_Previously.height; if( bChanged ) { if( _Autofit ) CalculateContentArea(); _Content_Area_Previously.width = _Content_Area.width; _Content_Area_Previously.height = _Content_Area.height; } } private void CheckIfContentStyleWasCreated() { if( _Content_Style_Name == "" ) _Content_Style_Name = "button"; if( _Content_Style == null ) { CreateContentStyle(); } } private void CreateContentStyle() { _Content_Style = new GUIStyle( _Content_Style_Name ); CalculateContentArea(); } private void CalculateContentArea() { Vector2 size = _Content_Style.CalcSize( _Content ); _Content_Area.width = size.x; _Content_Area.height = size.y; } private void HandleEvents() { if( _ControlID == 0 ) _ControlID = GUIUtility.GetControlID( _Content, FocusType.Native ); _EventType = HandleMouseEvents(); // if( _EventType == EventType.ignore ) // _EventType = HandleKeyboardEvents(); } private EventType HandleMouseEvents() { EventType eType = Event.current.GetTypeForControl( _ControlID ); switch( eType ) { case EventType.mouseDown: if( _Content_Area.Contains( Event.current.mousePosition ) ) { GUIUtility.hotControl = _ControlID; _MouseDown_Offset.x = Event.current.mousePosition.x - _Content_Area.x; _MouseDown_Offset.y = Event.current.mousePosition.y - _Content_Area.y; Event.current.Use(); return EventType.mouseDown; } break; case EventType.mouseUp: if( GUIUtility.hotControl != _ControlID ) return EventType.ignore; GUIUtility.hotControl = 0; Event.current.Use(); if( _Content_Area.Contains( Event.current.mousePosition ) ) return EventType.mouseUp; else return EventType.ignore; case EventType.mouseDrag: if( GUIUtility.hotControl == _ControlID ) { Event.current.Use(); if( _IsDraggable ) { _Content_Area.x = Mathf.Clamp( Event.current.mousePosition.x - _MouseDown_Offset.x, _DraggableArea.x, _DraggableArea.x + _DraggableArea.width - 1 ); _Content_Area.y = Mathf.Clamp( Event.current.mousePosition.y - _MouseDown_Offset.y, _DraggableArea.y, _DraggableArea.y + _DraggableArea.height - 1 ); } return EventType.mouseDrag; } else return EventType.ignore; case EventType.repaint: _Content_Style.Draw( _Content_Area, _Content, _ControlID ); if( _Content_Area.Contains( Event.current.mousePosition ) ) return EventType.mouseMove; else return EventType.repaint; } if( _Content_Area.Contains( Event.current.mousePosition ) ) return EventType.mouseMove; else return EventType.ignore; } public GUIContent Content { get { return _Content; } set { _Content = value; } } public Rect ContentArea { get { return _Content_Area; } set { _Content_Area = value; } } public float Width { get { return _Content_Area.width; } set { _Content_Area.width = value; } } public float Height { get { return _Content_Area.height; } set { _Content_Area.height = value; } } public float X { get { return _Content_Area.x; } set { _Content_Area.x = value; } } public float Y { get { return _Content_Area.y; } set { _Content_Area.y = value; } } public string StyleName { get { return _Content_Style_Name; } set { _Content_Style_Name = value; } } public GUIStyle Style { get { return _Content_Style; } set { _Content_Style = value; } } public bool Autofit { get { return _Autofit; } set { _Autofit = value; } } public int ControlID { get { return _ControlID; } // set { // _ControlID = value; // } } public bool IsDraggable { get { return _IsDraggable; } set { _IsDraggable = value; } } public Rect DraggableArea { get { return _DraggableArea; } set { _DraggableArea = value; } } public EventType TypeOfEvent { get { return _EventType; } // set { // _EventType = value; // } } } and usage: Code (csharp): // ---- MyControlTest.cs ---- using UnityEngine; using System.Collections; [RequireComponent( typeof( GUILayer ) )] public class MyControlTest : MonoBehaviour { public MyControl[] Controls = new MyControl[6]; public string[] ControlTypes = new string[] { "box", "toggle", "label", "button", "textfield", "window" }; void Start () { SetupControlls(); } void OnGUI() { for(int i=0; i<Controls.Length; i++ ) Controls[i].DrawButton(); } void SetupControlls() { for(int i=0; i<Controls.Length; i++ ) { Controls[i] = new MyControl( "Button " + i.ToString() ); Controls[i].StyleName = ControlTypes[i]; Controls[i].X = 160; Controls[i].Y = 30 * i ; Controls[i].Autofit = true; Controls[i].IsDraggable = true; Controls[i].DraggableArea = new Rect( 0, 0, Screen.width-1, Screen.height-1 ); } } }
I think it got it to Composite the letters nicely onto a Texture with an existing background. Here is the example I've got so far. Link to UnityPackage: https://www.dropbox.com/s/s0b8j3ejp1f53kr/Unity43_DrawText_2_Texture2D_001.unitypackage [video=youtube_share;1eNIf9SiU0s]http://youtu.be/1eNIf9SiU0s Suggestions welcome. Thanks All.
Cool stuff! Tip to simplify your wrapping - instead of writing this: Code (csharp): private GUIStyle _Content_Style; public GUIStyle Style { get { return _Content_Style; } set { _Content_Style = value; } } you can use automatic accessors, like this: Code (csharp): public GUIStyle Style { get; private set; } Hope that helps
Another 3 years later, thank you again! But this is not working in 2019.4... This maybe works better with little adjustments: http://blog.almostlogical.com/2010/...time-in-unity3d-without-using-render-texture/