我们想添加一个可交互的地图用户界面,让用户在空间站中消费看起来和感觉像生活在这个世界的信息。我们决定在 3D 空间内建造地图,而不是在覆盖体验的屏幕上。这种类型的沉浸式视觉可以让你更深入地与世界接触,而不是让你感觉像是完全分离的体验。
设计地图
要设计地图:
我们在外部应用中嘲讽了 UI,并提出了一个粗略的想法,我们想要它看起来是什么样子。
我们将地图的个别部分导出为 .png 并导入到 Studio。
构建地图
在 Studio 内构建地图涉及使用 Parts 和 SurfaceGuis 。
对于非互动元素,我们需要做的就是将 SurfaceGui 对象添加到零件。
对于互动元素,SurfaceGui 也需要位于 StarterGui 容器内,其 Adornee 属性链接到 3D 工作区中的相应部分。这样做可以让你添加按钮事件。
为了实现渐变效果,我们使用了三个独立的 ScreenGui 实例分配给三个独特的 Parts 与不同的 X 值。
然后我们添加了 SurfaceGui.LightInfluence 属性的发光效果。如果您将属性值设置为 1 以下任何值,它会启用 SurfaceGui.Brightness 属性。通过调整亮度,你可以增加图像发出的辉光。
要让用户切换地图显示,我们使用了我们附加到 3D 模型上的 ProximityPrompt 。这是一种简单的方式来允许用户与世界元素互动。
最后,使用 ReplicatedStorage 中的 UITweenModule 模块脚本模块脚本动画隐藏和显示用户界面,并使用 TweenService 和一点点的逻辑来确定状态。通过跟踪用户单击了哪些元素,我们可以通过渐变各种属性,例如 Alpha、位置和大小,来隐藏和显示元素。
UITweenModule 模块脚本local 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, --如果真实,反转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, --如果真实,反转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, --如果真实,反转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, --如果真实,反转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, --如果真实,反转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, --如果真实,反转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)-- 找到玩家图形用户界面和界面对象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)
这是互动地图的最终结果: