우리는 사용자들이 이 세계에 살고 있는 것처럼 보이고 느껴지는 우주 정거장에서 정보를 소비할 수 있도록 상호작용 가능한 지도 UI를 추가하기를 원했습니다. 우리는 경험을 겹치는 화면 위에 지도를 만드는 대신 3D 공간 안에 지도를 구축하기로 결정했습니다. 이러한 유형의 서사적 시각화는 완전히 별개의 경험처럼 느껴지는 것보다 세계와 더 몰입할 수 있게 해줍니다.
지도를 디자인하기
지도를 디자인하려면:
우리는 외부 애플리케이션에서 UI를 목업하고 원하는 모습에 대한 대략적인 아이디어를 제시했습니다.

우리는 지도의 개별 요소를 .png로 내보내고 이를 스튜디오에 가져왔습니다.

지도를 구축하기
스튜디오 안에서 지도를 구축하는 것은 Parts와 SurfaceGuis를 사용하는 것을 포함했습니다.
상호작용이 없는 요소의 경우, 우리는 단순히 파트에 SurfaceGui 객체를 추가하면 됩니다.
상호작용이 있는 요소의 경우, SurfaceGui도 StarterGui 컨테이너 안에 있어야 하며, Adornee 속성이 3D 작업 공간의 적절한 파트와 연결되어야 합니다. 이렇게 하면 버튼 이벤트를 추가할 수 있습니다.
패럴랙스 효과를 달성하기 위해, 우리는 서로 다른 X 값을 가진 세 개의 개별 ScreenGui 인스턴스를 사용했습니다.

그런 다음 SurfaceGui.LightInfluence 속성으로 빛나는 효과를 추가했습니다. 이 속성 값을 1보다 낮게 설정하면 SurfaceGui.Brightness 속성이 활성화됩니다. 밝기를 조정함으로써 이미지에서 나오는 빛을 증가시킬 수 있습니다.
사용자들이 지도를 표시하거나 숨길 수 있도록 하기 위해, 우리는 3D 모델에 부착된 ProximityPrompt를 사용했습니다. 이는 사용자가 세계 요소와 상호작용할 수 있는 간단한 방법입니다.

마지막으로, ReplicatedStorage 안에 UITweenModule 모듈 스크립트를 사용하여 TweenService와 상태 결정 로직을 약간 사용해 UI를 숨기고 표시하는 애니메이션을 만들었습니다. 사용자가 클릭한 내용을 추적함으로써 다양한 속성(알파, 위치 및 크기 등)을 트윈하여 요소를 숨기고 표시할 수 있었습니다.
UITweenModule 모듈 스크립트local TweenService = game:GetService("TweenService")local UITween = {}-- 이미지를 페이드 아웃하기 위한 함수function UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --시간Enum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --반복 횟수false, --true일 경우 반전delay --지연 시간)local tween = TweenService:Create(object, tweenAlpha, {Transparency = amount})tween:Play()endfunction UITween.fade(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --시간Enum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --반복 횟수false, --true일 경우 반전delay --지연 시간)local tween = TweenService:Create(object, tweenAlpha, {ImageTransparency = amount})tween:Play()end-- 이미지를 페이드 아웃하기 위한 함수function UITween.fadeBackground(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --시간Enum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --반복 횟수false, --true일 경우 반전delay --지연 시간)local tween = TweenService:Create(object, tweenAlpha, {BackgroundTransparency = amount})tween:Play()end-- 텍스트를 페이드 아웃하기 위한 함수function UITween.fadeText(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --시간Enum.EasingStyle.Quad, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --반복 횟수false, --true일 경우 반전delay --지연 시간)local tween1 = TweenService:Create(object, tweenAlpha, {TextTransparency = amount})tween1:Play()end-- 텍스트와 이미지를 이동시키기 위한 함수function UITween.move(object, position, time, delay)task.wait(delay)object:TweenPosition(position, Enum.EasingDirection.Out, Enum.EasingStyle.Quint, time)end-- 크기를 변경하기 위한 함수function UITween.size(object, size, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --시간Enum.EasingStyle.Quint, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --반복 횟수false, --true일 경우 반전delay, --지연 시간override,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, --시간Enum.EasingStyle.Quint, --EasingStyleEnum.EasingDirection.Out, --EasingDirection0, --반복 횟수false, --true일 경우 반전delay, --지연 시간override,callback)local tween = TweenService:Create(object, tweenSize, {Rotation = rotation})tween:Play()end-- 게임 카메라 흐림 효과를 위한 함수function 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-- 게임 카메라 밝기 조절을 위한 함수function 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 UITween객체에 UI 트윈 적용하기local ReplicatedStorage = game:GetService("ReplicatedStorage")-- UITween 모듈 추가local UITween = require(ReplicatedStorage.UITweenModule)-- 플레이어 GUI 및 UI 객체 찾기local playerGui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')local screenGuiMapUIFrame = playerGui:WaitForChild("ScreenGuiMapUIFrame").SurfaceGuilocal mapUIFrameStroke = screenGuiMapUIFrame.FrameStrokelocal mapUIFrameFill = screenGuiMapUIFrame.FrameFill-- 트윈에 사용되는 사이즈local frameSizeStart = UDim2.new(0, 0, 0, 0)local frameSizeMid = UDim2.new(1, 0, 0.05, 0)local frameSizeEnd = UDim2.new(1, 0, 1, 0)-- 예제 트위닝UITween.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)
여기 상호작용이 가능한 지도의 최종 결과물이 있습니다: