매치 종료

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

매치는 타이머가 종료되거나 단일 플레이어가 남겨지는 등 몇 가지 조건으로 종료될 수 있습니다.

패배한 플레이어 관리

현재 패배한 플레이어는 아레나에서 재생성됩니다. 대신 다음 일치기다리기 위해 로비로 돌려보내십시오.

  1. PlayerManager에서 respawnPlayerInLobby()라는 이름의 로컬 함수를 만듭니다. 해당 함수에서 팔로잉수행합니다.
  • 플레이어의 RespawnLocation 속성을 lobbySpawn으로 설정합니다.
  • Player:LoadCharacter()로 캐릭터를 다시 불러오십시오. 기억하십시오, LoadCharacter()는 플레이어의 스폰에서 도구를 제거하고 재생합니다.

익명 함수 사용

익명 함수는 특정 상황에서 고급 스크립트에서 일반적으로 사용됩니다.스크립트가 발견할 수 있는 상황을 이해하기 전에 정의하는 것이 중요합니다.

이것을 고려하십시오: 패배한 플레이어를 로비로 순간이동하려면 재생 기능이 플레이어의 사망 이벤트에 연결되어야 합니다.그러나 문제가 있습니다.과거에 사용했던 대로 이벤트를 연결하면 Died 이벤트에서 플레이어의 이름을 가져올 수 없습니다.스크립트는 이기지 못한 플레이어를 활성 플레이어 추적 테이블에서 제거하기 위해 이 이름이 필요합니다.

사망 이벤트를 트리거한 플레이어의 이름을 가져오려면 익명 함수를 사용하십시오. 익명 함수 는 이름이 없으며, 별도로 생성하는 대신 직접 내에서 Connect() 생성될 수 있습니다.

샘플 무명 함수는 아래에 있으며 구문을 보여줍니다.


myPlayer.Died:Connect(function()
print(player)
end)

죽은 이벤트 코드화

이 함수에서는 플레이어의 캐릭터가 죽을 때마다 그들을 재생성하는 함수가 트리거됩니다.

  1. 플레이어의 사망 이벤트에 액세스하려면 PlayerManager > preparePlayer() 에서 플레이어의 휴머노이드에 대한 변수를 추가하십시오.


    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
    local humanoid = character:WaitForChild("Humanoid")
    end
  2. Died 이벤트에 연결하는 익명 함수를 만듭니다.humanoid.Died:Connect()를 입력하여 시작합니다.그런 다음, 내부 Connect() 에서, type function() , press Enter 를 자동 완성하여 end 를 삭제하고, 추가 괄호를 삭제합니다.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    end)
  3. 익명 함수에서 respawnPlayerInLobby() 를 호출하십시오. player 를 전달하여 플레이어가 일치참여할 준비를 하는 변수를 저장합니다.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    end)
  4. 서버 를 시작 하고 매치를 일치.플레이어가 죽으면 로비에서 재생성되는지 테스트합니다.플레이어를 물리치려면 그들에게 걸어가서 로비에서 재생성되었는지 확인할 때까지 무기를 사용하십시오.

    플레이어2 공격하기
    플레이어2가 리스폰 후 로비에서

참고, 원하는 경우 테스트 방법도 다릅니다.

  • 플레이어를 죽이려면, 서버 > 출력 창 > 명령 바에서 workspace.Player1.Humanoid.Health = 0 복사하고 붙여넣으세요.명령을 실행하려면 Enter를 누르십시오.다른 플레이어를 제거하려면 Player2, Player3 등을 사용하십시오.
  • 게임설정 > matchDuration
  • 더 빠른 테스트를 위해 GameSettings > minimumPlayers를 2와 같은 더 작은 숫자로 변경합니다.

게임 종료

이제 패배한 플레이어가 재생성되었으므로 게임 종료에 대한 작업을 시작하십시오.MatchEnd 이벤트를 만드는 것을 기억하십니까? 타이머가 소진되거나 승자가 발견될 때 발사됩니다.

다른 스크립트에 게임이 종료된 조건을 알려주려면 TimerUpFoundWinner 변수가 있는 테이블을 만듭니다.일치 종료 이벤트가 발생하면 다른 스크립트가 응답할 수 있도록 변수를 전달합니다.

  1. 게임 설정에서 endStates라는 빈 모듈 테이블을 만듭니다.


    local GameSettings = {}
    -- 게임 변수
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- 게임이 종료수 있는 가능한 방법.
    GameSettings.endStates = {
    }
    return GameSettings
  2. Create two variables named TimerUpFoundWinner 를 만듭니다. 각각을 이름에 일치하는 문자열로 설정하십시오. 이 문자열은 코드를 테스트하는 데 사용됩니다.


GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}

타이머로 끝내기

타이머가 종료되면 일치하는 끝 상태 변수를 발사하고 일치하는 끝 이벤트를 발생시킵니다.그런 식으로 해당 이벤트를 수신하는 다른 스크립트가 적절하게 응답할 수 있습니다.이벤트가 신호를 발사할 때, 수신하는 데이터를 듣는 스크립트와 마찬가지로 TimerUp 또는 FoundWinner와 같은 데이터를 전송할 수도 있음을 기억하십시오.

  1. In 게임 관리자 , while true do 루프에서, 라인 matchEnd.Event:Wait() 을 찾습니다. 라인의 시작에서, local endState = 을 추가합니다.


    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    displayManager.updateStatus("Get ready!")
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    local endState = matchEnd.Event:Wait()
    end
  2. 올바른 상태가 받혔는지 확인하려면 endState를 포함하는 프린트 문을 추가합니다.


    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    displayManager.updateStatus("Get ready!")
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    local endState = matchEnd.Event:Wait()
    print("Game ended with: " .. endState)
    end
  3. In MatchManager에서 timeUp() 찾고 제거 인쇄 문을 제거합니다.그런 다음, 매치 종료 이벤트를 발사하려면 matchEnd:Fire() 을 입력하고 gameSettings.endStates.TimerUp 을 전달합니다.


    -- 값
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    -- 매치 시간을 추적하기 위해 사용할 새로운 타이머 개체를 생성합니다.
    local myTimer = timer.new()
    -- 로컬 함수
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. 일치 항목을 테스트합니다. 타이머가 소진되면 TimerUp 변수에 저장된 문자열이 인쇄 문에 포함되는지 확인하십시오.

문제 해결 팁

이 시점에서 메시지가 표시되지 않았습니다. 다음 중 하나를 시도하십시오.

  • 끝 상태 변수가 호출되는 곳마다 정확하게 작성되었는지 확인하십시오, 여기처럼: gameSettings.endStates.TimerUp .
  • Make sure to use :(콜론 연산자) with the 대신에 도트 연산자, like in .

승리하는 일치코드화

다음으로 스크립트는 승리하는 플레이어를 식별하고, 패배하는 플레이어를 제거하고, 타이머 중지와 같은 정리를 실행해야 합니다.매치는 플레이어가 하나 남으면 종료됩니다.FoundWinner 조건이 충족되었는지 확인하려면 매치에서 플레이어를 추적하는 테이블에 남은 숫자를 확인하는 함수가 필요합니다.

플레이어 수 확인

플레이어가 하나뿐이면 매치가 종료됩니다.이것을 확인하려면 스크립트가 라운드에서 플레이어를 추적해야 합니다.한 명의 플레이어가 남으면 승자가 지정될 수 있습니다.

  1. 플레이어 관리자에서 다음 변수를 정의하십시오:

    • 모듈 스크립트 폴더
    • 게임설정 모듈 - 최종 상태 변수에 액세스하는 데 사용됨
    • 이벤트 폴더 및 MatchEnd 이벤트 - 이벤트 발생

    local PlayerManager = {}
    -- 서비스
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- 모듈
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- 이벤트
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
  2. 위의 respawnPlayerInLobby() , 새로운 로컬 함수 이름 checkPlayerCount() 을 추가합니다.


    -- 플레이어 변수
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
    local function checkPlayerCount()
    end
    local function respawnPlayerInLobby(player)
  3. 해당 함수 내에서는 if 다음 문을 사용하여 승자를 확인합니다. 해당 문에서:

    • activePlayers 테이블의 크기가 1인지 확인합니다.
    • 그렇다면, 발사 matchEnd 및 전달 gameSettings.endStates.FoundWinner 합니다.

    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end

플레이어 제거

플레이어가 제거되지 않으면 정확한 카운트를 유지할 수 없습니다.플레이어가 패배하면 플레이어 테이블에서 제거하여 정확한 플레이어 수를 유지합니다.그런 다음 활성 플레이어 테이블의 크기를 확인하여 승자가 있는지 확인합니다.

  1. 아래 checkPlayerCount() 에서 새로운 로컬 함수 removeActivePlayer() 를 생성하여 매개 변수 이름이 player 인 이름을 지정합니다.


    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end
    local function removeActivePlayer(player)
    end
  2. activePlayers 테이블에서 플레이어를 찾으려면 for 루프를 사용하여 반복합니다.그런 다음, 이름과 일치하는 플레이어가 함수에 전달되면 실행되는 if 문을 추가합니다.


    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    end
    end
    end
  3. 플레이어를 제거하려면 if 문에서:

    • 호출 table.remove() . 괄호 내에서 activePlayers 를 전달하고 playerKey - 테이블에서 제거할 플레이어를 테이블에 전달합니다.
    • playersLeft 개체의 값을 #activePlayers로 설정합니다.
    • checkPlayerCount()

    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    table.remove(activePlayers, playerKey)
    playersLeft.Value = #activePlayers
    checkPlayerCount()
    end
    end
    end

이벤트 연결 및 테스트

방금 만든 함수를 사용하려면 플레이어의 Died 이벤트에 연결된 익명 함수에서 호출하십시오.

  1. preparePlayer(). Died 이벤트 연결이 있는 익명 함수에서 호출하십시오 removeActivePlayer(). 그런 다음 플레이어를 매개변수로 전달하십시오.


    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    removeActivePlayer(player)
    end)
  2. 승리 플레이어를 찾으려면 테스트 서버 를 시작하십시오.플레이어가 하나뿐이면 출력 창에서 FoundWinner를 볼 수 있어야 합니다.

  3. 테스트를 계속하고 일치가 종료하십시오. 새로운 일치가 시작되면 출력 창에 오류가 나타납니다.

이 오류는 타이머가 중지되지 않아서 다음 섹션에서 수정될 것입니다.

타이머 중지

매치가 승리하는 플레이어로 끝날 때마다 타이머도 중지해야 합니다.시간이 끝나기 전에 타이머를 중지하려면 매치 종료 이벤트가 발생할 때마다 타이머가 중지되도록 하십시오.이벤트를 만드는 것의 이점 중 하나입니다.여러 상황에서 스크립트 원인과 결과 관계를 재사용할 수 있습니다.

  1. 매치매니저에서 stopTimer()라는 새로운 로컬 함수를 만들고, 내부에서 myTimer:stop()를 입력하여 타이머를 중지합니다.


    -- 매치 시간을 추적하기 위해 사용할 새로운 타이머 개체를 생성합니다.
    local myTimer = timer.new()
    -- 로컬 함수
    local function stopTimer()
    myTimer:stop()
    end
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  2. 매치가 종료될 때 타이머를 중지하려면 매치End 이벤트를 stopTimer()에 연결하십시오.


    -- 모듈 기능
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. 테스트 이전 오류가 더 이상 발생하지 않도록 서버를 시작합니다().플레이어 하나를 제외하고 모두 제거한 다음 경기가 끝나면 몇 초 동안 기다립니다.

다음 단계

두 승리 조건이 완료되었지만, 게임 루프를 완료하기 위해 아직 완료해야 할 작업이 남아 있습니다.예를 인스턴스, 승리한 플레이어는 로비로 결코 순간이동되지 않습니다.다음 단원에서는 경기가 플레이어에게 어떻게 종료되었는지 표시하고 게임을 재설정하여 마침내 전체 루프를 완료합니다.

완료된 스크립트

아래는 작업을 확인하기 위한 완료된 스크립트입니다.

플레이어 관리자 스크립트


local PlayerManager = {}
-- 서비스
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 모듈
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- 이벤트
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- 맵 변수
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- 값
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- 플레이어 변수
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
-- 로컬 함수
local function checkPlayerCount()
if #activePlayers == 1 then
matchEnd:Fire(gameSettings.endStates.FoundWinner)
end
end
local function removeActivePlayer(player)
for playerKey, whichPlayer in activePlayers do
if whichPlayer == player then
table.remove(activePlayers, playerKey)
playersLeft.Value = #activePlayers
checkPlayerCount()
end
end
end
local function respawnPlayerInLobby(player)
player.RespawnLocation = lobbySpawn
player:LoadCharacter()
end
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
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
respawnPlayerInLobby(player)
removeActivePlayer(player)
end)
end
-- 모듈 기능
function PlayerManager.sendPlayersToMatch()
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
playersLeft.Value = #activePlayers
end
-- 이벤트
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager

게임설정 스크립트


local GameSettings = {}
-- 게임 변수
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- 게임이 종료수 있는 가능한 방법.
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

게임 관리자 스크립트


-- 서비스
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"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- 이벤트
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
while true do
displayManager.updateStatus("Waiting for Players")
repeat
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
displayManager.updateStatus("Get ready!")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
local endState = matchEnd.Event:Wait()
print("Game ended with: " .. endState)
end

MatchManager 스크립트


local MatchManager = {}
-- 서비스
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 모듈 스크립트
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- 이벤트
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- 값
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- 매치 시간을 추적하기 위해 사용할 새로운 타이머 개체를 생성합니다.
local myTimer = timer.new()
-- 로컬 함수
local function stopTimer()
myTimer:stop()
end
local function timeUp()
matchEnd:Fire(gameSettings.endStates.TimerUp)
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- +1을 추가하면 타이머 표시가 0이 아닌 1로 끝나도록 보장합니다.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- 대기 시간을 설정하지 않으면 더 정확한 루프가 제공됩니다
task.wait()
end
end
-- 모듈 기능
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager