Queríamos adicionar uma interface de mapa interativa para permitir que os usuários consumam informações na estação espacial que parecia e se sentia como se vivesse neste mundo. Decidimos construir o mapa dentro do espaço 3D em vez de em uma tela que se sobrepõe à experiência. Este tipo de visualização diegética permite mais imersão com o mundo, em vez de se sentir como se fosse uma experiência completamente separada.
Projetando o Mapa
Para projetar o mapa:
Nós zombamos da interface de usuário em um aplicativo externo e chegamos a uma ideia aproximada de como queríamos que fosse.
Nós exportamos as peças individuais do mapa como .png e as importamos para o Studio.
Construindo o mapa
Construindo o mapa dentro do Studio envolveu usar Parts e SurfaceGuis.
Para elementos não interativos, tudo o que precisávamos fazer era adicionar um objeto SurfaceGui à peça.
Para elementos interativos, o SurfaceGui também precisa estar dentro do StarterGui recipiente, com a propriedade Adornee ligada à parte apropriada na área de trabalho 3D. Isso permite que você adicione eventos de botões.
Para conseguir um efeito de paralaxe, usamos três instâncias separadas ScreenGui atribuídas a três instâncias únicas Parts com valores diferentes X .
Em seguida, adicionamos um efeito de brilho com a propriedade SurfaceGui.LightInfluence. Se você definir o valor da propriedade em menos de 1, ele habilitará a propriedade SurfaceGui.Brightness. Ao ajustar o brilho, você pode aumentar a emissão de brilho da imagem.
Para permitir que os usuários alterem a exibição do mapa, usamos um ProximityPrompt que anexamos a um modelo 3D. Esta é uma maneira fácil de permitir a interação do usuário com os elementos do mundo.
Finalmente, usando um UITweenModule ModuleScript dentro do ReplicatedStorage, animamos esconder e mostrar a interface do usuário com TweenService e um pouco de lógica para determinar o estado. Ao rastrear o que o usuário clicou, poderíamos esconder e mostrar elementos alterando várias propriedades, como alfa, posição e tamanho.
UITweenMóduloMóduloScriptlocal TweenService = game:GetService("TweenService")local UITween = {}-- para desaparecer imagensfunction UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TempoEnum.EasingStyle.Quad, --Estilo relaxanteEnum.EasingDirection.Out, --Direção de relaxamento0, --Contagem de repetiçãofalse, --Inverte se for verdadedelay --Tempo de atraso)local tween = TweenService:Create(object, tweenAlpha, {Transparency = amount})tween:Play()endfunction UITween.fade(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TempoEnum.EasingStyle.Quad, --Estilo relaxanteEnum.EasingDirection.Out, --Direção de relaxamento0, --Contagem de repetiçãofalse, --Inverte se for verdadedelay --Tempo de atraso)local tween = TweenService:Create(object, tweenAlpha, {ImageTransparency = amount})tween:Play()end-- para desaparecer imagensfunction UITween.fadeBackground(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TempoEnum.EasingStyle.Quad, --Estilo relaxanteEnum.EasingDirection.Out, --Direção de relaxamento0, --Contagem de repetiçãofalse, --Inverte se for verdadedelay --Tempo de atraso)local tween = TweenService:Create(object, tweenAlpha, {BackgroundTransparency = amount})tween:Play()end-- para desaparecer textofunction UITween.fadeText(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --TempoEnum.EasingStyle.Quad, --Estilo relaxanteEnum.EasingDirection.Out, --Direção de relaxamento0, --Contagem de repetiçãofalse, --Inverte se for verdadedelay --Tempo de atraso)local tween1 = TweenService:Create(object, tweenAlpha, {TextTransparency = amount})tween1:Play()end-- para texto e imagens em movimentofunction UITween.move(object, position, time, delay)task.wait(delay)object:TweenPosition(position, Enum.EasingDirection.Out, Enum.EasingStyle.Quint, time)end-- para alterar o tamanhofunction UITween.size(object, size, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --TempoEnum.EasingStyle.Quint, --Estilo relaxanteEnum.EasingDirection.Out, --Direção de relaxamento0, --Contagem de repetiçãofalse, --Inverte se for verdadedelay, --Tempo de atrasooverride,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, --TempoEnum.EasingStyle.Quint, --Estilo relaxanteEnum.EasingDirection.Out, --Direção de relaxamento0, --Contagem de repetiçãofalse, --Inverte se for verdadedelay, --Tempo de atrasooverride,callback)local tween = TweenService:Create(object, tweenSize, {Rotation = rotation})tween:Play()end-- para desfocar a câmerado jogofunction 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-- para desfocar a câmerado jogofunction 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 UITweenAplicando UI Tween a Objetoslocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Adicionar Módulo UITweenlocal UITween = require(ReplicatedStorage.UITweenModule)-- Encontre Guies de Jogador e objetos de UIlocal playerGui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')local screenGuiMapUIFrame = playerGui:WaitForChild("ScreenGuiMapUIFrame").SurfaceGuilocal mapUIFrameStroke = screenGuiMapUIFrame.FrameStrokelocal mapUIFrameFill = screenGuiMapUIFrame.FrameFill-- Tamanhos usados para 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)-- Exemplo de 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)
Aqui está o resultado final do mapa interativo: