I have an issue regarding generating Unity UI elements at runtime. I can generate them fine, but when trying to create LayoutGroups with LayoutElements at runtime via C# the elements don’t seem to register that they’re part of a LayoutGroup until an Update() or if I manually nudge them in the editor.
Is there an issue in setting up I’ve missed, or is this a bug. It seems like it could be a bug since everything adjusts itself when I play with any variable or setting in the editor window or adjust position.
Here’s some of the relative code:
//Generate Horizontal Group. Name - the gameobjects name.
public static RectTransform BeginHorizontal(string name = “HorizontalLayoutGroup”) {
positionCache.Push(currentPosition.x);
modeCache.Push(Mode.Horizontal);
// RectTransform t = go.AddComponent();
RectTransform t = BeginSubControl(name);
HorizontalLayoutGroup lg = t.gameObject.AddComponent();
lg.padding = new RectOffset(defaultMargin, defaultMargin, defaultMargin, defaultMargin);
lg.spacing = defaultMargin;
lg.childForceExpandWidth = true;
lg.childForceExpandHeight = false;
return t;
}
//Terminate BeginHorizontal component
public static void EndHorizontal() {
currentPosition.x = positionCache.Pop();
modeCache.Pop();
EndSubControl();
}
public static RectTransform BeginSubControl(string name = “SubGroup”) {
GameObject go = new GameObject(name);
RectTransform t = go.AddComponent();
Rect tr = t.rect;
if (subControls.Count > 0) {
RectTransform temp = subControls.Peek();
t.SetParent(temp, false);
}
subControls.Push(t);
t.anchoredPosition = Vector2.zero;
t.anchorMin = new Vector2(0, 0);
t.anchorMax = new Vector2(1, 1);
t.offsetMax = new Vector2(0, 0);
t.offsetMin = new Vector2(0, 0);
t.pivot = currentPosition;
return t;
}
public static void EndSubControl() {
subControls.Pop();
}
public static void AddChild(RectTransform trans) {
trans.parent = subControls.Peek();
//trans.anchoredPosition = currentPosition;
}
//GUI.Button(new Rect(10, 10, 50, 50), btnTexture)
public static Text Label(string text, string name = “Text”) {
GameObject go = new GameObject(name);
Text t = go.AddComponent();
t.font = Resources.FindObjectsOfTypeAll()[0];
t.text = text;
AddChild(t.rectTransform);
return t;
}
public static void Button(string text, string customFont = “Arial”, string name = “Button”) {
GameObject go = new GameObject(name);
Image i = go.AddComponent();
Button b = go.AddComponent();
b.targetGraphic = i;
//Creates a secondary gameObject which is parented to go, this will hole the text label - since its a little different to set up we can’t reuse Label()
GameObject go2 = new GameObject(name + “- label”);
go2.transform.parent = go.transform;
Text t = go2.AddComponent();
t.text = text;
t.rectTransform.anchoredPosition = new Vector2(.5f, .5f);
t.font = Resources.FindObjectsOfTypeAll()[0];
t.fontSize = 20;
t.color = Color.red;
t.alignment = TextAnchor.MiddleCenter;
LayoutElement le = go.AddComponent();
le.minHeight = defaultBtnSize;
//Button created, lets add it to the canvas objects
AddChild((RectTransform)go.transform);
// c# - Unity new UI - Dynamically change the functions called by GUI elements - Game Development Stack Exchange
b.onClick.AddListener(delegate {
Debug.Log(“Button " + b.name + " has been clicked!”);
});
}
Then executed here
void Start () {
root = GUIHelper.BeginSubControl();
root.SetParent(this.GetComponent().transform, false);
GUIHelper.BeginHorizontal();
GUIHelper.Button(“My Button”);
GUIHelper.Button(“My Button”);
GUIHelper.EndHorizontal();
GUIHelper.EndSubControl();
}