UI in Unity
UI
UI steht generell als Kurzform von User Interface. Im Kontext von Unity bezeichnet der Begriff UI allerdings eine von Unity spezifisch vorgegebene Interaktionsstruktur, die mit Buttons, Textfeldern und ähnlichem arbeitet, und sich im Code von den meisten anderen Interaktionen unterscheidet. Der Hauptunterschied besteht im von Unity vorgegebenen Interaktionsmodus durch UI Elemente und die Unterschiede in der Art der Darstellung auf dem Bildschirm.
UI Elemente hinzufügen
Unity UI Elemente sind GameObjects die man in der Hierarchy über den Unterpunkt UI erstellen kann.
![]()
Es stehen eine Reihe von Elementen zur Auswahl. Wir werden uns auf dieser Seite hauptsächlich mit den Elementen Button (TextMeshPro) und Text (TextMeshpro) beschäftigen.
Kurze Erklärung zu TextMeshPro
Unity ist in den letzten zehn Jahren enorm schnell gewachsen und hat oft Code-Elemente, die von Menschen ausserhalb der Firma erstellt wurden über Zeit in den eigenen Code übernommen. TextMeshPro ist so ein Fall, in dem besserer Code zur Darstellung von texten in unity eingeflossen ist. Unity muss allerdings nun den von ihnen selbst erstellten sowie den zugekauften Code weiter anbieten, was dazu führt, dass man als Nutzer*in die Auswahl aht, für welche dier beiden zur Verfügung gestellten Varianten man sich entscheiden möchte.
Wir wollen uns im Zweifel immer für TextMeshPro entscheiden, da der Text schöner dargestellt wird.
Wenn ihr das erste Mal aus der Hierarchy ein GameObject mit dem Zusatz (TextMeshPro) erstellt, ploppt folgender Dialog auf, bei dem ihr auf beide Knöpfe klicken könnt:
![]()
Das Canvas Konzept
Alle in Unity genutzten UI Elemente werden einem sogenannten Canvas Objekt zugeordnet, einer Art Leinwand, die über der Szenen auf den Bildschirm gespannt ist. Wenn wir in der Hierarchy einen neuen Button erstellen, erstellt Unity auch gleich ein Canvas Object sowie ein EventSystem (über letzteres werde wir uns im Rahmen des Studiengangs nur peripher unterhalten).
![]()
UI Elemente werden relativ zu diesem Canvas positioniert und dargestellt (gerendert) und unterliegen dem Koordinatensystem, das durch den Canvas vorgegeben ist. Für gewöhnlich sind sie daher unabhängig von der Position und Rotation der Kamera in der Szene immer am selben Ort auf dem Bildschirm. Deswegen müssen UI Elemente in der Hierarchy in Unity auch immer unter einem Canvas Objekt auftauchen.
Das Koordinatensystem des Canvas Objekts wiederum orientiert sich an der Auflösung des Bildschirms, wie in der Game View eingestellt.
![]()
Da man sich der Auflösung der Endgeräte zu Beginn eines Projektes nicht immer sicher sein kann, und Unity von sich aus vorsieht, dass die Nutzer*innen ihre Auflösung auch selbst einstellen können (kommt bei uns seltener vor), bietet uns Unity durch die Nutzung des Canvas Konzeptes an, dass wir verschiedene UI Elemente relativ zu den Ecken des Bildschirms positionieren können. Hierfür ändert Unity den uns bekannten Transform Component in ein RectTransform Component (der allerdings von Transform abgeleitet ist, so dass wir per Script weiterhin wie gewohnt auf transform.position zugreifen können):
![]()
Unterschiede in Koordinaten
Wie ihr gut erkennen könnt, sind die Zahlen, die in diesem Component die Position des GameObjects beschreiben deutlich anders, als die von uns bisher genutzten. Während wir bei unseren bisherigen Übungen für gewöhnlich Koordinaten zwischen 1 und 10 oder -1 und -10 für die x, y und z Werte genutzt haben, stehen hier plötzlich zahlen in der Grösse von 100 und 1000. Das hat damit zu tun, dass die Koordinaten bei Rect Transform als Bildschirmkoordinaten interpretiert werden, wobei eine Koordinate von 1 genau einen Pixel beschreibt. Zum Vergleich: in unserer Unity Szene beschreibt eine Koordinate von 1 für gewöhnlich die Distanz von einem Meter.
Darstellung in Scene View und Game View
Wenn wir zwischen der Unity Scene View und der Game View hin und her schalten, stellen wir fest, dass unser Button in der Game View zwar an einem sinnvollen Punkt dargestellt wird, in unserer Scene View Allerdings nichts von ihm zu sehen ist. Stattdessen sehen wir eine seltsame Linie mit Ecke:
![]()
Der Grund dafür ist, dass die Unity Scene View immer alle Dinge in Unity Koordinaten darstellt (1 Unity Koordinate interpretieren wir für gewöhnlich als 1 Meter), wohingegen in der Game View die Besonderheiten des Canvas-Konzeptes bereits in Betracht gezogen werden, und die UI Elemente unabhängig von der Kamera auf dem Bildschirm platziert werden.
UI Elemente sind also am Einfachsten in der Game View sichtbar und es empfiehlt sich, ihre positionierung auch dort zu überprüfen.
Trotzdem können UI Elemente auch in der Scene View angeschaut und manipuliert werden. Die oben angesprochene weisse Linie beschreibt den Umfang des Canvas Objektes in Unity 3D-Koordinaten. Im Canvas Objekt selbst könnt ihr unter width und height nachschauen, wie gross dieser Umfang ist. Wenn ihr gaaaaaaaanz weit herauszoomt, könnt ihr dann auch euren Button sehen. Eine einfachere Version, um eine übersicht über die UI Elemente in der Scene View zu bekommen ist, das Canvas GameObjekt doppelklicken.
Ihr könnt selbstverständlich wie gewohnt, auch UI Elemente in der Scene View anklicken und verschieben. Wichtig hierbei ist nur zu wissen, dass der Canvas diese Elemente nicht perspektivisch darstellt und sich an der Darstellung der UI Elemente somit auch bei Verschiebung in der Z-Achse nichts ändert.
Relatives Ausrichten der UI Elemente
Durch klicken auf das Piktogramm links bei RectTransform können wir bestimmen, wie Unity die relative Position unseres UI Elements bestimmen soll:
![]()
Gerade bewegt Unity unseren Button von der Mitte des Screens aus gesehen 687 Pixel nach links und 369.5 Pixel nach unten.
Mehr informationen hierzu findet ihr in der Unity Gebrauchsanweisung für UI Elemente.
Nachdem wir einen Button (TextMeshPro) in Unity hinzugefügt haben, sollte unsere Szene ungefähr so aussehen:
Buttons abfragen
Prinzipiell erstellen wir in unseren Szenen Buttons als UI-Elemente, weil wir im Code darauf reagieren wollen, dass jemensch den Button geklickt hat. Hier hilft uns Unity durch bereits vorprogrammierte Strukturen, die es uns sehr einfach ermöglichen, eine Funktion aufzurufen, wenn ein bestimmter Button geklickt wurde.
Beispielscript
Wir können also ein Beispielscript erstellen, nennen wir es KnopfGeklickt.cs (Grossschreibung bei neuen Scripten beachten!). Und diesem Script können wir eine einfache Funktion hinzufügen - in diesem Beispiel die Funktion ButtonWurdeGeklickt(), die uns in der Konsole etwas ausgibt:
public void ButtonWurdeGeklickt(){
Debug.Log("Yay!");
}
Das public bei public void ist in diesem Fall sehr wichtig, da wir diese Funktion ausserhalb des eigenen GameObjects aufrufen wollen!
Button mit Beispielscript verbinden
Nachdem wir unser Script als Component auf ein leeres Gameobject hinzugefügt haben, können wir daraufhin im Inspector den Button mit unserer Funktion direkt verbinden. Dazu fügen wir beim Button im Feld OnClick eine neue Verbindung zu unserer Funktion hinzu:
Ausgangspunkt ist unsere Hierarchy mit unserem GameObject (ich habe es KlickKonsequenz genannt) und unserem neuen Script als Component:
![]()
In Folgenden Schritten können wir die oben genannte Funktion in unserem Script ausführen lassen, wenn der Button gedrückt wurde: