现在你有了一个 3D 世界,本教程的这一部分教你如何添加第一个脚本来定义收集硬币的机制。这个机制允许玩家收集硬币,并禁用最近收集的硬币的收集。
创建硬币
在你能够脚本任何东西之前,你需要在世界上拥有可用作你的硬币的替换物体。像上一节中你制作的海堆平台一样,硬币可以是简单的 Part 对象。
要创建硬币:
在 探索器 窗口中,添加一个新文件夹到 世界 文件夹,然后重命名为 金币 。
将 缸 零件插入 金币 文件夹,然后将零件重命名为 金币 。
选择零件,然后在 属性 窗口中,
- 将 砖块颜色 设置为 金色 。
- 将 材料 设置为 金属 。
- 将 大小 设置为0.6, 8, 4。
- 禁用 可碰撞 。这告诉引擎其他部分可以通过硬币,意味着玩家可以通过硬币走来收集它们。
- 启用 锚定 。这告诉引擎永远不要因为任何物理相关模拟而更改硬币的位置,这意味着玩家可以触碰硬币而不会影响其位置。
复制一些更多的硬币,并将它们放在地图周围进行测试。
你的气缸零件现在看起来像硬币,防止物理模拟,但你需要将逻辑添加到硬币上,以便玩家可以收集它们。
创建脚本
要使硬币易于收集,您想要反应玩家触碰它们。Roblox 引擎可以通知您当某物触碰到硬币时,但您需要在脚本中声明这一点。要创建一个脚本:
在 浏览器 窗口中,将鼠标悬停在 ServerScriptService 上,然后单击 ⊕ 按钮。会话上下文菜单显示。
从上下文菜单中,选择 脚本 。一个新的脚本显示在 ServerScriptService 下,告诉引擎在服务器上运行脚本,并防止客户端访问代验证码。
将脚本重命名为 CoinService 。
将默认代码替换为以下验证码:
-- 初始化服务和变量local Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local coinsFolder = Workspace.World.Coinslocal coins = coinsFolder:GetChildren()local COOLDOWN = 10-- 定义事件处理器local function onCoinTouched(otherPart, coin)if coin:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- 玩家触碰了一个硬币coin.Transparency = 1coin:SetAttribute("Enabled", false)print("Player collected coin")task.wait(COOLDOWN)coin.Transparency = 0coin:SetAttribute("Enabled", true)endendend-- 设置事件听众for _, coin in coins docoin:SetAttribute("Enabled", true)coin.Touched:Connect(function(otherPart)onCoinTouched(otherPart, coin)end)end现在,每当玩家触碰到一枚硬币时,硬币将消失 10 秒,输出日志打印 Player collected coin .
代码说明以下部分描述了脚本在更详细的情况下如何工作。
初始化服务和变量
与你可能在其他语言中写的大量代码类似,你在脚本顶部定义需要稍后使用的变量。我们的代码做了以关注中/正在关注工作:
获取所有币的参考 - 脚本然后查询 3D 工作区对所有币对象的参考,使用 GetChildren() 方法。这个方法返回包含与其关联的对象的所有内容的阵列,在这种情况下是你之前创建的 Workspace.World.Coins 文件夹。
定义了全球变量 - 变量 COOLDOWN 在稍后被使用来定义收集后禁用多久的硬币。
初始化服务和变量local Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local coinsFolder = Workspace.World.Coinslocal coins = coinsFolder:GetChildren()local COOLDOWN = 10...
定义事件处理器
Roblox 引擎物理模拟 3D 世界,并处理大量与渲染、物理和网络相关的事件的逻辑。当您对某些事件感兴趣时编写自己的逻辑时,您可以听取并处理它们,同时让引擎完成剩下的工作。在这种情况下,您收听并处理与被触碰的硬币相关的事件。该脚本在 onCoinTouched() 方法中定义了处理此事件的逻辑,具有以关注中/正在关注功能:
检测是否启用了硬币 - 每个 Instance 都有一个 Enabled boolean 特性,该特性定义了对象是否存在于 3D 世界。您可以使用 GetAttribute() 方法获取实例属性。
检测玩家是否触碰了硬币 - 如果启用了硬币,方法使用玩家服务来检查触碰硬币的对象是否真的是玩家。当触摸事件发生时,Roblox 引擎将触摸硬币的对象作为 otherPart 参数传递。该脚本检查是否父辈 otherPart 属于玩家。
如果玩家触摸了硬币,将其禁用,然后在 10 秒后重新启用硬币 - 最后,如果玩家触摸了硬币,方法将禁用硬币,等待 10 秒,然后重新启用硬币以进行收系列。task.wait() 被用作代替 wait() ,因为它不完全暂停代码执行,允许其他线程的任务并行运行。
定义事件处理器local function onCoinTouched(otherPart, coin)if coin:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- 玩家触碰了一个硬币coin.Transparency = 1coin:SetAttribute("Enabled", false)print("Player collected coin")task.wait(COOLDOWN)coin.Transparency = 0coin:SetAttribute("Enabled", true)endendend
连接事件处理器
所有模拟 3D 对象都从 BasePart 继承,因此具有一个 Touched() 事件。以下循环将触发器 onTouchedEvent() 连接到每个硬币的触摸事件,通过执行以关注中/正在关注操作:
循环通过所有硬币 - 使用通用循环循环每个硬币。
将处理器连接到事件 - 在循环的每一轮中,默认情况下硬币是启用的,因此在体验初始启动期间在 3D 世界中可见。onCoinTouched() 处理器方法也连接到硬币的Touched事件,以便每次发生事件时运行。当引擎检测到触碰时,它还传递触碰对象的对象,otherPart。
连接事件处理器for _, coin in coins docoin:SetAttribute("Enabled", true)coin.Touched:Connect(function(otherPart)onCoinTouched(otherPart, coin)end)end
玩测机制
是时候看看硬币收集机制是否如预期般运行了。要测试您的体验:
在工具栏中,单击 播放 按钮。Studio 进入游戏测试模式。
将角色移动到触碰硬币。如果你的脚本正常运行,输出窗口会显示 ,金币会在重新出现前消失 10 秒。