管理玩家

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

随着游戏循环编写完成,现在是时候开始将功能添加到它中了。在比匹配期间,玩家可以来来去前往。因此,需要代码来执行任务,例如将玩家发送到比赛中并跟踪活跃玩家。要管理这些任务,创建一个名为 PlayerManager 的模块脚本。

这个脚本将启动一个函数将玩家送入竞技场并在系列中稍后扩展。

设置脚本

因为玩家管理器包含其他脚本使用的函数,它将是模块脚本。

  1. 在服务器存储 > 模块脚本中,添加一个名为 PlayerManager 的新模块脚本。然后,重命名模块表以匹配脚本名称并添加评论为本地和模块函数。


    local PlayerManager = {}
    -- 本地函数
    -- 模块功能
    return PlayerManager
  2. 为以关注中/正在关注添加本地变量:

    服务:

    • 玩家 - 了解玩家是否加入或离开了游戏。
    • 服务器存储 - 玩家武器的存储。

    地图和玩家变量:

    • 大厅生成、竞技场文件夹和竞技场生成文件夹 - 用于将玩家传送到不同的区域。
    • 激活玩家阵列 - 跟踪目前在游戏中的玩家。

    local PlayerManager = {}
    -- 服务
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    -- 地图变量
    local lobbySpawn = workspace.Lobby.StartSpawn
    local arenaMap = workspace.Arena
    local spawnLocations = arenaMap.SpawnLocations
    -- 玩家变量
    local activePlayers = {}
    -- 本地函数
    -- 模块功能
    return PlayerManager
  3. 创建一个名为 sendPlayersToMatch() 的模块函数,内部包含测试打印。


    -- 本地函数
    -- 模块功能
    function PlayerManager.sendPlayersToMatch()
    print("Sending players to match")
    end
    return PlayerManager

在大厅生成玩家

目前,有多个生成位置,这意味着玩家在加入游戏时会在随机位置生成。为了确保玩家在大厅生成,改变玩家的 RespawnLocation 属性。

  1. 创建一个名为 onPlayerJoin() 的新本地函数,其参数为 player 。在那个函数中,将玩家的重生位置设置为早нее制定的大厅重生变量。


    -- 本地函数
    local function onPlayerJoin(player)
    player.RespawnLocation = lobbySpawn
    end
  2. 在你的模块函数下添加一个事件部分。然后,连接 onPlayerJoin() 到玩家服务的 PlayerAdded 事件。


    -- 模块功能
    function PlayerManager.sendPlayersToMatch()
    print("Sending players to match")
    end
    -- 事件
    Players.PlayerAdded:Connect(onPlayerJoin)

连接和测试

现在,模块可以连接并测试。创建了 PlayerManager 后,需要它使该模块脚本中的代码可以运行并将玩家发送到大厅。

  1. 返回到 匹配管理器 并为以关注中/正在关注创建变量:

    • 服务器存储 服务。
    • 模块脚本 文件夹,是服务器存储的子文件。
    • 玩家管理器 模块脚本,子模块脚本。

    local MatchManager = {}
    -- 服务
    local ServerStorage = game:GetService("ServerStorage")
    -- 模块脚本
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    end
    return MatchManager
  2. 使用至少最小玩家的本地服务器进行测试。确认您可以看到以关注中/正在关注内容:

    • 所有玩家都在大厅生成。
    • 来自 PlayerManager 的打印声明出现在输出窗口。
  3. 完成后,单击清理来关闭服务器。

排除问题的提示

在这一点上,脚本的部分没有按预期的方式工作,请尝试以下方法之一。

  • 检查竞技场、大厅等零件的名称,或查看大厅 > StartSpawn的位置,尤其是如果你在教程中给予它们不同的命名。
  • 确保每个脚本中需要模块,使用 require() 函数,并正确拼写。

将玩家送到竞技场

现在,玩家生成在大厅,一旦中场结束后将他们传送到比赛中。将玩家的 更改为在竞技场使用 Player 对象中的函数来生成位置的地点。

  1. 前往 PlayerManager 脚本,下面 onPlayerJoin() ,添加一个名为 preparePlayer() 的新本地函数。包括两个参数:playerwhichSpawn ,发送到的生成位置。


    local activePlayers = {}
    -- 本地函数
    local function onPlayerJoin(player)
    player.RespawnLocation = lobbySpawn
    end
    local function preparePlayer(player, whichSpawn)
    end
    -- 模块功能
    function PlayerManager.sendPlayersToMatch()
    print("Sending players to match")
    end
  2. 将玩家的重生位置设置为 whichSpawn .


    local function preparePlayer(player, whichSpawn)
    player.RespawnLocation = whichSpawn
    end
  3. 使用 LoadCharacter() 强制角色重新加载,玩家将使用新分配的位置重生。


    local function preparePlayer(player, whichSpawn)
    player.RespawnLocation = whichSpawn
    player:LoadCharacter()
    end

将玩家发送到生成位置

确保每个玩家使用 for 循环遍历活跃玩家阵数组,然后被传送到不同的生成位置在竞技场中。使用 for 循环可以让你遍历玩家阵数组中的每个值,允许脚本适应各种玩家数量。

  1. sendPlayersToMatch() 函数中,使用变量创建一个阵列所有竞技场生成地点的子文件夹 Arena > SpawnLocations 的孩子。


    --模块功能
    function PlayerManager.sendPlayersToMatch()
    local arenaSpawns = spawnLocations:GetChildren()
    end
  2. 在下面添加 for 循环以获取所有玩家的阵列,然后循环通过每个玩家。要获取玩家,请输入: Players:GetPlayers() .


    function PlayerManager.sendPlayersToMatch()
    local arenaSpawns = spawnLocations:GetChildren()
    for playerKey, whichPlayer in Players:GetPlayers() do
    end
    end

