我们想添加一个交互式地图用户界面,让用户能够在空间站中消费信息,并且感觉像是它生活在这个世界中。我们决定在3D空间内构建地图,而不是在覆盖体验的屏幕上进行显示。这种具现化的可视化方式比起感觉像是一个完全独立的体验,可以带来更多的沉浸感。
设计地图
设计地图的步骤:
我们在外部应用程序中模拟了用户界面,并提出了我们想要的外观的粗略想法。

我们将地图的各个部分导出为.png文件,并将它们导入到Studio中。

构建地图
在Studio中构建地图涉及使用Parts和SurfaceGuis。
对于非交互式元素,我们只需要向该部分添加一个SurfaceGui对象。
对于交互式元素,SurfaceGui还需要位于StarterGui容器内,并且Adornee属性链接到3D工作区中的相应部分。这样做可以让你添加按钮事件。
为了实现视差效果,我们使用三个分别分配给三个具有不同X值的ScreenGui实例。

然后,我们使用SurfaceGui.LightInfluence属性添加发光效果。如果将属性值设置为小于1的任何值,它将启用SurfaceGui.Brightness属性。通过调整亮度,你可以增加图像发出的光辉。
为了让用户切换地图的显示,我们使用了一个ProximityPrompt,并将其附加到一个3D模型上。这是一种轻松允许用户与世界元素互动的方法。

最后,通过在ReplicatedStorage中使用UITweenModule ModuleScript,我们使用TweenService和一些逻辑来确定状态,动画化UI的隐藏和显示。通过跟踪用户的点击,我们能够通过Tween变化来隐藏和显示元素的各种属性,例如透明度、位置和大小。
UITweenModule ModuleScriptlocal TweenService = game:GetService("TweenService")local UITween = {}-- 用于淡出图像function UITween.fadePart(object, amount, time, delay)local tweenAlpha = TweenInfo.new(time, --时间Enum.EasingStyle.Quad, --缓动样式Enum.EasingDirection.Out, --缓动方向0, --重复次数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, --缓动样式Enum.EasingDirection.Out, --缓动方向0, --重复次数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, --缓动样式Enum.EasingDirection.Out, --缓动方向0, --重复次数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, --缓动样式Enum.EasingDirection.Out, --缓动方向0, --重复次数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, --缓动样式Enum.EasingDirection.Out, --缓动方向0, --重复次数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, --缓动样式Enum.EasingDirection.Out, --缓动方向0, --重复次数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 Tween应用于对象local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 添加UITween模块local UITween = require(ReplicatedStorage.UITweenModule)-- 查找玩家Guis和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)
这是交互式地图的最终结果: