现在你有了一个 3D 世界,是时候添加你的第一个脚本了。在本节中,你将创建一个硬币收集机制,让玩家可以收集硬币,并在收集后暂时禁用硬币。
创建硬币
在你可以编写任何脚本之前,你需要在世界中有占位符对象作为你的硬币。就像你在上一节中制作的海堆平台一样,硬币可以是简单的 Part 对象。
创建硬币
在 Workspace > World 中,创建一个名为 Coins 的新文件夹。
在 Coins 文件夹中,创建一个名为 Coin 的圆柱体 Part,BrickColor 设置为 Gold,Material 设置为 Metal,Size 设置为 0.6, 8, 4,Orientation 设置为 90, 0, 0。
禁用 CanCollide 并启用 Anchored。
然后复制 Coin 部件几次,并将副本散布在岛屿和平台上,以便从海堆层可以到达。
保持每个副本的名称为 Coin。创建脚本
接下来,你将使硬币对玩家做出反应。Roblox 引擎可以检测到某物是否触碰了硬币,但你需要使用脚本来定义硬币应该如何反应。
创建 CoinService
在 ServerScriptService 中,创建一个名为 CoinService 的脚本,代码如下:
```lua
-- 初始化服务和变量
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local coinsFolder = Workspace.World.Coins
local coins = coinsFolder:GetChildren()
local COOLDOWN = 10
-- 定义事件处理程序
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
-- 设置事件监听器
for _, coin in coins do
coin: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.Coins
local 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测试机制
从下拉菜单中选择 Test 并点击 Play。移动你的角色去触碰一个硬币。如果一切正常,硬币会消失, Output 窗口会打印 玩家收集了硬币,并且硬币会在 10 秒后重新出现。
