Wir wollten eine interaktive Karten-Benutzeroberfläche hinzufügen, damit die Benutzer Informationen im Raumstation konsumieren konnten, die aussahen und sich anfühlten, als würden sie in dieser Welt leben. Wir beschlossen, die Karte innerhalb des 3D-Raums zu erstellen, anstatt auf einem Bildschirm, der die Erfahrung überlagert. Diese Art der diegetischen Visualisierung ermöglicht eine höhere Eingetauchtsein in die Welt, anstatt sich wie eine völlig separate Erfahrung anzufühlen.
Die Karte entwerfen
Um die Karte zu entwerfen:
Wir haben die Benutzeroberfläche in einer externen Anwendung entworfen und eine grobe Vorstellung davon entwickelt, wie sie aussehen sollte.

Wir haben die einzelnen Teile der Karte als .png exportiert und in Studio importiert.

Die Karte erstellen
Die Erstellung der Karte in Studio beinhaltete die Verwendung von Parts und SurfaceGuis.
Für nicht-interaktive Elemente mussten wir lediglich ein SurfaceGui-Objekt zum Teil hinzufügen.
Für interaktive Elemente muss das SurfaceGui auch im StarterGui-Container sein, wobei die Adornee-Eigenschaft mit dem entsprechenden Teil im 3D-Arbeitsbereich verknüpft ist. Dadurch kannst du Schaltflächenereignisse hinzufügen.
Um einen Parallaxeneffekt zu erzielen, verwendeten wir drei separate ScreenGui-Instanzen, die drei einzigartigen Parts mit unterschiedlichen X-Werten zugewiesen waren.

Wir fügten dann einen Glüheffekt mit der SurfaceGui.LightInfluence-Eigenschaft hinzu. Wenn du den Eigenschaftswert auf weniger als 1 setzt, wird die SurfaceGui.Brightness-Eigenschaft aktiviert. Durch Anpassen der Helligkeit kannst du das Glühen des Bildes erhöhen.
Um den Benutzern zu ermöglichen, die Anzeige der Karte umzuschalten, verwendeten wir einen ProximityPrompt, den wir an ein 3D-Modell anfügten. Dies ist eine einfache Möglichkeit, Benutzereingaben mit Weltelementen zuzulassen.

Schließlich animierten wir das Verstecken und Zeigen der Benutzeroberfläche mithilfe eines UITweenModule ModuleScripts in ReplicatedStorage mit TweenService und ein wenig Logik zur Zustandsbestimmung. Indem wir verfolgten, was der Benutzer klickte, konnten wir Elemente durch Tweening verschiedener Eigenschaften wie Alpha, Position und Größe ein- und ausblenden.
UITweenModule ModuleScriptlocal TweenService = game:GetService("TweenService")local UITween = {}-- zum Ausblenden von Bildernfunction UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --ZeitEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Wiederholungsanzahlfalse, --kehrt zurück, wenn wahrdelay --Verzögerungszeit)local tween = TweenService:Create(object, tweenAlpha, {Transparency = amount})tween:Play()endfunction UITween.fade(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --ZeitEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Wiederholungsanzahlfalse, --kehrt zurück, wenn wahrdelay --Verzögerungszeit)local tween = TweenService:Create(object, tweenAlpha, {ImageTransparency = amount})tween:Play()end-- zum Ausblenden der Hintergründefunction UITween.fadeBackground(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --ZeitEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Wiederholungsanzahlfalse, --kehrt zurück, wenn wahrdelay --Verzögerungszeit)local tween = TweenService:Create(object, tweenAlpha, {BackgroundTransparency = amount})tween:Play()end-- zum Ausblenden von Textfunction UITween.fadeText(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --ZeitEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Wiederholungsanzahlfalse, --kehrt zurück, wenn wahrdelay --Verzögerungszeit)local tween1 = TweenService:Create(object, tweenAlpha, {TextTransparency = amount})tween1:Play()end-- zum Bewegen von Text und Bildernfunction UITween.move(object, position, time, delay)task.wait(delay)object:TweenPosition(position, Enum.EasingDirection.Out, Enum.EasingStyle.Quint, time)end-- für Größenänderungenfunction UITween.size(object, size, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --ZeitEnum.EasingStyle.Quint, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Wiederholungsanzahlfalse, --kehrt zurück, wenn wahrdelay, --Verzögerungszeitoverride,callback)local tween = TweenService:Create(object, tweenSize, {Size = size})tween:Play()endfunction UITween.rotate(object, rotation, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --ZeitEnum.EasingStyle.Quint, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Wiederholungsanzahlfalse, --kehrt zurück, wenn wahrdelay, --Verzögerungszeitoverride,callback)local tween = TweenService:Create(object, tweenSize, {Rotation = rotation})tween:Play()end-- für das Unschärfen der Spielkamerafunction UITween.blur(object, amount, time)local tweenInfo = TweenInfo.new(time, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)local tween = TweenService:Create(object, tweenInfo, {Size = amount})tween:Play()end-- für das Einschalten der Helligkeitfunction UITween.turnOn(object, amount, time)local tweenInfo = TweenInfo.new(time, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)local tween = TweenService:Create(object, tweenInfo, {Brightness = amount})tween:Play()endreturn UITweenAnwendung von UI Tween auf Objektelocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- UITween-Modul hinzufügenlocal UITween = require(ReplicatedStorage.UITweenModule)-- Benutzeroberflächen und UI-Objekte findenlocal playerGui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')local screenGuiMapUIFrame = playerGui:WaitForChild("ScreenGuiMapUIFrame").SurfaceGuilocal mapUIFrameStroke = screenGuiMapUIFrame.FrameStrokelocal mapUIFrameFill = screenGuiMapUIFrame.FrameFill-- Größen, die für Tweening verwendet werdenlocal frameSizeStart = UDim2.new(0, 0, 0, 0)local frameSizeMid = UDim2.new(1, 0, 0.05, 0)local frameSizeEnd = UDim2.new(1, 0, 1, 0)-- Beispiel-TweeningUITween.fade(mapUIFrameStroke, 0, 2, 0)UITween.size(mapUIFrameStroke, frameSizeMid, 0.4, 0)UITween.fade(mapUIFrameFill, 0, 2, 0.5)UITween.size(mapUIFrameFill, frameSizeEnd, 0.4, 0.25)task.wait(0.25)UITween.size(mapUIFrameStroke, frameSizeMid, 0.4, 0)UITween.size(mapUIFrameFill, frameSizeMid, 0.4, 0.25)task.wait(0.25)UITween.size(mapUIFrameStroke, frameSizeEnd, 0.4, 0)UITween.size(mapUIFrameFill, frameSizeEnd, 0.4, 0.25)
Hier ist das Endergebnis der interaktiven Karte: