I am trying to, when the game starts, create an image component as well as a text component, both a part of the UI. When I start the game, though, only the component that comes first in the method will actually be created. For example:
gameObject.AddComponent<Text>();
Rect rect = gameObject.GetComponent<RectTransform>().rect;
GetText().font = font;
GetText().color = new Color32(200, 200, 200, 255);
GetText().fontSize = 20;
GetText().alignment = TextAnchor.MiddleCenter;
Image img = gameObject.AddComponent<Image>();
Texture2D texture = Resources.Load<Texture2D>("Assets/GrayBorder");
Sprite sprite = Sprite.Create(texture, gameObject.GetComponent<RectTransform>().rect, new Vector2(0, 0));
img.overrideSprite = sprite;
This will create just the text, while this:
Image img = gameObject.AddComponent<Image>();
Texture2D texture = Resources.Load<Texture2D>("Assets/GrayBorder");
Sprite sprite = Sprite.Create(texture, gameObject.GetComponent<RectTransform>().rect, new Vector2(0, 0));
img.overrideSprite = sprite;
gameObject.AddComponent<Text>();
Rect rect = gameObject.GetComponent<RectTransform>().rect;
GetText().font = font;
GetText().color = new Color32(200, 200, 200, 255);
GetText().fontSize = 20;
GetText().alignment = TextAnchor.MiddleCenter;
will create just the image. How would I go about adding both at the same time?
The only reason it would stop would be if there’s an error that ceases execution of the function. My guess would be your Resources.Load is failing based on the folder name as assets needed to be in a special “Resources” folder, not your root “Assets” folder.
As an aside, what’s the point of dynamically adding the two components instead of using the editor?
That’s because the Text component as well as the Image component are both derived from Graphic and one gameobject can only have a single graphic component. Keep in mind that components define the behaviour of a gameobject. A single gameobject can not be a text and an image at the same time. It also wouldn’t make much sense since you only have a single transform (RectTransform) to define its location and orientation. You have to create two seperate gameobjects.
Just try the same thing in the editor manually and you get an error telling your exactly that. I thought that you should get an error / warning in the console as well, but I’m not sure about that.
So you usually create a grouping gameobject and add two child objects (one for the text, one for the image) so you can manage the whole thing as one object and each UI component can be positioned relatively. You probably want to setup those gameobject in the editor and create a prefab out of it, so you can simply instantiate the prefab at runtime. You just have to make sure you instantiate the prefab as a child of the canvas.
1 Like
VERY much this ^ ^ ^ ^ … yes, you CAN call AddComponent<Text>()
but you will very soon discover all the amazing things that the Editor scripts associated with the UnityEngine.UI.Text actually do when you create one, and you will be sad.
Even if you persist and get most of those things done yourself, if you don’t do 100% of them correctly, it won’t work anyway in all orientations, rotations, anchors, etc.
For anything UI-related, make prefabs, turn stuff on and off, fill in the data or images, etc. But seriously, just stay away from trying to create them yourself in code. It’s a freakin’ nightmare. It’s just not like other parts of Unity where it’s trivial to add a MeshFilter and a MeshRenderer and get yourself up and running. The UI stuff is hairy af.
ALSO: when you are Instantiating items that live under an Canvas, NEVER Instantiate them bare… you will also be very sad panda. Always use a form of Instantiate that takes the second Transform parent argument:
var myUIChunk = Instantiate<GameObject>( UIChunkPrefab, TransformParentWhereItGoesUnderCanvas);
1 Like