I am trying to use a constructor to create a custom control named Popup.
I want to set the text of the popup by passing a string via the constructor.
exactly in the same way that a Toggle VisualElement lets you do.
Example.
Unity’s Custom Control:
Toggle myToggle = new Toggle(“Text for toggle via a constructor”);
My Custom Control:
Popup myPopup = new Popup(“Text in the centre of the red box from c#”);
I want to be able to construct VisualElements this way so that I can create X number of VisualElements depending on data received from SQL all with different member variable data.
But what happens is that the myPopup instance has no Uxml or USS references at all.
Unity gives this error:
Note: This error is on line 22 of popup c# example below.
Please someone explain what I need to do.
Below is an example project created to try to solve this.
- The Main window has three visual elements, Header, Body, Footer.
- The Header has a button that when pressed should place a Popup within the Body.
- The Footer has a Toggle as an example of unity being able to do what I want to do.
MainWindow: Uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/UI/MainWindow.uss?fileID=7433441132597879392&guid=c91c9754ad6b2de4fbf95507110cc6a7&type=3#MainWindow" />
<MainWindow class="screen">
<ui:VisualElement name="Container" class="screen">
<ui:VisualElement name="Header" class="header">
<ui:Button text="Spawn Popup" display-tooltip-when-elided="true" name="HeaderButton" style="top: 25%; width: 50%; left: 25%; height: 75px; font-size: 32px;" />
</ui:VisualElement>
<ui:VisualElement name="Body" class="body" style="background-color: rgb(77, 64, 64);" />
<ui:VisualElement name="Footer" class="footer" />
</ui:VisualElement>
</MainWindow>
</ui:UXML>
MainWindow: Picture
Popup: UXML
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/UI/Popup/Popup.uss?fileID=7433441132597879392&guid=fb7fb0e47e1b69e4e9637badbc4e54de&type=3#Popup" />
<Popup int-attr="5" class="size">
<ui:VisualElement name="container" class="size container">
<ui:Label text="Change Me" display-tooltip-when-elided="true" name="PopupLabel" class="label" />
</ui:VisualElement>
</Popup>
</ui:UXML>
Popup: Picture
MainWindow:
public class MainWindow : VisualElement
{
Button headerButton;
public new class UxmlFactory : UxmlFactory<MainWindow, UxmlTraits> {}
public MainWindow()
{
this.RegisterCallback<GeometryChangedEvent>(OnGeometryChange);
}
void OnGeometryChange(GeometryChangedEvent evt)
{
headerButton = this.Q<Button>("HeaderButton");
headerButton.RegisterCallback<ClickEvent>(ev => OnHeaderButtonClicked());
LookAtUnityBeingAbleToDoWhatIWantToDo();
this.UnregisterCallback<GeometryChangedEvent>(OnGeometryChange);
}
private void OnHeaderButtonClicked()
{
// This should work the same way as a toggle.
Popup popup = new Popup("Text in the middle of Red Box"); // losses its uxml and uss references.
popup.style.flexGrow = 1;
this.Q("Body").Add(popup);
Debug.Log("Pressed But nothing spawned T.T ");
}
private void LookAtUnityBeingAbleToDoWhatIWantToDo()
{
// This is the goal... but I want the looks to be defined in uxml + uss
Toggle myToggle = new Toggle("Setting a label via a constructor");
this.Q("Footer").Add(myToggle);
}
Popup:
public class Popup : VisualElement
{
Label popupLabel;
string labelText = "Some Default Text";
public new class UxmlFactory : UxmlFactory<Popup, UxmlTraits> {}
public Popup()
{
Debug.Log("Default Constructor");
this.RegisterCallback<GeometryChangedEvent>(OnGeometryChange);
}
public Popup(string text) : this()
{
Debug.Log("The Constructor Being Used");
labelText = text;
}
void OnGeometryChange(GeometryChangedEvent evt)
{
popupLabel = this.Q<Label>("PopupLabel");
popupLabel.text = labelText;
this.UnregisterCallback<GeometryChangedEvent>(OnGeometryChange);
}
}