-
Notifications
You must be signed in to change notification settings - Fork 72
User Interface (UI)
UniverseLib's UI features live in the UniverseLib.UI namespace. The UI is built on top of Unity's uGUI framework (UnityEngine.UI), with some additional helpers and wrapper classes to make things easier.
It is recommended that you are somewhat familiar with Unity UI before using UniverseLib's UI systems, as it is presumed you have an understanding of how a GameObject-driven UI works. See the documentation here. Note however that we are using C# to create and control the UI as opposed to the Unity Editor, so it will be more like working with the DefaultControls class.
The UniverseLib.UI.UniversalUI class handles all UIBase instances. Using the UIBase system is required if you wish to make use of UniverseLib's UI Input support.
To create a UIBase, use UniversalUI.RegisterUI. The simplest implementation would look like this:
public static UIBase UiBase { get; private set; }
void Universe_OnInitialized()
{
UiBase = UniversalUI.RegisterUI("my.unique.ID", UiUpdate);
}
void UiUpdate()
{
// Called once per frame when your UI is being displayed.
}In the UniversalUI class you will also find:
-
GameObject CanvasRoot- the root object which all UiBase canvases live on. It does not actually contain aCanvascomponent itself. -
EventSystem EventSys- the globalEventSystemused by allUIBases. -
Font ConsoleFont- an instance of the Consola font, provided the AssetBundle was loaded successfully. Otherwise this will be Arial. -
Font DefaultFont- Arial, or the default font of the game.
The UIBase returned from UniversalUI.RegisterUI is a wrapper for your UI Canvas. It simply contains:
-
bool Enabled- use this to set your UI active or disabled. This callsUniversalUI.SetUIActive(ID, value); -
GameObject RootObject- the root object of your UI. All UI objects should be added onto this or a child of this. -
Canvas Canvas- theCanvascomponent on yourRootObject. -
PanelManager Panels- handles yourPanelBaseinstances
The PanelBase class can be inherited from to create dragable, resizable panels. These panels will also recognise panels created by other UIBases, any will reorder themselves (along with the UIBase) when clicked on.
public class MyPanel : UniverseLib.UI.Panels.PanelBase
{
public MyPanel(UIBase owner) : base(owner) { }
public override string Name => "My Panel";
public override int MinWidth => 100;
public override int MinHeight => 200;
public override Vector2 DefaultAnchorMin => new(0.25f, 0.25f);
public override Vector2 DefaultAnchorMax => new(0.75f, 0.75f);
public override bool CanDragAndResize => true;
protected override void ConstructPanelContent()
{
Text myText = UIFactory.CreateLabel(ContentRoot, "myText", "Hello world");
UIFactory.SetLayoutElement(myText.gameObject, minWidth: 200, minHeight: 25);
}
// override other methods as desired
}To create an instance of your panel class, simply call the constructor and UniverseLib will do the rest.
UIBase myUIBase = UniversalUI.RegisterUI("me.mymod", MyUpdateMethod);
MyPanel myPanel = new(myUIBase);Note: The PanelBase class was designed with the assumption that you will create a separate class for each panel instance, and not reuse the same class for multiple panels. However there is nothing stopping you from doing so if you want to implement it that way, it should work fine.
UIFactory contains methods for creating actual UI elements, and performing some common operations on them. It is loosely based on Unity's DefaultControls class.
UIFactory can help you create:
- Basic
*LayoutGroupobjects with anImagebackground Text-
InputField(wrapped in anInputFieldRef) -
Button(wrapped in aButtonRef) ToggleSliderScrollbarDropdown- Custom components and more
UIFactory has some helpers for working with Unity UI elements, including:
-
SetLayoutElement(GameObject, ...)- helper to easily create/get and set aLayoutElementon any GameObject. -
SetLayoutGroup<T>(GameObject, ...)- helper to easily create/get and set aHorizontalOrVerticalLayoutGroupon any GameObject. This also uses Runtime-specific helpers so that all platforms and Unity versions are supported.
UniverseLib has implemented several custom UI control classes for more advanced UI features such as ScrollPools, and better Scrollbars.
The ScrollPool class is an implementation of an object-pooled ScrollView component, using any ICell implementation for pooling. A ScrollPool must be initialized and controlled with an ICellPoolDataSource.
public class MyCell : ICell
{
// Implement interface members...
}
public class MyCellHandler : ICellPoolDataSource<MyCell>
{
GameObject myPanel;
GameObject panelContent;
ScrollPool<MyCell> ScrollPool;
void ConstructUI()
{
myPanel = UIFactory.CreatePanel("MyPanel", UiBase.RootObject, out panelContent, Color.black);
ScrollPool = UIFactory.CreateScrollPool<MyCell>(panelContent, "MyScrollPool", out GameObject scrollRoot, out GameObject scrollContent, Color.blue);
ScrollPool.Initialize(this);
}
// Implement interface members...
}The TransformTree class is used to create a Transform hierarchy panel, similar to the scene hierarchy in the Unity Editor.
It requires that you first set up a ScrollPool<TransformCell> and pass that to the constructor.
Importantly, you must call TransformTree.RefreshData whenever you want to update the tree, it will not update automatically. It is recommended to not call RefreshData more than once per second, as it can be a somewhat expensive method if there are a lot of Transforms being displayed.
transformScrollPool = UIFactory.CreateScrollPool<TransformCell>(parent, "TransformTree", out GameObject transformObj,
out GameObject transformContent, new Color(0.11f, 0.11f, 0.11f));
TransformTree = new TransformTree(transformScrollPool, GetTransformEntries, OnTransformCellClicked);
IEnumerable<GameObject> GetTransformEntries()
{
// ...
}
void OnTransformCellClicked(GameObject obj)
{
// ...
}AutoSliderScrollbar is a simple helper class for a more robust Scrollbar. It takes a Slider-Scrollbar created with UIFactory.CreateSliderScrollbar and automates the functionality behind it.
Generally you will only use this class when it is returned to you via functions like UIFactory.CreateScrollView, or UIFactory.CreateScrollInputField. For examples of how to set up an AutoSliderScrollbar, see the UIFactory source.
An InputFieldScroller uses an AutoSliderScrollbar to handle scrolling of an InputField, since Unity's implementation is far from perfect.
Generally you will only use this class when returned via UIFactory.CreateScrollInputField.
It has an OnScroll event you can subscribe to if you wish.
UniverseLib has a complete object-pooling implementation which you can use if you wish, in UniverseLib.UI.ObjectPool.Pool.
The Pool<T> class creates and manages an object pool for any IPooledObject implementation.
public class MyPoolableObject : IPooledObject
{
public GameObject UIRoot { get; set; }
// Used by ScrollPool. Not necessary if your object is not an ICell.
public float DefaultHeight => -1;
public GameObject CreateContent(GameObject parent)
{
UIRoot = UIFactory.CreateUIObject(...);
}
}
static void Example()
{
var borrowed = Pool<MyPoolableObject>.Borrow();
Pool<MyPoolableObject>.Return(borrowed);
}