在以前的教程中,您制作了各种体验功能,包括 渐变平台 和 致命熔岩。本教程将这些内容结合在一起,形成一个可玩的体验,让用户看看谁能够活得最久。每当他们生存一秒,便会向他们的得分中添加一分。
设置
首先,您需要为您的体验设置场景。复制您在上一教程中制作的 渐变平台,让用户竞争以在平台上尽可能长时间地生存。
您还可以使用 致命熔岩 来击杀当从平台上掉下的用户,或者让他们掉入死亡之中。请确保您在用户可以跳上平台开始玩的地方放置一个 SpawnLocation。

玩家积分
Roblox 有一个内置的 Leaderboard 来显示用户统计数据。当您通过排行榜设置玩家积分时,他们会显示在体验界面的右侧。

您将在后面的教程中学习更具自定义方式的信息展示,但排行榜是制作显性评分系统的最简单方法。
最好将设置体验状态的脚本放在 ServerScriptService 中,因为它们会在体验启动时自动运行。在 ServerScriptService 中,创建一个名为 SetupPoints 的脚本。

监听玩家
在 Roblox 中,服务 是执行一系列有用功能的对象。Players 服务有一个叫做 PlayerAdded 的事件,您可以用来设置每个加入体验的用户的积分。
您可以通过 GetService 函数在 game 对象中访问服务。game 是一个可以从任何地方访问的变量,它包含您体验中的所有内容。
使用 game:GetService("Players") 创建一个 Players 服务的变量。
创建一个名为 onPlayerAdded 的函数,并为传入的玩家定义一个参数。
将 onPlayerAdded 函数连接到 PlayerAdded 事件。
local Players = game:GetService("Players")local function onPlayerAdded(player)endPlayers.PlayerAdded:Connect(onPlayerAdded)
创建统计信息文件夹
要使用户的积分显示在排行榜中,您只需在他们的 Player 对象中创建一个名为 "leaderstats" 的新 Folder 并将他们的积分放在那里。可以通过 Instance.new() 函数从脚本中创建新对象。
使用 Instance.new("Folder") 创建一个新的 Folder 对象,并将结果存储在一个名为 leaderstats 的新变量中。
local function onPlayerAdded(player)local leaderstats = Instance.new("Folder")end将 leaderstats 的 Name 属性设置为 "leaderstats"。
将 leaderstats 父级设置为 player。
local Players = game:GetService("Players")local function onPlayerAdded(player)local leaderstats = Instance.new("Folder")leaderstats.Name = "leaderstats"leaderstats.Parent = playerendPlayers.PlayerAdded:Connect(onPlayerAdded)
创建积分
排行榜系统会读取 leaderstats 文件夹中的任何值,并显示它找到的任何内容。
要添加一个跟踪玩家积分的统计信息,可以将一个新的 IntValue 对象父级设置为 leaderstats 文件夹。值对象的名称将在其当前值旁边显示。
- 将 Name 设置为 "Points"。
- 将 Value 设置为 0;这是排行榜最初为玩家显示的内容。
- 将 points 对象父级设置为 leaderstats 文件夹。
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
end
Players.PlayerAdded:Connect(onPlayerAdded)
测试您的体验,您应该在右上角看到排行榜,显示用户的名称和他们的积分。
计算时间
每个用户应该为他们生存的每一秒获得一分。可以使用 while 循环和 task.wait() 函数每秒更新一次积分值。
- 在脚本末尾,创建一个条件为 true 的 while 循环。
- 在循环中,task.wait() 1 秒。
Players.PlayerAdded:Connect(onPlayerAdded)while true dotask.wait(1)end
玩家列表
要对体验中的每个用户运行代码,您需要通过 GetPlayers 函数返回的用户 数组 进行迭代。
数组是按顺序存储的项目列表。可以通过 索引 位置访问每个项目,从 1 开始。您可以通过在前面加上 # 来获取数组的长度。
- 将 Players:GetPlayers() 的结果存储在一个 playerList 变量中。
- 创建一个 for 循环,起始值为 1,结束值为 #playerList,这样每个玩家都会进行一次循环。
while true dotask.wait(1)local playerList = Players:GetPlayers()for currentPlayer = 1, #playerList do-- 在这里添加您对 playerList 中每个玩家的逻辑endend
奖励积分
要在 for 循环中向每个用户奖励一分,您需要从数组中获取用户并在他们的 leaderstats 文件夹中增加 Points 对象的 1。
存储在数组中的对象使用 方括号 访问,例如,可以通过 playerList[1] 访问 playerList 数组中的第一个项目。如果在 for 循环中编写 playerList[currentPlayer],您可以在每次循环迭代中遍历用户列表。
- 将 playerList[currentPlayer] 中的用户存储在名为 player 的变量中。
- 将用户的 Points 对象存储在名为 points 的变量中。
while true dotask.wait(1)local playerList = Players:GetPlayers()for currentPlayer = 1, #playerList dolocal player = playerList[currentPlayer]local points = player.leaderstats.Pointspoints.Value += 1endend
测试您的体验,您应该发现排行榜显示用户的得分每秒增加 1。
监听角色
体验的目标是看看谁可以活得最久,因此死去的用户需要将他们的积分重置为 0。
您需要获取用户的 Character 模型才能检测他们何时死亡。这个模型只有在 Player 对象加载后才会添加到体验中,您可以使用 CharacterAdded 事件来监听角色何时准备好使用。创建一个名为 onCharacterAdded 的函数,参数包括角色和玩家。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
尽管您在 onCharacterAdded 函数的参数中包含了用户,但实际的 CharacterAdded 事件只会返回角色,而不会返回关联的用户。要同时传递 player 对象,请为事件连接使用 匿名函数。
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
重置积分
当用户死亡时,他们的 Humanoid 会自动触发 Died 事件。您可以使用此事件来得知何时重置他们的积分。
Humanoid 位于 Character 模型内部,但该模型的内容只有在用户生成时组装。为了安全等待 Humanoid 对象加载,使用 WaitForChild() 函数。您可以在任何父对象上调用它,传递您正在等待的子对象的字符串名称。使用 character:WaitForChild("Humanoid") 创建一个变量以等待 Humanoid。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
local humanoid = character:WaitForChild("Humanoid")
end
您需要连接到 Died 事件的函数非常简短,并且只在这里需要,因此您可以再次使用匿名函数。
- 将一个新的匿名函数连接到 Humanoid 的 Died 事件。
- 在匿名函数中,为玩家的 Points 对象创建一个名为 points 的变量。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
end)
end
测试一下,您将看到用户的积分在他们死亡时重置。
检查玩家
如果用户在死亡时仍然获得积分,这显然不符合体验的精神,因此代码需要在奖励积分之前检查用户是否仍然活着。
您需要从 onPlayerAdded 函数开始定义一个 属性,用于检查用户是否存活。在这一点上,用户还没有存活并产生,因为他们的角色模型仍需要添加。
属性允许您在 Roblox 中使用自己数据自定义对象。一个属性由名称和值组成。您可以使用 SetAttribute 函数在任何对象上创建一个。在 player 上调用 SetAttribute 创建一个名为 "IsAlive" ,值为 false 的新 属性。
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player:SetAttribute("IsAlive", false)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
一旦用户的角色模型重生,IsAlive 的值需要更改为 true,以便用户可以重新开始获得积分。
- 在 onCharacterAdded 中,将 player 的 IsAlive 属性设置为 true。
- 在 onCharacterDied 中,将 player 的 IsAlive 属性设置为 false。
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
player:SetAttribute("IsAlive", true)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
player:SetAttribute("IsAlive", false)
end)
end
最后,在脚本末尾的 while 循环中,应该在奖励任何积分之前检查 IsAlive 。 GetAttribute 函数接受属性名称并返回其值。在 while 循环中,用条件 player:GetAttribute("IsAlive") 将奖励积分的代码包裹在 if 语句中。
while true dotask.wait(1)local playerList = Players:GetPlayers()for currentPlayer = 1, #playerList dolocal player = playerList[currentPlayer]if player:GetAttribute("IsAlive") thenlocal points = player.leaderstats.Pointspoints.Value += 1endendend
现在测试一下您的体验,您应该发现用户在生存时每秒获得积分,在不生存时积分保持为 0。让您的朋友们和您一起玩,看看谁能获得最高的分数。
这只是一个开始:您可以继续为您的用户改善体验。以下是一些提示:
- 将所有平台的代码放入一个脚本中,这样更新起来更为简便。
- 创建一个候机区,让用户等待传送到体验区域,允许用户同时开始。
- 宣布每轮的赢家。
最终代码
local Players = game:GetService("Players")
local function onCharacterAdded(character, player)
player:SetAttribute("IsAlive", true)
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
local points = player.leaderstats.Points
points.Value = 0
player:SetAttribute("IsAlive", false)
end)
end
local function onPlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local points = Instance.new("IntValue")
points.Name = "Points"
points.Value = 0
points.Parent = leaderstats
player:SetAttribute("IsAlive", false)
player.CharacterAdded:Connect(function(character)
onCharacterAdded(character, player)
end)
end
Players.PlayerAdded:Connect(onPlayerAdded)
while true do
task.wait(1)
local playerList = Players:GetPlayers()
for i = 1, #playerList do
local player = playerList[i]
if player:GetAttribute("IsAlive") then
local points = player.leaderstats.Points
points.Value += 1
end
end
end