追踪和生成

当游戏运行时,需要识别哪些用户正在游戏,以便他们可以在竞技场中生成。在回合开始时,每个玩家都会被记录在一组活跃的玩家中。该阵列将用于不同的功能,例如传送或分配武器,确保在回合期间仍然在大厅中的玩家不受影响。

  1. 在 for 循环中,使用 table.insert() , 使用两个参数为 activePlayers 阵列和玩家添加。


    function PlayerManager.sendPlayersToMatch()
    local arenaSpawns = spawnLocations:GetChildren()
    for playerKey, whichPlayer in Players:GetPlayers() do
    table.insert(activePlayers, whichPlayer)
    end
    end
  2. 要从竞技场获得生成位置,创建一个名为 spawnLocation 的变量并将其设置为 第一 索引在 arenaSpawns 表中。


    for playerKey, whichPlayer in Players:GetPlayers() do
    table.insert(activePlayers, whichPlayer)
    local spawnLocation = arenaSpawns[1]
    end
  3. 调用 preparePlayer() 并传递 whichPlayerspawnLocation。然后,因为那个生成位置已被使用, 移除 它从表中,以便下一位玩家获得不同的重生点。


    for playerKey, whichPlayer in Players:GetPlayers() do
    table.insert(activePlayers, whichPlayer)
    local spawnLocation = table.remove(arenaSpawns, 1)
    preparePlayer(whichPlayer, spawnLocation)
    end
  4. 在玩家被发送到竞技场的本地 服务器 上进行测试。玩家将继续在同一位置重生,因为将他们送回大厅的代码尚未实场景。

排除问题的提示

在这一点上,你没有看到预期的结果,尝试以下方法之一。

  • GetPlayers() 中,确保有 两个 关闭括号,例如声明中的 Class.Players.GetPlayers(|Players:GetPlayers())
  • 检查模块脚本中的函数调用序列。例如,matchManager.prepareGame() 应该调用 playerManager.sendPlayersToMatch()

给玩家提供武器

当回合开始时,竞技场的每个玩家都将获得一个武器使用。

添加工具

玩家武器将是工具。虽然 Roblox 中的任何工具都可以使用,但我们已提供了一个示例剑以供开始。

  1. 从工具箱中导入武器,或创建自己的(见 Tools)。

  2. 将武器放入 ServerStorage。如果你正在创建自己的工具,请确保工具名为武器,因为它将在稍后的脚本中使用。

向玩家提供工具

现在工具已存储在存储中,工作在一个脚本来通过激活的玩家阵列并为每个用户提供该工具。

  1. 在 PlayerManager 中,为服务器存储中的武器添加名为 playerWeapon 的变量。


    -- 地图变量
    local lobbySpawn = workspace.Lobby.StartSpawn
    local arenaMap = workspace.Arena
    local spawnLocations = arenaMap.SpawnLocations
    -- 玩家变量
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
  2. preparePlayer() 中,粘贴以下代码以获取玩家的角色。


    local function preparePlayer(player, whichSpawn)
    player.RespawnLocation = whichSpawn
    player:LoadCharacter()
    local character = player.Character or player.CharacterAdded:Wait()
    end
  3. 创建一个名为剑的新变量,并使用 Clone() 函数创建武器的副本在 ServerStorage。然后,将剑交给玩家角色。


    local function preparePlayer(player, whichSpawn)
    player.RespawnLocation = whichSpawn
    player:LoadCharacter()
    local character = player.Character or player.CharacterAdded:Wait()
    local sword = playerWeapon:Clone()
    sword.Parent = character
    end
  4. 在本地服务器上测试 以确认每个玩家在发送到竞技场时都得到一件工具。 请记住,如果您继续测试,中断将继续重启,因此玩家每隔几秒就会重生。这将在下一课中解决。

已完成的脚本

以下是完成的脚本来检查您的工作。

游戏管理器脚本


-- 服务
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- 模块脚本
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
while true do
repeat
task.wait(gameSettings.intermissionDuration)
print("Restarting intermission")
until #Players:GetPlayers() >= gameSettings.minimumPlayers
print("Intermission over")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
end

匹配管理器脚本


local MatchManager = {}
-- 服务
local ServerStorage = game:GetService("ServerStorage")
-- 模块脚本
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
end
return MatchManager

玩家管理器模块脚本


local PlayerManager = {}
-- 服务
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
-- 地图变量
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- 玩家变量
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
-- 本地函数
local function onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
end
local function preparePlayer(player, whichSpawn)
player.RespawnLocation = whichSpawn
player:LoadCharacter()
local character = player.Character or player.CharacterAdded:Wait()
local sword = playerWeapon:Clone()
sword.Parent = character
end
-- 模块功能
function PlayerManager.sendPlayersToMatch()
print("Sending players to match")
local arenaSpawns = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers, whichPlayer)
local spawnLocation = table.remove(arenaSpawns, 1)
preparePlayer(whichPlayer, spawnLocation)
end
end
--事件
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager