We wilden een interactieve kaart-UI toevoegen zodat gebruikers informatie in het ruimtestation konden consumeren die eruitzag en aanvoelde alsof het in deze wereld leefde. We besloten de kaart binnen de 3D-ruimte te bouwen in plaats van op een scherm dat de ervaring overlayt. Dit type diegetische visualisatie zorgt voor meer onderdompeling in de wereld in plaats van dat het aanvoelt als een volledig aparte ervaring.
Ontwerp de kaart
Om de kaart te ontwerpen:
We hebben de UI in een externe applicatie gemockt en kwamen met een ruw idee van hoe we wilden dat het eruitzag.

We exporteerden de individuele onderdelen van de kaart als .png en importeerden ze in Studio.

Bouw de kaart
Het bouwen van de kaart binnen Studio omvatte het gebruik van Parts en SurfaceGuis.
Voor niet-interactieve elementen hoefden we alleen maar een SurfaceGui object aan het onderdeel toe te voegen.
Voor interactieve elementen moet de SurfaceGui ook binnen de StarterGui container zijn, met de Adornee eigenschap gekoppeld aan het juiste onderdeel in de 3D-werkruimte. Dit stelt je in staat om knopgebeurtenissen toe te voegen.
Om een parallax-effect te bereiken, gebruikten we drie aparte ScreenGui instanties die aan drie unieke Parts met verschillende X waarden waren toegewezen.

We voegden vervolgens een gloei-effect toe met de SurfaceGui.LightInfluence eigenschap. Als je de eigenschapswaarde op minder dan 1 instelt, wordt de SurfaceGui.Brightness eigenschap ingeschakeld. Door de helderheid aan te passen, kun je de gloed die uit de afbeelding komt verhogen.
Om gebruikers de mogelijkheid te geven om de weergave van de kaart in te schakelen, gebruikten we een ProximityPrompt die we aan een 3D-model bevestigden. Dit is een gemakkelijke manier om gebruikersinteractie met wereldelementen toe te staan.

Ten slotte, met behulp van een UITweenModule ModuleScript binnen ReplicatedStorage, animeerden we het verbergen en tonen van de UI met TweenService en een beetje logica om de staat te bepalen. Door bij te houden wat de gebruiker klikte, konden we elementen verbergen en tonen door verschillende eigenschappen zoals alpha, positie en grootte te tweenen.
UITweenModule ModuleScriptlocal TweenService = game:GetService("TweenService")local UITween = {}-- voor het vervagen van afbeeldingenfunction UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TijdEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Herhalingsaantalfalse, --Keert om als waardelay --Vertragingstijd)local tween = TweenService:Create(object, tweenAlpha, {Transparency = amount})tween:Play()endfunction UITween.fade(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TijdEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Herhalingsaantalfalse, --Keert om als waardelay --Vertragingstijd)local tween = TweenService:Create(object, tweenAlpha, {ImageTransparency = amount})tween:Play()end-- voor het vervagen van afbeeldingenfunction UITween.fadeBackground(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TijdEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Herhalingsaantalfalse, --Keert om als waardelay --Vertragingstijd)local tween = TweenService:Create(object, tweenAlpha, {BackgroundTransparency = amount})tween:Play()end-- voor het vervagen van tekstfunction UITween.fadeText(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TijdEnum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Herhalingsaantalfalse, --Keert om als waardelay --Vertragingstijd)local tween1 = TweenService:Create(object, tweenAlpha, {TextTransparency = amount})tween1:Play()end-- voor het verplaatsen van tekst en afbeeldingenfunction UITween.move(object, position, time, delay)task.wait(delay)object:TweenPosition(position, Enum.EasingDirection.Out, Enum.EasingStyle.Quint, time)end-- voor het veranderen van groottefunction UITween.size(object, size, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --TijdEnum.EasingStyle.Quint, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Herhalingsaantalfalse, --Keert om als waardelay, --Vertragingstijdoverride,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, --TijdEnum.EasingStyle.Quint, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --Herhalingsaantalfalse, --Keert om als waardelay, --Vertragingstijdoverride,callback)local tween = TweenService:Create(object, tweenSize, {Rotation = rotation})tween:Play()end-- voor het vervagen van de gamecamerafunction 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-- voor het inschakelen van de helderheidfunction 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 UITweenToepassen van UI Tween op Objectenlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Voeg UITween Module toelocal UITween = require(ReplicatedStorage.UITweenModule)-- Vind speler Guis en UI-objectenlocal playerGui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')local screenGuiMapUIFrame = playerGui:WaitForChild("ScreenGuiMapUIFrame").SurfaceGuilocal mapUIFrameStroke = screenGuiMapUIFrame.FrameStrokelocal mapUIFrameFill = screenGuiMapUIFrame.FrameFill-- Groottes gebruikt voor tweeninglocal frameSizeStart = UDim2.new(0, 0, 0, 0)local frameSizeMid = UDim2.new(1, 0, 0.05, 0)local frameSizeEnd = UDim2.new(1, 0, 1, 0)-- Voorbeeld 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 is het eindresultaat van de interactieve kaart: