有了游戏循环代码,现在是时候开始添加功能到它。在一场匹配中,玩家可以来来去前往。因此,为了完成任务,例如将玩家发送到比赛中或跟踪激活玩家,需要使用代码。要管理这些任务,请创建名为 PlayerManager 的模块脚本。
这个脚本将启动一个函数,用武器将玩家发送到竞技场,并在系列中扩展。
设置脚本
因为玩家管理器包含其他脚本使用的功能,它将是模块脚本。
在 ServerStorage > ModuleScripts 中,添加一个名为 PlayerManager 的新模块脚本。然后,将模块表命名为与脚本名称匹配,并添加评论为本地和模块功能。
local PlayerManager = {}-- 本地函数-- 模块功能return PlayerManager为以关注中/正在关注添加本地变量:
服务:
- 玩家 - 了解哪些玩家已经加入或离开游戏。
- 服务器存储 - 玩家武器的存储。
地图和玩家变量:
- 大厅生成、竞技场文件夹和竞技场文件夹 - 用于将玩家传送到不同的地区。
- 一个有活跃玩家阵列 - 跟踪玩家在游戏中当前的轨迹。
local PlayerManager = {}-- 服务local Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")-- 地图变量local lobbySpawn = workspace.Lobby.StartSpawnlocal arenaMap = workspace.Arenalocal spawnLocations = arenaMap.SpawnLocations-- 玩家变量local activePlayers = {}-- 本地函数-- 模块功能return PlayerManager创建一个名为 sendPlayersToMatch() 的模块函数,内部有一个测试打印。
-- 本地函数-- 模块功能function PlayerManager.sendPlayersToMatch()print("Sending players to match")endreturn PlayerManager
在大厅中生成玩家
现在有多个生成地点,玩家加入游戏时会随机生成在一个生成地。要确保玩家在大厅中生成,请更改玩家的 RespawnLocation 属性。
创建一个名为 onPlayerJoin() 的新本地函数,并将参数设置为 player 。在该函数中,将玩家的重生位置设置为以前所做的大厅重生变量。
-- 本地函数local function onPlayerJoin(player)player.RespawnLocation = lobbySpawnend在您的模块功能下添加一个事件部分。然后,连接 onPlayerJoin() 到 Player Service 的 PlayerAdded 事件。
-- 模块功能function PlayerManager.sendPlayersToMatch()print("Sending players to match")end-- 事件Players.PlayerAdded:Connect(onPlayerJoin)
连接和测试
现在模块可以连接并测试。 使用 PlayerManager 创建后,需要它以便代码在该模块脚本中运行和发送玩家到大厅。
回到 匹配管理器 并为以关注中/正在关注创建变量:
- 服务器存储 服务。
- 模块脚本 文件夹,子 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()endreturn MatchManager使用至少最低玩家数量的 本地服务器 进行测试。确认您可以看到以关注中/正在关注内容:
- 所有玩家都会在大厅中生成。
- PlayerManager 的打印声明会出现在输出窗口中。
完成后,单击“清理”关闭服务器。
排查提示
在此时,脚本的部分内容可能无法正常运行,请尝试以下一种方法。
- 检查如竞技场、大厅等零件的名称,或者在开始生成时指定的位置,例如果你在课程中命名了它们。
- 请确保在使用 require() 函数和正确拼写模块。
将玩家发送到竞技场
现在玩家在大厅生成时,将被传送到结束中场休息后的比赛。将玩家的 RespawnLocation 改为在竞技场使用“ReloadCharacter()”函数的地方生成。
前往 PlayerManager 脚本,添加一个名为 onPlayerJoin() 的新本地函数,并在两个参数上包含 preparePlayer() 。 包括两个参数: 1> 玩家layer1> 和 4> whichSpawn4>,发送到的生成位置。
local activePlayers = {}-- 本地函数local function onPlayerJoin(player)player.RespawnLocation = lobbySpawnendlocal function preparePlayer(player, whichSpawn)end-- 模块功能function PlayerManager.sendPlayersToMatch()print("Sending players to match")end将玩家的重生位置设置为 whichSpawn。
local function preparePlayer(player, whichSpawn)player.RespawnLocation = whichSpawnend使用 LoadCharacter() 强制角色重新加载,并使用玩家的新位置重生。
local function preparePlayer(player, whichSpawn)player.RespawnLocation = whichSpawnplayer:LoadCharacter()end
将玩家发送到生成
确保每个玩家都被传送到竞技场的不同生成位置,使用 for 循环对其它有效玩家阵数组进行迭代,使用 for 循环您可以通过每个玩家阵数组中的每个值进行导航,允许脚本适应各种玩家数量。
在 sendPlayersToMatch() 函数中,使用变量创建所有竞技场生成位置的阵列,取得 Arena > SpawnLocations 文件夹中的所有子生位置。
--模块功能function PlayerManager.sendPlayersToMatch()local arenaSpawns = spawnLocations:GetChildren()end在下面添加 for 循环以获得所有玩家的阵列,然后在每个玩家上循环。要获取玩家,请键输入: Players:GetPlayers() 。
function PlayerManager.sendPlayersToMatch()local arenaSpawns = spawnLocations:GetChildren()for playerKey, whichPlayer in Players:GetPlayers() doendend
追踪和生成
当游戏运行时,它需要识别哪些用户正在玩游戏,以便他们可以在竞技场中生成。在回合开始时,每个玩家都将被追踪在一组有效玩家中。该阵列将用于不同的功能,例如传送或分配武器,确保在回合中仍然在大厅的玩家不受影响。
在 for 循环中,使用 table.insert() ,使用两个参数为 activePlayers 阵列和玩家添加。
function PlayerManager.sendPlayersToMatch()local arenaSpawns = spawnLocations:GetChildren()for playerKey, whichPlayer in Players:GetPlayers() dotable.insert(activePlayers, whichPlayer)endend要从竞技场中获得一个生成地点,请创建一个名为 spawnLocation 的变量,并将其设置为 第一个 索引在 arenaSpawns 表中。
for playerKey, whichPlayer in Players:GetPlayers() dotable.insert(activePlayers, whichPlayer)local spawnLocation = arenaSpawns[1]end调用 preparePlayer() 并在 whichPlayer 和 spawnLocation 。然后,因为该生成位置已使用,因此将其从表中移除以便下一位玩家使用不同的重生点位置。
for playerKey, whichPlayer in Players:GetPlayers() dotable.insert(activePlayers, whichPlayer)local spawnLocation = table.remove(arenaSpawns, 1)preparePlayer(whichPlayer, spawnLocation)end在玩家被发送到竞技场的 本地 服务器上测试。玩家将继续在同一位置重生,因为代码还没有放场景在发送他们回大厅。
排查提示
在这个时候,您没有看到您想要的结果,请尝试以下一种。
- 在 GetPlayers() 中,确保有 两个 关闭父级,例如 Class.Players.GetPlayers(|Players:GetPlayers()) 在声明中。
- 检查模块脚本中的函数调用序列。例如, matchManager.prepareGame() 应该调用 playerManager.sendPlayersToMatch() 。
向玩家提供武器
当回合开始时,每个参与者在竞技场都将获得一件武器。
添加工具
玩家武器将是工具。 虽然任何工具都可以用来,但我们提供了一个示例剑以开始。
从工具箱导入武器,或创建您自己(见 Tools)。
将武器放置在 ServerStorage 中。如果您正在创建自己的工具,请确保工具的名称为“武器”,因为它将在后续脚本中使用。
向玩家提供工具
现在该工具已存储,请使用脚本访问并提供给每个用户的工具。
在 PlayerManager 中,为服务器存储中的武器添加一个名为 playerWeapon 的变量。
-- 地图变量local lobbySpawn = workspace.Lobby.StartSpawnlocal arenaMap = workspace.Arenalocal spawnLocations = arenaMap.SpawnLocations-- 玩家变量local activePlayers = {}local playerWeapon = ServerStorage.Weapon在 preparePlayer() 中,复制以下代码获取玩家的角色。
local function preparePlayer(player, whichSpawn)player.RespawnLocation = whichSpawnplayer:LoadCharacter()local character = player.Character or player.CharacterAdded:Wait()end创建一个名为剑的新变量,使用 Clone() 函数创建一个武器的副本,然后将剑作为父级交给玩家的角色。
local function preparePlayer(player, whichSpawn)player.RespawnLocation = whichSpawnplayer:LoadCharacter()local character = player.Character or player.CharacterAdded:Wait()local sword = playerWeapon:Clone()sword.Parent = characterend在 本地服务器 上测试,以确认每个玩家在发送到竞技场时都获得工具。 请注意,如果您继续测试,中场休息将继续重新启动,因此玩家每几秒钟就会重生。 这将在下一课程中解决。
已完成的脚本
以下是完成脚本来重新检查您的工作。
游戏管理器脚本
-- 服务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 dorepeattask.wait(gameSettings.intermissionDuration)print("Restarting intermission")until #Players:GetPlayers() >= gameSettings.minimumPlayersprint("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