在工作室中实现设计

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

实现您的设计 是 Studio 中使用内置和自定义 UI 元素与脚本来创建您的网格的过程。 这个教程的令人激动的部分是您可以在本教程的任何时候看到所有您的设计并且准备好玩家交互的工作流程。

使用 样本激光标记体验.rbxl 文件作为参考,此部分用户界面设计课程向您展示如何将您的 UI 计划带到生命,包括指导:

  • 从 UI 资产库中检索资产 ID ,以便您可以重现示例激光标签体验的 UI 组件。
  • 在工作室中直接模拟各种设备,以便看到您的用户界面在不同屏幕和视角比例上显示。
  • 创建 ScreenGuiSurfaceGuiBillboardGui 对象,显示您的 UI 在玩家的屏幕、零件表面和 3D 空间中, respective.

在本节后,您可以将技术应用到您自己的项目上,以创建令人兴奋的用户界面组件,帮助玩家在您的体验中导航他们可以做的事情。

获取资产库

资产库是您可以添加到您的库存以获得简单访问和重用的资产集。您项目从创建者商店中使用的资产库包含九个 2D 个独立 UI 元素资产,并且您在此部分的教程中创建的目标、blaster选择器和玩家信息组件的最终版本。

MultiBlaster 图标 rbxassetid://14309094777
单击器图标 rbxassetid://14309094641
粉红队图标 rbxassetid://14309678581
陷阱线索 rbxassetid://14304828203
反向三角形陷阱 rbxassetid://14304827304
绿色队伍图标 rbxassetid://14309678701
渐变 rbxassetid://14304826876
多向渐变 rbxassetid://14304827147
爆炸按钮图标 - 默认 rbxassetid://18308375067
爆炸按钮图标 - 按下 rbxassetid://18308372597
箭头图标 rbxassetid://14400935532
命中标记图标 rbxassetid://14401148777
六角形 rbxassetid://14462567943
选择箭头图标 rbxassetid://14309187282
边框渐变 rbxassetid://14309518632

您可以在 Studio 中将大多数图书添加到您的库存中,通过单击以下部件中的 添加到库存 链接。一旦资产在您的道具中,您可以在平台上的任何项目中重用它们。


要将资产库从您的库存中获得到您的体验:

  1. 在菜单栏中,选择 视图 标签。

  2. 显示 部分中,单击 工具箱 。显示 工具箱 窗口。

  3. 工具箱 窗口中,单击 物品栏 选项卡。显示 我的模型 排序显示。

  4. 单击下拉菜单,然后选择 My Packages 排序。

  5. 单击 最终屏幕用户界面组件 地瓦片,然后在 Explorer 窗口中,选择 完成组件 ,然后拖动它们到1>StarterGui1>服务。现在您可以启用任何最终组件的设计。

模拟设备

Studio 的 设备模拟器 允许您测试玩家在各个设备上看到和与您的 UI 交互的方式。 此工具是实现过程中的重要组成部分,因为 Studio 的视窗在 Studio 的视窗中不 necessarily反映屏幕玩家使用您的体验的方面比例。 重要的是,您的 UI 应该在每个设备上都可以是可读的、可访问的。

例如,如果您不在多个屏幕尺寸上测试您的 UI,玩家可能无法读取您的文本或解码您的图标,并且小屏幕玩家可能无法看到 3D 空间,因为您的 UI 元素在显示上占用了太多空间。

要将屏幕缩放到最小屏幕尺寸:

  1. 在菜单栏中,选择 测试 标签。

  2. 模拟 部分中,单击 设备 。视窗更改为反映平均笔记本电脑外观比例的方面。

    Device button indicated in Test tab
  3. 在解析下拉菜单中,选择 实际分辨率 。这允许您在您模拟的设备上查看您的UI元素的真实分辨率。

  4. 在设备下拉列表中,选择拥有最小屏幕尺寸的设备,玩家可以使用它来访问您的体验。 尽管最佳选择会根据您的体验支持的设备变化,但示例激光标记体验使用 iPhone 4S 验证 UI 是否在有限屏幕空间内正确显示。

创建屏幕GUI对象

要在每个玩家的屏幕上显示 UI 元素,您可以在 ScreenGui 服务中创建一个 StarterGui 对象。 ScreenGui 对象是体验 UI 的主要容器,而 2>Class.PlayerGui2> 服务复制其内容到每个玩家的 <

您可以创建多个 ScreenGui 对象来组织和显示在游戏中的 UI 元素群组,以在游戏过程中在主要 ScreenGui 中遇到不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足不同条件时玩家满足

  • HUDGui - 显示玩家在回合中激活时的游戏体验关键信息,例如目标和每个团队的总得分。
  • PickABlasterGui - 显示玩家开始或重新加入回合时所有的冲击波选项。
  • ForceFieldGui - 显示六边形网格,当玩家选择一个冲击波并且暂时免疫时。
  • OutStateGui - 显示玩家标记出时屏幕周围的黑暗边界。
  • RoundResultsGui - 显示屏幕顶部的黑暗 overlay,包含哪个团队赢了该回合。

在创建一个 ScreenGui 对象后,您可以根据每个容器的目的来创建和自定义其子 GuiObjects 。 示例在即将到来的部分中展示,您将学习如何为三个类别的信息玩家需要成功在示例激光标签体验中知道的实

要创建一个 ScreenGui 对象:

  1. Explorer 窗口中,将鼠标悬停在 StarterGui 服务上,然后单击 图标。一个上下文菜单显示。

  2. 插入一个 屏幕游戏用户界面

  3. 根据子 UI 元素的上下文重命名 ScreenGUI

  4. 重复这个过程为每个屏幕上的玩家需要显示的 UI 元素。

目标用户界面

按照Wireframe Your Layouts的视觉层级最佳实践,此部分教您如何实现与体验目标相关的所有屏幕元素。此组合元素位于屏幕顶部,因为目标和每个团队的点有最大意义在于如何赢得游戏。

例如,样例提供玩家参考以了解他们在回合中成功的知识。当玩家标记出敌方队员并获得积分时,该组件跟踪每个团队伍的得分对于整个提示的目标。 对于跟踪积分的高级评论,请参阅跟踪积分在游戏脚本中的客户端和服务器脚本。

要在样本 激光标签 体验中精确重现目标用户界面:

  1. 创建一个容器以为整个组件创建一个容器。

    1. 在 HUDGui 对象中插入 框架

      1. 在 Explorer 窗口中,导航到 StarterGui 服务。
      2. 将鼠标悬停在其子对象上 HUDGui 对象上,然后单击 ⊕ 图标。一个上下文菜单显示。
      3. 从上下文菜单中,插入一个 框架
    2. 选择新的 框架 ,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0 以将框架的起始点设置在框架的中间顶部(从左到右框架的边缘 50%,从上到下框架的边缘 0%)。
      2. 背景透明度 设置为 1 使框架的背景完全透明。
      3. {0.5, 0},{0.03, 0}设置为0.5, 0,0.03, 0 以将屏幕顶部中间的框架设置为1> 0.5, 0,0.03, 01> 以设置屏幕顶部的屏幕框架(屏幕左端至右端的50%,屏幕顶端至屏幕左端的3%),以便在屏幕上有一个小缓冲器。
      4. 将大小设置为{0.5, 0},{0.13, 0},以便框架的元素占用屏幕顶部的大部分以吸引玩家的注意(50% horizontal,13% vertical)。
      5. 名称 设置为 目标
    3. (可选) 插入一个 UIAspectRatioConstraint目标 以确保标签的外观比例始终保持不变,无论玩家的屏幕大小。 样本将其 0> Class.UIAspectRatioConstraint.AspectRatio0> 属性设置为 3>7 3>。

  2. 创建一个容器以满足目标的提示对象。

    1. 插入一个 框架目标

    2. 选择新的 框架 ,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0 以将框架的起始点设置在框架的中间顶部(从左到右框架的边缘 50%,从上到下框架的边缘 0%)。
      2. 背景透明度 设置为 1 使框架的背景完全透明。
      3. 将位置设置为{0.5, 0},{0, 0},以将框架放置在容器中间(父框架从左到右的50%,并从上到下的父框架的0%)。
      4. 将大小设置为{1, 0},{0.67, 0},使选择用户界面组件占用容器从上到下的大部分(100% horizontal 和 67% vertical 的父框)。
      5. 名称 设置为 目标显示 .
  3. 创建标题元素。

    1. 图像标签 插入 目标显示

    2. 选择 图像标签 ,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 1 以在标签的标签底部中设置标签的起始点(从左到右标签左边 50% ,从右到标签右边 100%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 布局顺序 设置为 -1
      4. {0.5, 0},{0.34, 0}设置为0.5, 0,0.34, 0 以将标签设置在框架的顶部上中间(50%从左到右,父框从右到左)。
      5. 大小 设置为{0.46, 0},{0.34, 0}以宽扁平区域的提示区域为框架的几乎一半(46% horizontalmente和34% verticalmente的父框).
      6. 名称 设置为标题。
      7. 图像 设置为 rbxassetid://14304828123 显示楔形。
      8. 图像透明度 设置为 0.15 以使头衔半透明。
    3. (可选) 在 图像标签 中插入一个 UIAspectRatioLimit 以确保标签的外观比例始终保持不变,无论玩家的屏幕大小。 样例将其 0> Class.UIAspectRatioLimit.AspectRatio0> 属性设置为 3> 13.781 3>。

    4. 文本标签 插入 标题页 显示标题。

    5. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将新标签的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 将位置设置为{0.5, 0},{0.5, 0} 将标签移动到父标签的中间(父标签的左端至右端为 50%,父标签的上端至底端为 50%)。
      4. 大小 设置为{0.62, 0},{0.55, 0} 以宽涟文本空间到父标签的一半以上(62% 横向和55% 垂直)。
      5. 名称 设置为 头衔文本标签
      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。
      7. 重量 设置为 中等 以粗化字体。
      8. 文本 设置为 目标
      9. 启用 文本缩放
  4. 创建提示元素。

    1. 图像标签 插入 目标显示

    2. 选择 图像标签 ,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 1 以在标签的标签底部中设置标签的起始点(从左到右标签左边 50% ,从右到标签右边 100%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. {0.5, 0},{1, 0}设置为0.5, 0,1, 0 将标签移到父框的底部中间(父框的左侧至右侧,父框的顶部至底部)。
      4. 将大小设置为{0.89, 0},{0.66, 0},以宽扁文本空间到达父框的全宽度(89%水平和66%垂直)。
      5. 名称 设置为 身体 .
      6. 图像 设置为 rbxassetid://14304827265 显示上下游戏轨道。
      7. 图像颜色3 设置为 0, 0, 0 为了给图像上色。
      8. 图像透明度 设置为 0.3 以使头条半透明。
    3. (可选) 在 图像标签 中插入一个 UIAspectRatioConstraint 以确保标签的外观比例始终保持不变,无论玩家的屏幕大小。 样例将其 0> Class.UIAspectRatioConstraint.AspectRatio0> 属性设置为 3> 13.781 3>。

    4. 文本标签 插入 身体 以显示提示。

    5. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将新标签的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 将位置设置为{0.5, 0},{0.5, 0} 将标签移动到父标签的中间(父标签的左端至右端为 50%,父标签的上端至底端为 50%)。
      4. 大小 设置为{0.85, 0},{0.39, 0},以宽扁文本空间到达父标签的一半(85%水平和39%垂直)。
      5. 名称 设置为 BodyTextLabel
      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。
      7. 重量 设置为 中等 以粗化字体。
      8. 将 TextColor3 设置为 255, 255, 255 使文本在黑暗背景上与白色字体相对应。
      9. 文本 设置为 标记对玩家得分!第一支获得 %d 分的队伍获胜。 10. 启用 文本缩放
  5. 创建一个为目标团队计数器创建容器。

    1. 插入一个 框架目标

    2. 选择新的 框架 ,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 1 以在标签的原始点在框架的中间下部(从左到右框架的 50% 到右框架的 100%)。
      2. 背景透明度 设置为 1 使框架的背景完全透明。
      3. 将位置设置为{0.5, 0},{1, 0} 以将框架设置在容器的左中间(父框架的左后50%,并且父框架的右后100%)。
      4. 将大小设置为{0.44, 0},{0.27, 0},使选择用户界面组件从左到右的容器中的大小比例为44%(横向44%和垂直向27%)。
      5. 名称 设置为 TeamPointCounter
  6. 为团队计数器创建垫子。

    1. UIListLayout 对象插入从步骤 5 到步骤 6 的框架。
    2. 选择 UIListLayout 对象,然后在 属性 窗口中,
      1. 垫子 设置为 0.025, 0 为将未来团队计数器之间提供空间。
      2. FillDirection 设置为 横向 ,以便每个团队的柜台都能旁边旁边显示。
      3. HorizontalAlignment 设置为 中心 ,以便每个团队的橱柜都能对齐。
  7. 创建绿队反击元素。

    1. 图像标签 插入 TeamPointCounter

    2. 选择 图像标签 ,然后在 属性 窗口中,

      1. 背景透明度 设置为 1 使标签的背景完全透明。
      2. {0.5, 0},{1, 0}设置为0.5, 0,1, 0 将标签移到父框的底部中间(父框的左侧至右侧,父框的顶部至底部)。
      3. 大小 设置为{0.5, 0},{1, 0} 以宽度标签的一半宽度(50% 横向和 100% 垂直向)。
      4. 名称 设置为 TeamACount
      5. 图像 设置为 rbxassetid://14304826831 显示方向渐变。
      6. 图像颜色3 设置为 88, 218, 171 以涂色图像绿色。
    3. 配置一个自定义属性来跟踪这个标签是绿团队的。

      1. 属性 窗口中,导航到 属性 部分,然后单击“+”标志。弹出对话框显示。
      2. 名称 字段中,输入 团队颜色
      3. 类型 弹出菜单中,选择 BrickColor
      4. 点击 保存 按钮。
      5. 将新的 团队颜色 属性设置为 薄荷色
    4. 文本标签 插入 TeamACount器 以显示提示。

    5. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 1, 0.5 以在新标签的中间右侧设置新标签的起始点 (100% 从左到右标签,50% 从顶到标签)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. {0.95, 0},{0.5, 0}设置为 0.95, 0,0.5, 0 8>标签移动到父标签的右侧 (95%从左到右的父标签, 50%从顶到底的父标签)。
      4. 大小 设置为{0.85, 0},{0.39, 0},以宽扁文本空间到达父标签的一半(85%水平和39%垂直)。
      5. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。
      6. 重量 设置为 bold 以增加字体的厚度。
      7. 将 TextColor3 设置为 255, 255, 255 使文本在黑暗背景上与白色字体相对应。
      8. 文本 设置为 -
      9. 启用 文本缩放
      10. 文本对齐 设置为 右侧
    6. 将 UIStroke 对象插入 TextLabel ,然后在 Properties 窗口中将 2>颜色2> 设置为 5> 8, 78, 525> 以轮廓黑绿色踪迹。

  8. 创建粉队伍对象。

    1. 复制 TeamAICount 和它的子女。

    2. 选择重复的 TeamACount ,然后在 속性 窗口中

      1. 名称 设置为 TeamBCount
      2. 图像 设置为 rbxassetid://14305849451 显示方向矢量渐变在相反方向。
      3. 颜色图层3 设置为 255, 170, 255 以涂色图层粉红。
      4. 团队颜色 属性设置为 樱桃粉
    3. 选择 TextLabelTeamBCount ,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0, 0.5 以在左中间的新标签的起始点(从左到右标签的左到右,从上到下标签的顶部到下标签的底部)为新标签的原始点。
      2. 将位置设置为{0.05, 0},{0.5, 0} 将标签移动到父标签的左侧 (父标签的左端从左到右移动 5% ,父标签的右端从上到下移动 50%)。
      3. TextXAlignment 设置为 左侧
    4. 选择 UIStrokeTeamBCount ,然后在 属性 窗口中将 1>颜色1> 设置为 4> 158, 18, 944> 来轮廓黑色粉色踪迹。

  9. 在示例 ReplicatedStorage 位置文件中,参考以下 Class.ReplicatedStorage 脚本。它们程序更新目标提示和跟踪团队点。

下面的脚本需要一个组 of 模块脚本 工作 together to set up the main Heads Up Display (HUD),包括 setObjectivestartSyncingTeamPoints 。 后一个玩家加入 a round 并选择他们的 blaster,这脚本确保所有 HUD UI 元素显示适当的状态、设备和团队状态。


local Players = game:GetService("Players")
local setPlayerPortrait = require(script.setPlayerPortrait)
local setPlayerName = require(script.setPlayerName)
local startSyncingTeamColor = require(script.startSyncingTeamColor)
local setObjective = require(script.setObjective)
local setupTouchButtonAsync = require(script.setupTouchButtonAsync)
local startSyncingTeamPoints = require(script.startSyncingTeamPoints)
local disableMouseWhileGuiEnabled = require(script.disableMouseWhileGuiEnabled)
local setupHitmarker = require(script.setupHitmarker)
local localPlayer = Players.LocalPlayer
local gui = localPlayer.PlayerGui:WaitForChild("HUDGui")
setPlayerPortrait(gui)
setPlayerName(gui)
startSyncingTeamColor(gui)
setObjective(gui)
startSyncingTeamPoints(gui)
disableMouseWhileGuiEnabled(gui)
setupHitmarker(gui)
setupTouchButtonAsync(gui)

Blaster 用户界面

按照Wireframe Your Layouts的视觉层级最佳实践,此部分教您如何实现所有与玩家的 Blaster 相关的屏幕 UI 元素。 组合 UI 元素的屏幕空间占用了屏幕空间的大部分,因为它作为中心点向玩家注意3D空间中的行动,并且有最大意义玩游戏。

十字箭头

枪口是一个用户界面元素,可以告诉玩家他们将在哪里造成影响,当他们使用武器时会爆炸。 此 UI 元素是第一人称射击体验的关键游戏要求,因为玩家需要能够准确瞄准他们的武器并标记出敌人的团队成员。

与其他第一人称射击游戏体验类似,样本激光标记体验位置在屏幕中心,让玩家有 something静止的焦点,而且他们的虚拟形象在 3D 空间中移动。 除了减少运动 sickness 外,这个布局允许 crosshair 在移动到 3D 环境间中时可以被感知。

要在样本 激光标签 体验中精确重现箭头:

  1. 图像标签 插入 HUDGui 对象 ScreenGui

    1. 在 Explorer 窗口中,导航到 StarterGui 服务。

    2. 将鼠标悬停在其子对象上 HUDGui ,然后单击 标志。一个上下文菜单显示。

    3. 从上下文菜单中,插入一个 图像标签

  2. 选择新的 图像标签 ,然后在 属性窗口 中,

    1. 图像 设置为 rbxassetid://14400935446
    2. AnchorPoint 设置为 0.5, 0.5 以将标签的标签标记中间的标签原始点 (50% 从左到右标签, 50% 从上到下标签)。
    3. 背景透明度 设置为 1 使标签的背景完全透明。
    4. 名称 设置为 箭头 .
    5. 位置设置{0.5,0},{0.5,0} 以设置标签在屏幕中间。
    6. ScaleType 设置为 Fit ,以便图像在其容器内容纳,并且在各个屏幕尺寸上不会伸展。
  3. (可选) 在 箭头 上插入一个 UIAspectRatioConstraint 以确保标签的外观比例在玩家屏幕大小无论如何保持一致。 样例将其 0> Class.UIAspectRatioConstraint.AspectRatio0> 属性设置为 3>0.895 3>。

命中标记

命中标记是一个 UI 元素,只会在爆炸与另一名玩家在敌方团队上造成影响时显示。 像箭头一样,这个 UI 元素是首人称射击体验的关键游戏要求,因为它提供视觉反馈,当玩家成功标记出对手时提供视觉反馈。

要在样本 激光标签 体验中精确重现命中标记:

  1. 图像标签 插入 十字箭头 ImageLabel 对象。

    1. 在 Explorer 窗口中,导航到 StarterGui 服务。

    2. 将鼠标悬停在其子对象 箭头 上,然后单击 标志。一个上下文菜单显示。

    3. 从上下文菜单中,插入一个 图像标签

  2. 选择新的 图像标签 ,然后在 属性窗口 中,

    1. 图像 设置为 rbxassetid://14401148736 显示长方形命中标记标志。
    2. AnchorPoint 设置为 0.5, 0.5 以将标签的起始点设置在标签中间的中间。
    3. 背景透明度 设置为 1 使标签的背景完全透明。
    4. 位置设置{0.5,0},{0.5,0} 以设置标签在屏幕中间。
    5. 名称 设置为 命中标记
    6. 大小 设置为{0.6, 0},{0.06, 0} 以减少交叉箭头中央的长方形的大小。
    7. 将图像透明度设置为1 使命标记完全透明。在下一步的脚本将每次玩家的爆炸与另一名敌人队团队打击时恢复透明度。
  3. 在示例 ReplicatedStorage 中参考以下脚本 激光标签 位置文件,程序显示击中标记, когда激光与玩家在敌方团队伍中造成冲击。

下面的脚本需要一些模块脚本,它们可以协作以设置主要的头显示(HUD),包括 setupHitmarker 。 一旦玩家加入回合并选择他们的冲击波,这个脚本确保所有的HUD UI元素都显示适当地显示状态、设备和团队状态。


local Players = game:GetService("Players")
local setPlayerPortrait = require(script.setPlayerPortrait)
local setPlayerName = require(script.setPlayerName)
local startSyncingTeamColor = require(script.startSyncingTeamColor)
local setObjective = require(script.setObjective)
local setupTouchButtonAsync = require(script.setupTouchButtonAsync)
local startSyncingTeamPoints = require(script.startSyncingTeamPoints)
local disableMouseWhileGuiEnabled = require(script.disableMouseWhileGuiEnabled)
local setupHitmarker = require(script.setupHitmarker)
local localPlayer = Players.LocalPlayer
local gui = localPlayer.PlayerGui:WaitForChild("HUDGui")
setPlayerPortrait(gui)
setPlayerName(gui)
startSyncingTeamColor(gui)
setObjective(gui)
startSyncingTeamPoints(gui)
disableMouseWhileGuiEnabled(gui)
setupHitmarker(gui)
setupTouchButtonAsync(gui)

激光选择器

一个选择器激光是玩家在加入或重新加入回合之前选择其激光类型的 UI 组件。 示例激光标签体验提供两种激光类型:一个生成多个光束并且覆盖横向布局的激光,另一个生成单个光束。 玩家选择的激光类型在回合中影响其策略,因此该 UI 组件是整个体验的关键工作流程。

下面的步骤详细描述如何为各个UI元素群组创建多个容器,有提示的标题、导航和选择按钮,以及一个预制按钮。 脚本逻辑对整个组件的组件人口根据 Configuration 实例代表每个组件类输入的 blaster 按钮进行弹出。

此设置允许您为更多的冲击型机器人创建额外的 Configuration 实例,因为它们在冲击选择器中自动显示正确,而无需在 StarterGui.PickABlasterGui 中创建个별按钮。

要在样本 激光标签 体验中精确重现激光选择器:

  1. 创建一个容器以为整个组件创建一个容器。

    1. 在 选择器能量框 中插入一个 框子ScreenGui 对象。

      1. 在 Explorer 窗口中,导航到 StarterGui 服务。
      2. 将鼠标悬停在其子对象上 选择激光器 对象,然后单击 标志。 上下文菜单显示。
      3. 从上下文菜单中,插入一个 框架
    2. 选择新框架,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 1 以将框架的起始点在框架底部中间设置为 (50% 从左到右,100% 从右到左)。
      2. 背景透明度 设置为 1 使框架的背景完全透明。
      3. 将位置设置为{0.5, 0},{0.9, 0} 以将屏幕框架放置在屏幕中间的底部(屏幕左侧至右侧50%,屏幕右侧至屏幕底部92.4%)。
      4. 将大小设置为{0.8, 0},{0.25, 0},以便 blaster 选择器的 UI 组件占用大部分屏幕,吸引玩家的注意(80% horizontal,25% vertical)。
      5. 名称 设置为 组件
    3. (可选) 在 组件 中插入一个 UIAspectRatioLimit 以确保框架和其子 UI 元素的外观比例保持不变,无论玩家的屏幕大小。 样例将其 0> Class.UIAspectRatioLimit.AspectRatio0> 属性设置为 3> 5 3>。

  2. 创建一个容器来持有 UI 元素群组。

    1. 框子 插入 组件

    2. 选择新框架,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将框架的起始点设置在框架中间(从左到右框架的边缘 50%,从上到下框架的边缘 50%)。
      2. 背景透明度 设置为 1 使框架的背景完全透明。
      3. {0.5, 0},{0.375, 0}设置为0.5, 0,0.375, 0 以将框架靠近容器顶部中间 (50% 从左 到右 的父 框, 37.5% 从上 到下 的父 框)。
      4. 大小 设置为{1, 0},{0.75, 0} ,使选择用户界面组件占用容器的 3/4(100% 垂直于父框,75% 垂直于父框)。
      5. 名称 设置到 选择框架
  3. 创建一个对冲击波选择器的提示。

    1. 图像标签 插入 选择框

    2. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 1 以在标签的标签底部中设置标签的起始点(从左到右标签左边 50% ,从右到标签右边 100%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 布局顺序 设置为 -1
      4. {0.5, 0},{0.22, 0}设置为0.5, 0,0.22, 0 以将标签设置在框架的顶部上中间(50%从左到右,父框从右到左)。
      5. 大小 设置为{0.45, 0},{0.22, 0} 以宽扁提示区域的边框(45% 横向和 22% 垂直向)。
      6. 名称 设置为 标题
      7. 图像 设置为 rbxassetid://14304828123 显示楔形。
      8. 图像透明度 设置为 0.15 以使头衔半透明。
    3. (可选) 在标签中插入一个 UIAspectRatioConstraint 以确保标签的外观比例始终保持不变,无论玩家的屏幕大小。 样例将其 UIAspectRatioConstraint.AspectRatio 属性设置为 0>13.780>。

    4. 文本标签 插入 头谈 以显示提示。

    5. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将新标签的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 将位置设置为{0.5, 0},{0.5, 0} 将标签移动到父标签的中间(父标签的左端至右端为 50%,父标签的上端至底端为 50%)。
      4. 大小 设置为{0.6, 0},{0.55, 0} 以宽涟文本空间到父标签的一半以上(60% 横向和55% 垂直)。
      5. 名称 设置为 头衔文本标签
      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。
      7. 重量 设置为 中等 以粗化字体。
      8. 文本 设置为 选择一个冲击波
      9. 启用 文本缩放
  4. 创建您的 Blaster 按钮容器和选择箭头。

    1. 图像标签 插入 选择框

    2. 选择新标签,然后在 属性 窗口中,

      1. 移除默认值 图像
      2. AnchorPoint 设置为 0.5, 1 以在标签的标签底部中设置标签的起始点(从左到右标签左边 50% ,从右到标签右边 100%)。
      3. 背景颜色 设置为 0, 0, 0 使标签黑色。
      4. 背景透明度 设置为 0.3 以减少标签的不透明度,并在体验中匹配所有黑色 UI 元素。
      5. 将位置设置为{0.5, 0},{1, 0},将标签设置为父框的左侧中间(父框的左侧距离离开到右侧的60%,右侧距离离开到父框的100%)。
      6. 大小 设置为{1, 0},{0.77, 0} 以宽润标签区域到达提示下方的空间(100%水平和77%垂直)。
    3. 将容器的角落圆化。

      1. 在标签中插入一个 UICorner 对象。
      2. 选择新的角对象,然后在 属性 窗口中,将 角圆半径 设置为 0.075, 0 以圆形2>。
  5. 创建您的 Blaster 按钮的容器。

    1. 在步骤 4 中插入一个 框架 到标签。

    2. 选择新框架,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将新框架的起始点设置在框架中间(从左到右框架的左侧到右侧,从上到下框架的顶部到底)。
      2. 背景透明度 设置为 1 使框架的背景完全透明。
      3. 将位置设置为{0.5, 0},{0.5, 0} 以将框架放置在父框架的中间 (50% 从左 到 右 的父框架, 50% 从上 到 下 的父框架)。
      4. 大小 设置为 {0.85, 0},{0.77, 0} 以宽涵标签框的大部分标签区域 (85% 横向和 77% 垂直向的父标签).
      5. 名称 设置为 容器
  6. 为所有未来的冲击按钮创建垫子。

    1. UIListLayout 对象插入从步骤 5 到步骤 6 的框架。
    2. 选择新的布局对象,然后在 属性 窗口中,
      1. 将 垫子 设置为 0.035, 0 以提供所有未来按钮之间的空间。
      2. 填充方向 设置为 水平 ,以便每个按钮都能显示在每个按钮旁边。
      3. HorizontalAlignmentVerticalAlignment 设置为 中心 ,以便每个按钮都能相互对齐。
  7. 创建左侧导航按钮。

    1. 从步骤 4 插入一个 图像按钮 对象到 图像标签

    2. 选择新按钮,然后在 属性 窗口中,

      1. 移除默认值 图像
      2. AnchorPoint 设置为 0, 0.5 以在左中间的新按钮的起始点(从左到右的按钮 0% 从右到下的按钮 50%)。
      3. 背景透明度 设置为 0.15 以在鼠标悬停时提供视觉反馈,显示按钮可选择。
      4. 将 位置 设置为 {0.02, 0},{0.5, 0} 提供垫子来左侧按钮从其父容器 (2% 从左到右的父标签, 50% 从顶到底的父标签) 提供垫子。
      5. 大小 设置为 {0.04, 0},{0.33, 0} 使选择按钮小得多于冲击按钮 (4% 垂直于父框,33% 水平于父框)。
      6. 名称 设置为 导航按钮左侧
    3. 将按钮的角落圆化。

      1. 在按钮上插入一个 UICorner 对象。
      2. 选择新的角对象,然后在 属性 窗口中,将 CornerRadius 设置为 0.1, 0 以圆弧角。
    4. 图像标签 对象插入按钮。

    5. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将新标签的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。
      2. 位置 设置为 {0.45, 0},{0.5, 0} 将标签设置为 父按钮的中间 (45% 从左到右,父按钮的上半部 50%) 。此值不在中间,因为箭头不
      3. 大小 设置为 {0.8, 0},{0.8, 0} 以宽涟标签区域以下的空间 (80% 垂直于父框的 80% 横向)。
      4. 背景透明度 设置为 1 使图像的背景完全透明。
      5. 图像 设置为 rbxassetid://14309187238
      6. ScaleType 设置为 Fit
  8. 创建正确的导航按钮。

    1. 复制 导航按钮左侧

    2. 选择复制按钮,然后在 属性 窗口中,

      1. AnchorPoint 设置为 1, 0.5 以在右中间设置新按钮的起始位置(从左到右按钮的左端到右端,100%从左到右,50%从顶部到底)。
      2. 将 位置 设置为 {0.98, 0},{0.5, 0} 提供垫子在按钮的右侧 (从父容器 (98% 从左到右的父标签, 50% 从顶到底的父标签) 提供垫子。
      3. 名称 设置为 导航按钮右侧
    3. 选择其 图像标签 子对象。

      1. 旋转 设置为 180 以翻转图像。
      2. 位置 设置为 {0.55, 0},{0.5, 0} 将标签设置为 0.55, 0,0.5, 0 将标签设置为 1> 0.5, 0,0.5, 0
  9. 创建 选择 按钮。

    1. 图像按钮 插入 组件 。注意这个过程将选择按钮与 选择框 分开,以便您可以在选择按钮的主部分从选择按钮添加垫子。

    2. 选择新按钮,然后在 属性 窗口中,

      1. 移除默认值 图像
      2. AnchorPoint 设置为 0.5, 1 以在自身的底部中设置新按钮的起始位置(从左到右按钮的左侧到右侧 50%,从右到左的上方到下面 100%)。
      3. 背景透明度 设置为 0.15 以在鼠标悬停时提供视觉反馈,显示按钮可选择。
      4. {0.5, 0},{0.99, 0}设置为0.5, 0,0.99, 0 将按钮放置在容器底部中间(从左到右父框的左端到右端,从右到父框的左端到父框的右端)的位置。
      5. 大小 设置为{0.17, 0},{0.18, 0}以长按钮下方的按钮(17%水平和18%垂直)。
      6. 名称 设置为 选择按钮
    3. 将按钮的角落圆化。

      1. 在按钮上插入一个 UICorner 对象。
      2. 选择新的角对象,然后在 属性 窗口中,将 CornerRadius 设置为 0.2, 0 以圆弧角。
    4. 文本标签 对象插入按钮,以便您可以显示要求行动作。

    5. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将新标签的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 将位置设置为{0.5, 0},{0.5, 0} 将标签移到按钮的中间(父按钮的左侧至右侧50%,父按钮的顶部至底部50%)。
      4. 将大小设置为{0.9, 0},{0.55, 0}以宽涵文本空间到达父标签的宽度(90%横向和55%纵向)。
      5. 名称 设置为 SelectTextLabel
      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。
      7. 重量 设置为 中等 以粗化字体。
      8. 文本 设置为 选择
      9. 启用 文本缩放
  10. 创建一个 blaster 按钮预制。

    1. ReplicatedStorage 服务中,创建一个文件夹结构来组织您的UI对象。样例使用一个 实例 文件夹,其子文件夹为 Guis 文件夹。
    2. 将 图像按钮 对象插入 Guis 文件夹。
    3. 选择新按钮,然后在 属性 窗口中,
      1. 移除默认值 图像
      2. AnchorPoint 设置为 0.5, 0.5 以在新按钮的中间设置新按钮的起始点 (50% 从左到右的按钮, 50% 从上到下的按钮)。
      3. 背景透明度 设置为 0.65 提供视觉反馈,说明按钮不在焦点上。在步骤 12 中,脚本提供程序视觉反馈,当按钮处于焦点上。
      4. 布局顺序 设置为 2
      5. 名称 设置为 BlasterButtonPrefab
      6. 大小 设置为 {0.8, 0},{0.8, 0}
      7. 透明度图像 设置为 1 以使图像完全透明。
    4. UIAspectRatioConstraint 插入 BlasterButtonPrefab 以确保按钮的外观比例在组件内无论玩家的屏幕大小都保持相同。
    5. 将按钮的角落圆化。
      1. UICorner 对象插入 BlasterButtonPrefab
      2. 选择 UICorner ,然后在 属性 窗口中,将 CornerRadius 设置为1> 0.05, 01>以圆弧角。
    6. 图像标签 插入 BlasterButtonPrefab
    7. 选择新标签,然后在 属性 窗口中,
      1. 移除默认值 图像
      2. AnchorPoint 设置为 0.5, 0.5 以将新标签的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。
      3. 背景透明度 设置为 1 使标签的背景完全透明。
      4. 将 位置 设置为 {0.52, 0},{0.497, 0} 将标签设置为 0.5% 从左 到右 的父 按钮的中间, 49.7% 从上 到下 的父 按钮的
      5. 大小 设置为 {1.20, 0},{0.9, 0} 以宽涟标签区域外的按钮区域(120% 横向和 90% 垂直于父按钮)。
      6. ScaleType 设置为 Fit
  11. 在示例 ReplicatedStorage 位置文件中,参考以下 Class.ReplicatedStorage 脚本,程序显示按钮对于每个激光标记,在玩家选择不在焦点上的按钮时,将按钮缩放到按钮位置,并将玩家的 blaster 选择添加到他们的虚拟形象。

下面的脚本需要一些脚本来创建 blaster 选择器。当玩家加入体验或重生后回到回合后,玩家的生命值达到零时,这些脚本将启动 blaster 选择器的所有 UI 元素,直到玩家做出选择。


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GuiAttribute = require(ReplicatedStorage.GuiAttribute)
local setupBlasterButtons = require(script.setupBlasterButtons)
local connectResetSelectionOnEnabled = require(script.connectResetSelectionOnEnabled)
local localPlayer = Players.LocalPlayer
local gui = localPlayer.PlayerGui:WaitForChild("PickABlasterGui")
setupBlasterButtons(gui)
connectResetSelectionOnEnabled(gui)
gui:SetAttribute(GuiAttribute.selectedIndex, 1)

爆炸按钮

爆炸按钮是玩家使用移动或平板设备访问体验的爆炸功能的 UI 组件。 示例激光标记体验使用了一个带有箭头和爆炸按钮的图标来表示按钮的功能,无需文本来传达按钮的功能。

要在样本 激光标签 体验中完全重现爆炸按钮:

  1. 图像按钮 插入 HUDGui 对象 ScreenGui

    1. 在 Explorer 窗口中,导航到 StarterGui 服务。

    2. 将鼠标悬停在其子对象上 HUDGui ,然后单击 标志。一个上下文菜单显示。

    3. 从上下文菜单中,插入一个 图像按钮

  2. 在视图中,将按钮移动到玩家的手指自然放置的位置,然后在 属性 窗设备中,

    1. 图像 设置为 rbxassetid://18308375035 显示爆炸按钮标志。
    2. 按下图像 设置为 rbxassetid://18308372558 显示玩家按下按钮时显示反向版本的爆炸按钮图标。
    3. 背景透明度 设置为 1 使标签的背景完全透明。
    4. 名称 设置为 爆炸按钮 .
    5. ScaleType 设置为 Fit ,以便图像在其容器内容纳,并且在各个屏幕尺寸上不会伸展。
    6. 图像透明度 设置为 0.3 以减少标签的不透明度,使其与体验中的所有黑色 UI 元素匹配。
  3. UIAspectRatioConstraint 插入 BlastButton 以确保按钮的外观比例始终保持不变,无论玩家的屏幕大小。

  4. 在示例 ReplicatedStorage 位置文件中,参考以下 Class.ReplicatedStorage 脚本显示 blaster 按钮,当玩家使用触摸输入在设备上接受触摸控制时。

下面的脚本需要一些模块脚本,它们可以协同工作以设置主要的头显示(HUD),包括 setupTouchButtonAsync 。 一旦玩家加入回合并选择他们的冲击波,这个脚本确保所有的HUD UI元素都能够显示适当地为玩家的状态、设备和团队状态。


local Players = game:GetService("Players")
local setPlayerPortrait = require(script.setPlayerPortrait)
local setPlayerName = require(script.setPlayerName)
local startSyncingTeamColor = require(script.startSyncingTeamColor)
local setObjective = require(script.setObjective)
local setupTouchButtonAsync = require(script.setupTouchButtonAsync)
local startSyncingTeamPoints = require(script.startSyncingTeamPoints)
local disableMouseWhileGuiEnabled = require(script.disableMouseWhileGuiEnabled)
local setupHitmarker = require(script.setupHitmarker)
local localPlayer = Players.LocalPlayer
local gui = localPlayer.PlayerGui:WaitForChild("HUDGui")
setPlayerPortrait(gui)
setPlayerName(gui)
startSyncingTeamColor(gui)
setObjective(gui)
startSyncingTeamPoints(gui)
disableMouseWhileGuiEnabled(gui)
setupHitmarker(gui)
setupTouchButtonAsync(gui)

玩家界面

按照Wireframe Your Layouts的视觉层级最佳实践,此部分教您如何实现所有与玩家状态相关的屏幕上的 UI 元素。 此集合的 UI 元素位于屏幕的两侧,因为玩家可以通过从游戏中分散注意力来理解此边界信息。

玩家指示器

玩家标记是玩家参考到团队所在位置时快速解码团队所属团队的标记。 示例激光标签体验提供两种玩家标记依赖于玩家是否在 绿色粉色 团队上。

绿队
粉红队

按照选择颜色主题的指示,玩家指示器的两个版本都会将团队颜色与独特、简单的图标结合,以便在小屏幕上保持可读性。提供两种视觉反馈形式是重要的,因为它有助于让颜色盲症的玩家保持设计可访问。

要在样本 激光标签 体验中精确重现玩家标记组件:

  1. 在 HUDGui 对象中插入 框架

    1. 在 Explorer 窗口中,导航到 StarterGui 服务。
    2. 将鼠标悬停在其子对象上 HUDGui 对象上,然后单击 ⊕ 图标。一个上下文菜单显示。
    3. 从上下文菜单中,插入一个 框架
  2. 选择新的 框架 ,然后在 属性 窗口中,

    1. 锚定点 设置为 0, 1 以在框架的中间下部设置框架的起始点 (0% 从左到右,100% 从上到下)。

    2. 背景透明度 设置为 1 使标签的背景完全透明。

    3. 名称 设置为 玩家显示器

    4. 位置 设置为 {0.02, 0},{0.97, 0} 将框架设置为屏幕左下角的框架。

    5. 大小 设置为 {0.23, 0},{0.08, 0} 以缩短和宽度框架。

    6. 启用 ClipsDescendants 来切换子 GuiObjets 在框架之外延展到的子对象。

  3. 创建多边形状。

    1. 图像标签 插入 玩家显示

    2. 选择新标签,然后在 属性 窗口中,

      1. 图像 设置为 rbxassetid://14304828123 显示楔形标志。
      2. AnchorPoint 设置为 1, 1 以在标签的底部右侧设置标签的起始点(从左到右标签的左到右,100%从右到左)。
      3. 背景透明度 设置为 1 使标签的背景完全透明。
      4. 名称 设置为
      5. 位置 设置为 {1,0},{1,0} 将标签设置为框架的右侧。
      6. 大小 设置为{1.858, 0},{0.581, 0},以便在框架外的标签上宽度,并将其缩短为框架的一半以下。
      7. 透明度图像 设置为 0.15 以使标签略透明。
      8. ScaleType 设置为 Fit ,以便图像在其容器内容纳,并且在各个屏幕尺寸上不会伸展。
      1. UIAspectRatioConstraint 插入 以确保标签和其子 UI 元素的外观比例保持不变,无论玩家的屏幕大小。
      2. 选择新的约束,然后在 属性 窗口中,将 方向比 设置为 13.78
  4. 为玩家创建一个箱子以便画竖向。

    1. 图像标签 插入 玩家显示

    2. 选择新标签,然后在 属性 窗口中,

      1. 将其他资源ID置换为 图像 属性内。步骤 7 的脚本程序将玩家的肖像放入图像标签。
      2. AnchorPoint 设置为 0, 1 以在标签的左下角设置标签的起始点(从左到右标签的 0% 到右,从上到下标签的 100%)。
      3. 背景颜色3 设置为 0, 0, 0 以将标签的背景颜色设置为黑色。
      4. 背景透明度 设置为 0.3 以减少标签的不透明度,并在体验中匹配所有黑色 UI 元素。
      5. 名称 设置为 玩家肖像 .
      6. 位置 设置为 {0.11, 0},{1, 0} 将标签设置为 左侧多边形状状态。
      7. 大小 设置为 {0.23, 0},{1, 0} 以缩小标签。
      8. 透明度图像 设置为 0.15 以使标签略透明。
      9. ScaleType 设置为 Fit ,以便图像在其容器内容纳,并且在各个屏幕尺寸上不会伸展。
      1. UIAspectRatioConstraint 插入 PlayerPortrait 确保标签和其子 UI 元素的外观比例保持不变,无论玩家的屏幕大小。
      2. 将 UICorner 插入 PlayerPortrait ,然后在 属性 窗口中设置 2> 角度圆度2> 为 5> 0.05, 05> 以稍微圆化角落。
  5. 创建玩家的名称的文本标签。

    1. 文本标签 对象插入 玩家显示器

    2. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0, 0.5 以在左中间的新按钮的起始点(从左到右的按钮 0% 从右到下的按钮 50%)。
      2. 背景透明度 设置为 1 使标签的背景完全透明。
      3. 名称 设置为 PlayerNameTextLabel
      4. 将位置设置为{0.35, 0},{0.72, 0} 将标签设置为容器右侧(父标签的左侧35%,父标签的右侧72%)。
      5. 大小 设置为{0.52, 0},{0.3, 0},以便文本可以占领大多数方形形状区域(52%水平和30%垂直)。
      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。
      7. 重量 设置为 bold 以增加字体的厚度。
      8. 移除 文本 属性中的占位符文本。脚本在步骤 7 中程序化地将玩家的名称插入文本标签。
      9. 启用 文本缩放
      10. TextXAlignment 设置为 左侧
  6. 创建左侧玩家头竖向显示的团队图标和颜色。

    1. 文件夹 插入 玩家显示 ,然后重命名为 团队图标

    2. 创建 绿色 团队图标和颜色。

      1. 图像标签 插入 团队图标
      2. 选择新标签,然后在 属性 窗口中,
        1. AnchorPoint 设置为 0, 1 以在标签的左下角设置标签的起始点(从左到右标签的 0% 到右,从上到下标签的 100%)。
        2. 背景颜色3 设置为 88, 218, 171 来将标签的背景颜色设置为薄荷绿。
        3. 名称 设置为 TeamAIcon
        4. 位置 设置为 {0, 0},{1, 0} 将标签设置为框架的左侧。
        5. 大小 设置为 {0.135, 0},{0.58, 0} 以缩小标签的左侧玩家头竖向。
        6. 透明度图像 设置为 1 以使标签透明。
      1. 配置一个自定义属性来跟踪这个标签是绿团队的。这是步骤 7 中的关键。
        1. 属性 窗口中,导航到 属性 部分,然后单击“+”标志。弹出对话框显示。
        2. 名称 字段中,输入 团队颜色
        3. 类型 弹出菜单中,选择 BrickColor
        4. 点击 保存 按钮。
        5. 将新的 团队颜色 属性设置为 薄荷色
      2. UIAspectRatioConstraint 插入 TeamAIcon 以确保标签和其子 UI 元素的外观比例保持不变,无论玩家的屏幕大小。
      3. 创建标志。
        1. 图像标签 插入 团队图标
        2. 选择新标签,然后在 属性 窗口中,
          1. 图像 设置为 rbxassetid://14309678670 以显示绿色团队标志。
          2. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。
          3. 背景透明度 设置为 1 使标签的背景完全透明。
          4. 名称 设置为 图标 .
          5. 位置 设置为 {0.5, 0},{0.5, 0} 将标签设置为父标签的中间。
          6. 大小 设置为 {0.7, 0},{0.6, 0} 以缩小标签。
          7. ScaleType 设置为 Fit ,以便图像在其容器内容纳,并且在各个屏幕尺寸上不会伸展。
    3. 创建 粉红色 团队图标和颜色。

      1. 复制 TeamAIcon 和它的子女。
      2. 选择重复的 TeamAIcon ,然后在 속性 窗口中
        1. 背景颜色3 设置为 255, 170, 255 以将标签的背景颜色设置为番褐色粉。
        2. 名称 设置为 TeamBIcon
        3. 团队颜色 属性设置为 樱桃粉
        4. 选择团队图标 Icon 的重复子,然后在 属性 窗口中将 图像 设置为 2> rbxassetid://143096785492> 显示粉色团队标志。
  7. 在示例 ReplicatedStorage 中,参考 Class.ReplicatedStorage 脚本,显示在样本 Class.ReplicatedStorage 位置的程序显示玩家标记,并在玩家激活时显示相应的团队颜色和图标。

下面的脚本需要一些模块脚本,它们可以协同工作以设置主要的头显示(HUD),包括 startSyncingTeamColorsetPlayerNamesetPlayerPortrait。 在玩家加入回合并选择他们的冲击波后,这个脚本确保所有的HUD UI元素都能正确显示玩家的状态、设


local Players = game:GetService("Players")
local setPlayerPortrait = require(script.setPlayerPortrait)
local setPlayerName = require(script.setPlayerName)
local startSyncingTeamColor = require(script.startSyncingTeamColor)
local setObjective = require(script.setObjective)
local setupTouchButtonAsync = require(script.setupTouchButtonAsync)
local startSyncingTeamPoints = require(script.startSyncingTeamPoints)
local disableMouseWhileGuiEnabled = require(script.disableMouseWhileGuiEnabled)
local setupHitmarker = require(script.setupHitmarker)
local localPlayer = Players.LocalPlayer
local gui = localPlayer.PlayerGui:WaitForChild("HUDGui")
setPlayerPortrait(gui)
setPlayerName(gui)
startSyncingTeamColor(gui)
setObjective(gui)
startSyncingTeamPoints(gui)
disableMouseWhileGuiEnabled(gui)
setupHitmarker(gui)
setupTouchButtonAsync(gui)

力场屏幕

一个力场屏幕是一个用户界面元素,将窗口区域覆盖到显示区域,以便告诉玩家他们加入或重新加入回合时,从敌方队伍的攻击中安全的。 根据美学指南为“选择一个艺术风格”的图标,样本激光标记体验使用半透明六边形图案来符号化力场。 这个设计决定

要在样本 激光标签 体验中精确重现力场屏幕:

  1. 图像标签 插入 ForceFieldGui 对象。

    1. 在 Explorer 窗口中,导航到 StarterGui 服务。

    2. 将鼠标悬停在其子对象上 ForceFieldGui 对象,然后单击 标志。一个上下文菜单显示。

    3. 从上下文菜单中,插入一个 图像标签

  2. 选择新标签,然后在 属性 窗口中,

    1. 图像 设置为 rbxassetid://14462567888

    2. 背景透明度 设置为 0.8 使力场半透明。

    3. 大小 设置为{1, 0},{1, 0} 使画像填满整个屏幕(100%垂直和100%水平的父屏幕GUI)。

    4. ScaleType 设置为 Tile ,以便在整个屏幕上使用六边形地砖。

    5. 地砖大小 设置为 {0, 104},{0, 180}

  3. 在标签中插入一个 UIGradient 对象。

  4. 选择新的渐变对象,然后在 属性 窗口中,

    1. 颜色 设置为开始为蓝色、变为白色,然后变为蓝色的颜色序列。

      1. 颜色 设置为 120, 192, 250 以应用浅蓝色色调给所有六边形。

      2. 单击 颜色 属性,然后单击 按钮。一个颜色序列弹出显示。

        颜色序列的底轴上的每个三角形是一个钥匙点,它将左侧图像的颜色值确定为右侧图像的颜色值。

      3. 单击并拖动颜色顺序直到您达到 时间 值的 0.05 ,然后单击颜色旁边的小块来打开 颜色 弹出窗口。

      4. 选择一个亮白色,然后关闭弹出窗口。

      5. 点击并拖动颜色顺序直到您达到 时间 值的 0.95 ,然后再次打开 颜色 弹出窗口,然后选择与之前相同的颜色白色。

    2. 旋转 设置为225,以便在左上角和右下角显示您的颜色序列的蓝色部分。

    3. 透明度 设置为数字顺序,使力场看起来像是闪烁。

      1. 单击 透明度 属性,然后单击 按钮。一个数字序列弹出显示。每个开始和结束数字序列的四个方块是一个钥匙,确定图像从左到右的图像开始和结束的透明度值。

      2. 在数字顺序中设置以下时间和值属性:

      • 时间 =0 =0> 0.250>
      • 时间 =.101 =0> 0.8750>
      • 时间 =.183 =0>00>
      • 时间 = .3 = 0> 10>
      • 时间 =.7 =0>00>
      • 时间 =1 =0> 0.90>
  5. 从步骤 2 复制 图像标签

  6. 选择 UIGradient 对象在重复标签内,然后在 属性 窗口中,

    1. 旋转 设置为 -45 以反射图像,使其在 Y 轴上几乎相互镜像。

    2. 修改 透明度 以使闪光更有机。

      1. 单击 透明度 属性,然后单击 按钮。显示一个数字序列弹出显示。
      2. 选择第三关键帧 keyframe,然后单击 删除 按钮。
  7. 在示例 ReplicatedStorage 中,参考以下 激光标签 位置文件,程序显示玩家加入或重新加入回合时显示的力场屏幕。

下列 ReplicatedStorage.ForceFieldClientVisuals 客户脚本将默认 ForceField 视觉与 StarterGui.ForceFieldGui 生成在一个 1> Class.SpawnLocation1> 上,具有 4> Duration

这个脚本首先听取当 ForceField 添加到角色时,禁用默认的第一人称视图,然后启用 ForceFieldGui ScreenGui 对象。注意,这会 1>不1> 影响第三人称视图当玩家看到其他玩家重生回到体验。

First-person force field visuals include a futuristic hexagonal grid on the perimeter of the screen.
第一人称视角的驾驶舱视图
Third-person force field visuals include a blue sparkling orb around the player spawning into the experience.
第三人称视角下的力场视图

local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local function onCharacterAddedAsync(character: Model)
local forceField = character:WaitForChild("ForceField", 3)
if not forceField then
-- 如果玩家在有力场已禁用的生成点生成
return
end
forceField.Visible = false
localPlayer.PlayerGui:WaitForChild("ForceFieldGui").Enabled = true
forceField.Destroying:Wait()
localPlayer.PlayerGui.ForceFieldGui.Enabled = false
end
if localPlayer.Character then
onCharacterAddedAsync(localPlayer.Character)
end
localPlayer.CharacterAdded:Connect(onCharacterAddedAsync)

重生屏幕

重生屏幕是一个 UI 元素,将视窗模糊以向玩家通知他们已被标记出,并且服务器正在将它们重生回到他们的生成区域。 此 UI 元素是重要的,因为它给玩家时间处理他们被标记出的事实,并在他们重新加入活跃回合之前策略他们的下一步。

了解有关在样本激光标签体验中的自定义重生行为的更多信息,请参阅Respawn Characters 游戏玩法脚本教程。

要在样本 激光标签 体验中精确重现屏幕:

  1. 创建中心信息 banner。

    1. 图像标签 插入 OutstateGui 对象 ScreenGui

      1. 在 Explorer 窗口中,导航到 StarterGui 服务。

      2. 将鼠标悬停在其子对象 OutStateGui 上,然后单击 标志。一个上下文菜单显示。

      3. 从上下文菜单中,插入一个 图像标签

    2. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以在新按钮的中间设置新按钮的起始点 (50% 从左到右标签,50% 从上到下标签)。

      2. 背景透明度 设置为 1 使标签的背景完全透明。

      3. {0.5, 0},{0.5, 0}设置为0.5, 0,0.5, 0 8>标签在容器中间的标签,以设置标签在父级屏幕гиui的左侧(父级屏幕гиui的左侧)。

      4. 大小 设置为{0.48, 0},{0.06, 0} 以宽润标签(48% 横向和 6% 垂直的父屏幕GUI)。

      5. 名称 设置为

      6. 图像 设置为 rbxassetid://14304827265 使图像成为三角形。

      7. 图像颜色 设置为 0,0,0 使三角形黑。

      8. 透明度图像 设置为 0.3 以减少标签的不透明度,并在体验中匹配所有黑色 UI 元素。

    3. UIAspectRatioConstraint 插入 以确保标签和其子 UI 元素的外观比例保持不变,无论玩家的屏幕大小。

    4. 选择新的约束,然后在 属性 窗口中,将 方向比 设置为 13.78

    5. 在 块 中插入一个 文本标签 以获取信息文本。

    6. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。

      2. 背景透明度 设置为 1 使标签的背景完全透明。

      3. 将位置设置为{0.5, 0},{0.5, 0} 以将标签放在父标签的中间(父标签的左端至右端为 50%,父标签的上端至下端为 50%)。

      4. 大小 设置为{.85, 0},{0.55, 0},以便文本可以占领大多数三角形区域(85% horizontally和55% vertically的父级标签)。

      5. 名称 设置为 BodyTextLabel

      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。

      7. 重量 设置为 bold 以增加字体的厚度。

      8. 文本 设置为 重生… .

      9. 将 TextColor3 设置为 255, 255, 255 以使文本白色。

      10. 启用 文本缩放

  2. 创建头部。

    1. 图像标签 插入

    2. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 1 以在标签的标签底部中设置标签的起始点(从左到右标签左边 50% ,从右到标签右边 100%)。

      2. 背景透明度 设置为 1 使标签的背景完全透明。

      3. 将位置设置为{0.5, 0},{0, 0},以将标签设置在父标签的中间顶部(父标签从左到右的50%,父标签从上到下的0%)。

      4. 大小 设置为{0.46, 0},{0.56, 0} 以宽润标签(46% 横向和 56% 垂直的父标签)。

      5. 名称 设置为 标题

      6. 图像 设置为 rbxassetid://14304826985 使图像成为多向渐变。

      7. 图像颜色 设置为 245, 46, 46 使渐变红色标记玩家在回合结束时暂时无效,以便表示玩家在回合结束时暂时无效。

    3. 在 标题 中插入一个 文本标签 以获取信息文本。

    4. 选择新标签,然后在 属性 窗口中,

      1. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。

      2. 背景透明度 设置为 1 使标签的背景完全透明。

      3. 将位置设置为{0.5, 0},{0.5, 0} 以将标签放在父标签的中间(父标签的左端至右端为 50%,父标签的上端至下端为 50%)。

      4. 大小 设置为{.85, 0},{0.55, 0} 以便文本可以占领大多数渐变区域(85%垂直于父标签的父标签,55%垂直于父标签的子标签)。

      5. 名称 设置为 头衔文本标签

      6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。

      7. 重量 设置为 黑色 以增加字体的厚度。

      8. 文本 设置为 标记 - 你退出了! 9. 将 TextColor3 设置为 255, 255, 255 以使文本白色。

      9. 启用 文本缩放

  3. 创建渐变边界。

    1. 图像标签 插入 OutstateGui
    2. 选择新标签,然后在 属性 窗口中,
      1. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。
      2. 背景颜色3 设置为 0,0,0 以将标签的背景颜色设置为黑色。
      3. 背景透明度 设置为 0.5 使标签的背景半透明。
      4. {0.5, 0},{0.5, 0}设置为0.5, 0,0.5, 0 将标签设置在容器中间(父屏幕гу伊的左侧50%,并且父屏幕гу伊的右侧50%)。
      5. 大小 设置为{1, 0},{1, 0} 以将标签扩展到整个屏幕(100%水平和100%垂直的父屏幕GUI)。
      6. ZIndex 设置为 -1 以显示渐变在其他 UI 元素后。
      7. 名称 设置为 标题
      8. 图像 设置为 rbxassetid://14309518613 使图像变成边框渐变。
      9. 图像透明度 设置为 0.1 以使渐变稍微透明。
  4. 在示例 ReplicatedStorage 位置文件中,参考以下 Class.ReplicatedStorage 脚本显示重生屏幕,当玩家的生命值达到零,并且他们正在重生回到他们的团队生成区域。

下列 ReplicatedStorage.PlayerStateHandler 客户端脚本包含启发不同类型的行为,根据 playerState 属性。所有事件回应都是在此脚本中按照类似的行为启动或禁用玩家控制、相机移动和显示哪个 UI 层。

当玩家的生命值达到零时,其 playerState 变为 TaggedOut,这会触发 onTaggedOut() 函数。 2>onTaggedOut2> 立即触发以下行为:

  • 玩家不能在竞技场中移动。
  • 玩家无法移动相镜头。
  • 玩家无法使用他们的冲击波。
  • StarterGui.OutStateGui 变为仅用于启动的状态。

当玩家重生时,其 playerState 变为 SelectingBlaster,这会触发 onSelectingBlaster() 函数。1> onSelectingBlaster1> 然后仅用于启用 4> StarterGui.PickABlasterGui


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local PlayerState = require(ReplicatedStorage.PlayerState)
local PlayerAttribute = require(ReplicatedStorage.PlayerAttribute)
local BlasterState = require(ReplicatedStorage.Blaster.BlasterState)
local togglePlayerMovement = require(script.togglePlayerMovement)
local togglePlayerCamera = require(script.togglePlayerCamera)
local scheduleDestroyForceField = require(ReplicatedStorage.scheduleDestroyForceField)
local localPlayer = Players.LocalPlayer
local playerGui = localPlayer.PlayerGui
local guiLayers = {
playerGui:WaitForChild("HUDGui"),
playerGui:WaitForChild("OutStateGui"),
playerGui:WaitForChild("PickABlasterGui"),
}
-- 禁用所有与给予的例外除外的 UI 层
local function setGuiExclusivelyEnabled(enabledGui: ScreenGui?)
-- guilayers 包含一个列表 of the guis 应该设置专用。
for _, screenGui in guiLayers do
screenGui.Enabled = screenGui == enabledGui
end
end
local function onSelectingBlaster()
-- 启用相机,让玩家在选择一个冲击波时可以看到周围
togglePlayerCamera(true)
togglePlayerMovement(false)
setGuiExclusivelyEnabled(playerGui.PickABlasterGui)
-- 选择一个激光器时禁用激光器
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
local function onPlaying()
-- 在选择一个冲击波后启用玩家移动
togglePlayerMovement(true)
setGuiExclusivelyEnabled(playerGui.HUDGui)
-- 在游戏中启用冲击波
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Ready)
-- 编程玩家开始游戏时的删除力场逻辑
scheduleDestroyForceField()
end
local function onTaggedOut()
-- 在被标记为“禁用”控件时禁用控制
togglePlayerMovement(false)
togglePlayerCamera(false)
setGuiExclusivelyEnabled(playerGui.OutStateGui)
-- 在被标记出来时禁用冲击波
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
local function onInLobby()
-- 在大厅中启用控制
togglePlayerMovement(true)
togglePlayerCamera(true)
-- 在大厅中隐藏所有 HUD
setGuiExclusivelyEnabled(nil)
-- 在大厅中禁用冲击波
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
local function onPlayerStateChanged(newPlayerState: string)
if newPlayerState == PlayerState.SelectingBlaster then
onSelectingBlaster()
elseif newPlayerState == PlayerState.Playing then
onPlaying()
elseif newPlayerState == PlayerState.TaggedOut then
onTaggedOut()
elseif newPlayerState == PlayerState.InLobby then
onInLobby()
else
warn(`Invalid player state ({newPlayerState})`)
end
end
-- 设置初始玩家状态
local initialPlayerState = localPlayer:GetAttribute(PlayerAttribute.playerState)
onPlayerStateChanged(initialPlayerState)
local function updateFromPlayerState()
onPlayerStateChanged(localPlayer:GetAttribute(PlayerAttribute.playerState))
end
-- 处理未来玩家状态更新
localPlayer:GetAttributeChangedSignal(PlayerAttribute.playerState):Connect(updateFromPlayerState)
-- 确保更改仍然适用在重生后
localPlayer.CharacterAdded:Connect(updateFromPlayerState)

创建 SurfaceGui 对象

要在 3D 空间中显示 UI 在零件的表面,您可以将 Class.SurfaceGui 对象作为父级对零件, которое您想要在 SurfaceGui 服务中显示您的 UI 的脚本逻辑。这种技术确保您的 UI 和脚本逻辑都可用于服务器和每个玩家的客户端。

SurfaceGui 对象包含所有 GuiObjects 显示在零件表面上的 3D 空间中显示的对象。 示例激光标签体验仅包含一个 SurfaceGui 对象:冷却计量器,显示每个玩家的激光枪。

要创建一个 SurfaceGui 对象:

  1. Explorer 窗口中,将鼠标悬停在 ReplicatedStorage 服务上,然后单击 图标。一个上下文菜单显示。

  2. 从上下文菜单中,插入一个 零件 对象。

  3. 屏幕指南 对象插入零件。

  4. 根据子 UI 元素的上下文重命名 SurfaceGui

  5. 重复此过程,为您需要在 3D 空间中显示的每个 UI 元素。

冷却计

冷却时间计数器是一个 UI 组件,该组件会告诉玩家在什么时候他们可以再次爆炸他们的冲击枪。 此轻度暂停会使玩家无法像点击或按下按钮一样快地爆炸,这是对激光标签游戏的不公平的游戏方式。

要在样本 激光标签 体验中精确重现冷却时间计量器:

  1. 创建一个零件来持有您的 SurfaceGui 对象。

    1. 在 Explorer 窗口中,将鼠标悬停在 工作区 上,然后单击 ⊕ 标志。一个上下文菜单显示。
    2. 从上下文菜单中,插入一个 部分。这是一个临时位置,以便您可以在过程的每个步骤中查看更改。
  2. 将零件放置在玩家角色的武器在其位置的右侧,然后在 属性 窗口中,

    1. 透明度 设置为1使零件完全透明。

    2. 名称 设置为 CooldownBarPrefab .

    3. 大小 设置为0.169, 0.027, 2.537,以将零件缩放到零件的长度。

    4. 禁用 可以碰撞可以查询

  3. 地面图形用户界面 插入 冷却条预制

  4. 选择新的 地面图形用户界面 ,然后在 属性 窗口中,

    1. 设置为 顶部 以便显示 UI 朝上显示。

    2. 光影响响力最大距离 设置为 0

    3. 像素每平方英尺 设置为 200

  5. 创建黑色栏。

    1. 图像标签 插入 地面图形用户界面 .

    2. 选择新标签,然后在 属性 窗口中,

      1. 移除默认值 图像
      2. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。
      3. 背景颜色3 设置为 0,0,0 以将标签的背景颜色设置为黑色。
      4. 背景透明度 设置为 0.4 以使标签的背景半透明。
      5. {0.5, 0},{0.5, 0}设置为 0.5, 0,0.5, 0 8> 在容器中间的标签设置为1> 0.5, 0,0.5, 0 11> 在父级 SurfaceGui的左侧到右侧(父级 SurfaceGui的左侧到父级 SurfaceGui的右侧)。
      6. 大小 设置为{1, 0},{1, 0} 以宽涵标签到整个零件(100%水平和100%垂直的父级表面图形)。
      7. 名称 设置为 容器
  6. 将容器的角落圆化。

    1. UICorner 对象插入 Container

    2. 选择 UICorner ,然后在 属性 窗口中,将 CornerRadius 设置为1> 0.15, 01>以稍微圆化角落。

  7. 创建红色栏。

    1. 图像标签 插入 容器 中。
    2. 选择新标签,然后在 属性 窗口中,
      1. 移除默认值 图像
      2. AnchorPoint 设置为 1, 0.5 以在标签的中间右侧设置标签的起始点 (100% 从左到右标签,50% 从上到下标签)。
      3. 背景颜色3 设置为 172, 13, 13 以将标签的背景颜色设置为深红色。
      4. 背景透明度 设置为 0.2 使标签的背景稍微透明。
      5. 名称 设置为 酒吧
      6. 位置 设置为 {1, 0},{0.5, 0} 将标签设置在容器的右中间 (100% 从左到右的父标签, 50% 从顶到底的父标签)。
      7. 将大小设置为{0, 0},{1, 0} 以长度标签上的标签顶部(0% 横向和100% 垂直)。此步骤还有助于发生在脚本步骤8中的调整行为(潜在渐变为父级标签的子标签).
  8. 将标签的边缘圆起来。

    1. UICorner 对象插入 Bar
    2. 选择 UICorner ,然后在 属性 窗口中,将 CornerRadius 设置为1> 0.15, 01>以稍微圆化角落。
  9. 冷却条预制表 移动到 ReplicatedStorage

    1. 创建文件夹结构来组织您的 UI 对象。样例使用一个 实例 文件夹,拥有一个子文件夹 Guis

    2. 冷却条预制表 移入 图形用户界面

  10. 在示例 ReplicatedStorage 位置文件中,参考以下 Class.ReplicatedStorage 脚本,程序将冷却计时器附加到玩家的激光标记,然后在玩家激光标记射击后的红色条上动画。

下列 ReplicatedStorage.FirstPersonBlasterVisuals 客户端脚本处理所有视觉逻辑为玩家的第一人称射击视角。它需要一套模块脚本,其中工作 together 设置 blaster 视觉效果,以便为激光标签游戏玩法提供更真实的感觉,包括 FirstPersonBlasterVisuals.addCooldownBar 和


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local BlastData = require(ReplicatedStorage.Blaster.BlastData)
local PlayerAttribute = require(ReplicatedStorage.PlayerAttribute)
local PlayerState = require(ReplicatedStorage.PlayerState)
local getBlasterConfig = require(ReplicatedStorage.Blaster.getBlasterConfig)
local runBlastVisuals = require(script.runBlastVisuals)
local setupAnimations = require(script.setupAnimations)
local addCooldownBar = require(script.addCooldownBar)
local runCooldownBarEffect = require(script.runCooldownBarEffect)
local laserBlastedBindableEvent = ReplicatedStorage.Instances.LaserBlastedBindableEvent
local RIG_OFFSET_FROM_CAMERA = CFrame.new(2, -2, -3) * CFrame.Angles(math.rad(0.25), math.rad(95.25), 0)
local localPlayer = Players.LocalPlayer
local currentCamera = Workspace.CurrentCamera
local rigModel = nil
local cooldownBar = nil
local animations = {}
local function addFirstPersonVisuals()
local blasterConfig = getBlasterConfig()
-- 添加第一个人称骨架
rigModel = blasterConfig.RigModel:Clone()
rigModel.Parent = Workspace
-- 添加冷却时间栏
cooldownBar = addCooldownBar(rigModel.PrimaryPart.CooldownBarAttachment)
animations = setupAnimations(blasterConfig, rigModel)
end
local function removeFirstPersonVisuals()
for _, animation in animations do
animation:Stop()
animation:Destroy()
animation = nil
end
if rigModel then
-- 这也会摧毁冷却条,因为它是冷却器的父骨架
rigModel:Destroy()
rigModel = nil
end
end
-- 在爆炸发生时运行第一人称视觉效果
laserBlastedBindableEvent.Event:Connect(function(blastData: BlastData.Type)
runBlastVisuals(rigModel.PrimaryPart.TipAttachment, blastData, animations.blastAnimation)
runCooldownBarEffect(cooldownBar)
end)
-- 如果存在,请将相机绑定到装备上
RunService.RenderStepped:Connect(function()
if rigModel then
-- 更新到装骨架的 CFrame 与相镜头位置和 RIG_OFFSET_FROM_CAMERA 相对
rigModel:PivotTo(currentCamera.CFrame * RIG_OFFSET_FROM_CAMERA)
end
end)
-- 处理器类型在游戏中变更时更改视觉效果
localPlayer:GetAttributeChangedSignal(PlayerAttribute.blasterType):Connect(function()
local playerState = localPlayer:GetAttribute(PlayerAttribute.playerState)
if playerState == PlayerState.Playing then
removeFirstPersonVisuals()
addFirstPersonVisuals()
end
end)
-- 处理玩家状态更改时更改视觉效果
localPlayer:GetAttributeChangedSignal(PlayerAttribute.playerState):Connect(function()
local newPlayerState = localPlayer:GetAttribute(PlayerAttribute.playerState)
-- 移除玩家选择冲击波或在大厅中时的视觉
if newPlayerState == PlayerState.SelectingBlaster or newPlayerState == PlayerState.InLobby then
removeFirstPersonVisuals()
-- 添加视觉效果,当玩家完成选择冲击波时。
elseif newPlayerState == PlayerState.Playing then
addFirstPersonVisuals()
end
end)

创建 BillboardGui 对象

为了在 3D 空间中显示 UI 元素,响应脚本逻辑并且总是面向每个玩家的相机无论他们的视角是否,例如玩家名称或地图标记,您可以创建一个 BillboardGui 对象作为 BasePartAttachment 的子级。

示例激光标记体验包括在 BillboardGui 服务中的两个单独的 ReplicatedStorage 对象:

  • 其他玩家指示器GUIPrefab - 显示在回合中激活时,每个玩家头上的粉色或绿色圆圈。
  • TaggedOutIndicatorGuiPrefab - 显示玩家在回合结束时头部上的标记。

在您创建一个 BillboardGui 对象后,您可以根据每个容器的目的来创建和自定义其子 GuiObjects 。 示例在即将到关注的部分中展示,您将学习如何在示例激光标记体验中实现 UI 元素。 您可以调整过程中的任何部分以满足您自己的体验要求

要创建一个 BillboardGui 对象:

  1. Explorer 窗口中,将鼠标悬停在 BasePartAttachment 上,然后单击显示 1> ⊕1> 标志。 一個上下文菜單顯示。
  2. 从上下文菜单中,插入一个 广告牌指南员 对象。
  3. 根据子 UI 元素的上下文重命名 广告牌指南
  4. 重复此过程,每个需要上下文显示的 UI 元素。

团队指示器

团队指示是一种 UI 元素,该元素可以告诉玩家其他玩家在该回合属于哪个队伍,便于他们轻松地区分自己的盟友和敌方队伍成员。 此信息很重要,因为第一人称射击体验的游戏玩法需要玩家做出快速的战略决策,而不会被标记出并且失去比匹配。

要在样本 激光标签 体验中精确重现团队指示:

  1. 广告牌指南 对象插入临时骨架。

    1. 在菜单栏中,导航到头像选项卡,然后单击装备建造器。

    2. 从可用选项中选择。 示例使用一个 R15 装备类输入,一个 女性 身体形状,并一个 Rthro 虚拟形象。 装备显示在 3D 视窗和 2> 探险者2> 窗口下的名称为 5>Rig5> 。

    3. Explorer 窗口中,导航到装骨架的子 网格,然后单击 标志。一个上下文菜单显示。

    4. 从上下文菜单中,插入一个 广告牌指南员

  2. 选择新的 广告牌指示器 ,然后在 属性 窗口中

    1. LightInfluence 设置为 0 以防止环境灯影响指示器的颜色。

    2. 名称 设置为 OtherPlayerIndicatorPrefab .

    3. 大小 设置为 {0, 10},{0, 10} 以使标签变得更小。

    4. StudsOffsetWorldSpace 设置为 0, 4, 0 将其位置在头顶上。

  3. 框子对象 插入 OtherPlayerIndicatorPrefab

  4. 选择新框架,然后在 属性 窗口中,

    1. AnchorPoint 设置为 0.5, 0.5 以将框架的起始点设置在标签中间(从左到右标签左侧 50%,从上到标签右侧 50%)。

    2. 将 背景颜色3 设置为 255, 3, 0 以将框架的背景颜色设置为红色作为占位符颜色。

    3. {0.5, 0},{0.5, 0}设置为 0.5, 0,0.5, 0 8> 以将框架放置在容器的中间(从左到右父亲 BillboardGui的左侧到右父亲 BillboardGui的右侧)。

    4. 大小 设置为{1, -2},{1, -2} 以缩小广告牌GUI的表面区域。

  5. UICorner 对象插入 以完全将角落圆化。

  6. 将 UIStroke 对象插入 框架 以显示指示器的圆形。

  7. OtherPlayerIndicatorPrefab 移动到 ReplicatedStorage

  8. 在示例 ReplicatedStorage 位置文件中,参考以下 Class.ReplicatedStorage 脚本显示团队标志 для每个玩家在活跃回合中,除非他们在敌方队伍中,否则不会被屏蔽。

下列 ReplicatedStorage.OtherPlayerIndicatorGuiSetup 脚本会在玩家生成到竞技场参加活跃回合时运行。它会通过调用 addIndicatorToCharacter() 函数,将每个玩家角色参与到回合中的头

如果其他玩家在同一队,团队指示器总是显示,即使他们躲在 3D 空间中的对象后面;如果其他玩家在敌队,团队指示器只会显示,如果 3D 空间中没有对象,它们就不会被包围。


local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local localPlayer = Players.LocalPlayer
local otherPlayerIndicatorPrefab = ReplicatedStorage.Instances.Guis.OtherPlayerIndicatorPrefab
local characterSpawnConnectionsByPlayer: { [Player]: RBXScriptConnection } = {}
local playerAddedConnection: RBXScriptConnection?
local function removeIndicatorFromPlayer(player: Player)
if not player.Character then
return
end
local head = player.Character:WaitForChild("Head", 3)
if not head then
return
end
local gui = head:FindFirstChild(otherPlayerIndicatorPrefab.Name)
if gui then
gui:Destroy()
end
end
local function addIndicatorToCharacter(otherCharacter: Model?)
local otherPlayer = Players:GetPlayerFromCharacter(otherCharacter)
if not otherPlayer then
return
end
task.spawn(function()
local otherHead = otherCharacter:WaitForChild("Head", 3)
if not otherHead then
return
end
-- 仅将指示添加到参加回合的玩家
if not otherPlayer.Team then
return
end
-- 避免添加重复的指示,只有在它不存在时才创建一个新的
local gui = otherHead:FindFirstChild(otherPlayerIndicatorPrefab.Name)
if not gui then
gui = otherPlayerIndicatorPrefab:Clone()
gui.Frame.BackgroundColor3 = otherPlayer.TeamColor.Color
gui.Parent = otherHead
end
-- 指示器始终只有一个人友好
local isFriendly = otherPlayer.Team == localPlayer.Team
gui.AlwaysOnTop = isFriendly
end)
end
local function addIndicatorWhenCharacterSpawns(player: Player)
if characterSpawnConnectionsByPlayer[player] then
return
end
local connection = player.CharacterAdded:Connect(addIndicatorToCharacter)
characterSpawnConnectionsByPlayer[player] = connection
end
local function stopSyncingIndicators()
for _, connection in characterSpawnConnectionsByPlayer do
connection:Disconnect()
end
table.clear(characterSpawnConnectionsByPlayer)
if playerAddedConnection then
playerAddedConnection:Disconnect()
playerAddedConnection = nil
end
for _, player in Players:GetPlayers() do
removeIndicatorFromPlayer(player)
end
end
local function addIndicatorToPlayer(player: Player)
if player == localPlayer then
return
end
addIndicatorToCharacter(player.Character)
addIndicatorWhenCharacterSpawns(player)
end
local function startSyncingIndicators()
for _, player in Players:GetPlayers() do
addIndicatorToPlayer(player)
end
if not playerAddedConnection then
playerAddedConnection = Players.PlayerAdded:Connect(addIndicatorToPlayer)
end
end
local function onLocalTeamChanged()
local localTeam = localPlayer.Team
if localTeam then
startSyncingIndicators()
else
stopSyncingIndicators()
end
end
localPlayer:GetPropertyChangedSignal("Team"):Connect(onLocalTeamChanged)
onLocalTeamChanged()

标记出指示

一个带有标记的指示是一个 UI 元素,该元素会告诉玩家在其他玩家不再活跃在回合中,以及在进行重生回到其生成区域。 此信息很重要,因为第一人称射击体验的游戏玩法需要玩家将标记出的玩家移动到下一个目标,以便在竞技场中玩得安全,并且不会在竞技场中玩得安全,并且不会在竞技场中玩得安

要在样本 激光标签 体验中精确重现标记出的指示器:

  1. 广告牌指示 对象插入一个临时装置,以便您可以在过程的每个步骤中视觉化更改。

    1. 在菜单栏中,导航到头像选项卡,然后单击装备建造器。

    2. 从可用选项中选择。 示例使用一个 R15 装备类输入,一个 男性 身体形状,并一个 Rthro 虚拟形象。 装备显示在 3D 视窗和 2> 探险者2> 窗口下的名称为 5>Rig5> 。

    3. Explorer 窗口中,导航到装骨架的子 网格,然后单击 标志。一个上下文菜单显示。

    4. 从上下文菜单中,插入一个 广告牌指南员

  2. 选择新的 广告牌指示器 ,然后在 属性 窗口中

    1. LightInfluence 设置为 0 以防止环境灯影响指示器的颜色。

    2. 名称 设置为 TaggedOutIndicatorGuiPrefab

    3. 大小 设置为 {3, 0},{0.5, 0} 以宽敞标签的空间。

    4. StudsOffset 设置为 0, 3.25, 0 以将其位置在玩家头上。

  3. 图像标签页面指示器GUI预设 对象插入 TaggedOutIndicatorGuiPrefab

  4. 选择新标签,然后在 属性 窗口中,

    1. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。
    2. 背景透明度 设置为 1 使标签的背景完全透明。
    3. 名称 设置为 框架
    4. {0.5, 0},{0.5, 0}设置为 0.5, 0,0.5, 0 8> 以将标签设置为容器中间(父级广告牌图的左侧至右侧50%,父级广告牌图的顶部至底部50%)。
    5. 大小 设置为{1, 0},{1, 0} 以便将标签扩展到整个 BillboardGui(100%水平和100%垂直的父级 BillboardGui)。
    6. 图像 设置为 rbxassetid://14304826985 使图像成为多向渐变。
    7. 图像颜色 设置为 245, 46, 46 来为标签涂色。
  5. 文本标签 对象插入 框架

  6. 选择新标签,然后在 属性 窗口中,

    1. AnchorPoint 设置为 0.5, 0.5 以将标签的原始点设置在标签中间(从左到右标签的左侧到右侧,从上到下标签的顶部到底)。

    2. 背景透明度 设置为 1 使标签的背景完全透明。

    3. 名称 设置为 BodyTextLabel

    4. 将位置设置为{0.5, 0},{0.5, 0} 将标签设置为容器中间(父标签的左侧至右侧,父标签的顶部至底部)。

    5. 大小 设置为{0.85, 0},{0.7, 0},以便文本可以占领大部分渐变标签域(85%水平和70%垂直)。

    6. 字体面 设置为 蒙特塞拉特 来满足未来主义的美感。

    7. 重量 设置为 bold 以增加字体的厚度。

    8. 文本 设置为 标记

    9. 将 TextColor3 设置为 255, 255, 255 以使文本白色。

    10. 启用 文本缩放

  7. TaggedOutIndicatorGuiPrefab 移动到 ReplicatedStorage

  8. 在示例 ServerScriptService 位置文件中,参考以下 Class.ServerScriptService 脚本。

    程序在玩家重生到他们的团队生成区域时,显示标记出的提示。

ServerScriptService.SetupHumanoid 服务器脚本运行为 soon as a player loads the experience。它确保每当玩家的角色添加到数据模型时,setupHumanoidAsync 与其 Humanoid 调用。


local Players = game:GetService("Players")
local setupHumanoidAsync = require(script.setupHumanoidAsync)
local function onCharacterAdded(player: Player, character: Model)
local humanoid = character:WaitForChild("Humanoid")
setupHumanoidAsync(player, humanoid)
end
local function onPlayerAdded(player: Player)
-- 调用已添加的角色,如果玩家已有角色
if player.Character then
onCharacterAdded(player, player.Character)
end
-- 为此玩家所有的角色生成添加字符
player.CharacterAdded:Connect(function(character: Model)
onCharacterAdded(player, character)
end)
end
-- 调用已添加的玩游戏
for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end
-- 为所有未来的玩家调用添加
Players.PlayerAdded:Connect(onPlayerAdded)

恭喜您完成“用户界面设计”课程!既然您有经验创建艺术风格,将布局布局制作完成,并在 Studio 从开始到最后实现您的设计,就可以扩展您的项目,或者跟随额外的教程课程,例如“游戏脚本编程课程”,它教您关于示例激光标记体验的总体组织和关键实现细节。愉快的创建!