Chúng tôi muốn thêm một giao diện bản đồ tương tác để cho phép người dùng tiêu thụ thông tin trong trạm không gian mà trông và cảm thấy như nó sống trong thế giới này. Chúng tôi quyết định xây dựng bản đồ bên trong không gian 3D thay vì trên một màn hình phủ lên trải nghiệm. Loại hình trực quan diegetic này cho phép trải nghiệm một cách đắm chìm hơn với thế giới thay vì cảm thấy như đó là một trải nghiệm hoàn toàn tách biệt.
Thiết kế bản đồ
Để thiết kế bản đồ:
Chúng tôi đã tạo mô phỏng giao diện trong một ứng dụng bên ngoài và đưa ra ý tưởng sơ bộ về cách chúng tôi muốn nó trông như thế nào.

Chúng tôi đã xuất các phần riêng lẻ của bản đồ dưới dạng .png và nhập chúng vào Studio.

Xây dựng bản đồ
Xây dựng bản đồ bên trong Studio liên quan đến việc sử dụng Parts và SurfaceGuis.
Đối với các phần không tương tác, tất cả những gì chúng tôi cần làm là thêm một đối tượng SurfaceGui vào phần đó.
Đối với các phần tương tác, SurfaceGui cũng cần phải nằm trong chứa StarterGui, với thuộc tính Adornee liên kết với phần phù hợp trong không gian 3D. Làm như vậy cho phép bạn thêm các sự kiện nút bấm.
Để đạt được hiệu ứng parallax, chúng tôi đã sử dụng ba thể hiện ScreenGui riêng biệt gán cho ba Parts độc đáo với các giá trị X khác nhau.

Chúng tôi đã thêm một hiệu ứng phát sáng với thuộc tính SurfaceGui.LightInfluence. Nếu bạn đặt giá trị thuộc tính dưới 1, nó sẽ kích hoạt thuộc tính SurfaceGui.Brightness. Bằng cách điều chỉnh độ sáng, bạn có thể tăng cường ánh sáng phát ra từ hình ảnh.
Để cho phép người dùng chuyển đổi hiển thị bản đồ, chúng tôi đã sử dụng ProximityPrompt mà chúng tôi gắn vào một mô hình 3D. Đây là một cách dễ dàng để cho phép người dùng tương tác với các yếu tố của thế giới.

Cuối cùng, bằng cách sử dụng một ModuleScript UITweenModule bên trong ReplicatedStorage, chúng tôi đã hoạt hình việc ẩn và hiển thị giao diện với TweenService và một chút logic để xác định trạng thái. Bằng cách theo dõi những gì người dùng đã nhấp, chúng tôi có thể ẩn và hiển thị các yếu tố bằng cách tweening các thuộc tính khác nhau như alpha, vị trí và kích thước.
ModuleScript UITweenModulelocal TweenService = game:GetService("TweenService")local UITween = {}-- cho việc làm mờ hình ảnhfunction UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --Thời gianEnum.EasingStyle.Quad, --Phong cách làm mờEnum.EasingDirection.Out, --Hướng làm mờ0, --Số lần lặpfalse, --Đảo ngược nếu đúngdelay --Thời gian chờ)local tween = TweenService:Create(object, tweenAlpha, {Transparency = amount})tween:Play()endfunction UITween.fade(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --Thời gianEnum.EasingStyle.Quad, --Phong cách làm mờEnum.EasingDirection.Out, --Hướng làm mờ0, --Số lần lặpfalse, --Đảo ngược nếu đúngdelay --Thời gian chờ)local tween = TweenService:Create(object, tweenAlpha, {ImageTransparency = amount})tween:Play()end-- cho việc làm mờ nềnfunction UITween.fadeBackground(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --Thời gianEnum.EasingStyle.Quad, --Phong cách làm mờEnum.EasingDirection.Out, --Hướng làm mờ0, --Số lần lặpfalse, --Đảo ngược nếu đúngdelay --Thời gian chờ)local tween = TweenService:Create(object, tweenAlpha, {BackgroundTransparency = amount})tween:Play()end-- cho việc làm mờ văn bảnfunction UITween.fadeText(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --Thời gianEnum.EasingStyle.Quad, --Phong cách làm mờEnum.EasingDirection.Out, --Hướng làm mờ0, --Số lần lặpfalse, --Đảo ngược nếu đúngdelay --Thời gian chờ)local tween1 = TweenService:Create(object, tweenAlpha, {TextTransparency = amount})tween1:Play()end-- cho việc di chuyển văn bản và hình ảnhfunction UITween.move(object, position, time, delay)task.wait(delay)object:TweenPosition(position, Enum.EasingDirection.Out, Enum.EasingStyle.Quint, time)end-- cho việc thay đổi kích thướcfunction UITween.size(object, size, time, delay, override, callback)local tweenSize = TweenInfo.new(time, --Thời gianEnum.EasingStyle.Quint, --Phong cách làm mờEnum.EasingDirection.Out, --Hướng làm mờ0, --Số lần lặpfalse, --Đảo ngược nếu đúngdelay, --Thời gian chờ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, --Thời gianEnum.EasingStyle.Quint, --Phong cách làm mờEnum.EasingDirection.Out, --Hướng làm mờ0, --Số lần lặpfalse, --Đảo ngược nếu đúngdelay, --Thời gian chờoverride,callback)local tween = TweenService:Create(object, tweenSize, {Rotation = rotation})tween:Play()end-- cho việc làm mờ camera của trò chơifunction 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-- cho việc bật sáng camera của trò chơifunction 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Áp dụng tween UI cho các đối tượnglocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Thêm Module UITweenlocal UITween = require(ReplicatedStorage.UITweenModule)-- Tìm giao diện và các đối tượng UI của người chơilocal playerGui = game:GetService('Players').LocalPlayer:WaitForChild('PlayerGui')local screenGuiMapUIFrame = playerGui:WaitForChild("ScreenGuiMapUIFrame").SurfaceGuilocal mapUIFrameStroke = screenGuiMapUIFrame.FrameStrokelocal mapUIFrameFill = screenGuiMapUIFrame.FrameFill-- Kích thước sử dụng cho 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)-- Ví dụ 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)
Dưới đây là kết quả cuối cùng của bản đồ tương tác: