管理玩家

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

有了游戏循环代码,现在是时候开始添加功能到它。在一场匹配中,玩家可以来来去前往。因此,为了完成任务,例如将玩家发送到比赛中或跟踪激活玩家,需要使用代码。要管理这些任务,请创建名为 PlayerManager 的模块脚本。

这个脚本将启动一个函数,用武器将玩家发送到竞技场,并在系列中扩展。

设置脚本

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

  1. 在 ServerStorage > ModuleScripts 中,添加一个名为 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() 到 Player Service 的 PlayerAdded 事件。


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

连接和测试

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

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

    • 服务器存储 服务。
    • 模块脚本 文件夹,子 of ServerStorage。
    • PlayerManager 模块脚本,子模块Scripts。

    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. 完成后,单击“清理”关闭服务器。

排查提示

在此时,脚本的部分内容可能无法正常运行,请尝试以下一种方法。

  • 检查如竞技场、大厅等零件的名称,或者在开始生成时指定的位置,例如果你在课程中命名了它们。
  • 请确保在使用 require() 函数和正确拼写模块。

将玩家发送到竞技场

现在玩家在大厅生成时,将被传送到结束中场休息后的比赛。将玩家的 RespawnLocation 改为在竞技场使用“ReloadCharacter()”函数的地方生成。

  1. 前往 PlayerManager 脚本,添加一个名为 onPlayerJoin() 的新本地函数,并在两个参数上包含 preparePlayer() 。 包括两个参数: 1> 玩家layer1> 和 4> whichSpawn4>,发送到的生成位置。


    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()

向玩家提供武器

当回合开始时,每个参与者在竞技场都将获得一件武器。

添加工具

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

  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() 函数创建一个武器的副本,然后将剑作为父级交给玩家的角色。


    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

MatchManager 脚本


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

PlayerManager 模块脚本


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