现在,您已经有了一个 3D 世界,是时候添加您的第一个脚本了。在此部分中,您将创建一个金币收集机制,让玩家可以收集金币,并在金币被收集后暂时禁用它们。
创建金币
在您可以编写脚本之前,您需要在世界中放置占位符对象来用作金币。就像您在上一节中制作的海堆平台一样,这些金币可以是简单的 Part 对象。
创建金币在 Workspace > World 中,创建一个名为 Coins 的新文件夹。在 Coins 文件夹中,创建一个圆柱形 Part,命名为 Coin,BrickColor 设置为 Gold,Material 设置为 Metal,Size 设置为 0.6, 8, 4,Orientation 设置为 90, 0, 0。禁用 CanCollide 并启用 Anchored。然后多次复制 Coin part,并在岛屿和平台上散布这些副本,以便从海堆高度达到。保持每个副本命名为 Coin。
创建脚本
接下来,您将使金币对玩家作出反应。Roblox 引擎可以检测到某个物体何时触碰金币,但是您需要使用脚本来定义金币应该如何反应。
创建 CoinService在 ServerScriptService 中,创建一个名为 CoinService 的脚本,并包含以下代码:```lua-- 初始化服务和变量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("玩家收集了金币")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 秒,并且输出日志会打印 玩家收集了金币。
代码说明
以下部分详细描述了脚本的工作原理。
初始化服务和变量
像您可能在其他语言中编写的大多数代码一样,您在脚本的顶部定义了稍后需要的变量。我们的代码执行以下操作:
- 获取所有金币的引用 - 然后,脚本查询 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() 方法中定义了处理该事件的逻辑,如下所示:
- 检测玩家是否触碰了金币 - 如果金币被启用,该方法使用玩家服务来检查触碰金币的对象是否确实是玩家。当触碰事件发生时,Roblox 引擎会将触碰金币的对象作为 otherPart 参数传递给脚本。脚本检查 otherPart 的父对象是否属于玩家。
- 如果玩家触碰了金币,则禁用金币,并在 10 秒后重新启用 - 最后,如果玩家触碰了金币,该方法会禁用金币,等待 10 秒,然后再重新启用金币以供收集。使用 task.wait() 而不是 wait(),因为它提供更好的性能,不会完全暂停代码执行,允许其他线程中的任务并发运行。
定义事件处理程序
local function onCoinTouched(otherPart, coin)
if coin:GetAttribute("Enabled") then
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
-- 玩家触碰了一个金币
coin.Transparency = 1
coin:SetAttribute("Enabled", false)
print("玩家收集了金币")
task.wait(COOLDOWN)
coin.Transparency = 0
coin:SetAttribute("Enabled", true)
end
end
end
连接事件处理程序
所有模拟的 3D 对象均继承自 BasePart,因此都有一个 Touched() 事件。以下循环通过执行以下操作,将 onTouchedEvent() 处理程序连接到每个金币的触碰事件:
- 遍历所有金币 - 使用一般迭代遍历每个金币。
- 将处理程序连接到事件 - 在循环的每次迭代中,金币默认启用,因此在游戏开始时在 3D 世界中可见。同时将 onCoinTouched() 处理程序连接到金币的 Touched 事件,以便每次事件发生时都执行该处理程序。当引擎检测到触碰时,它还会将触碰该对象的对象 otherPart 一并传入。
连接事件处理程序
for _, coin in coins do
coin:SetAttribute("Enabled", true)
coin.Touched:Connect(function(otherPart)
onCoinTouched(otherPart, coin)
end)
end
测试机制
从下拉菜单中选择 测试,然后点击 播放。移动您的角色以触碰金币。如果一切正常,金币将消失,输出 窗口打印 玩家收集了金币,金币将在 10 秒后重新出现。
