팀 구성하기
이 섹션에서는 게임 시작 시 헌터 팀과 사물 팀을 구성하여 시작 영역으로 순간이동시키는 방법을 알아봅니다.
이 페이지에는 이 게임플레이에 필요한 게임플레이 메커니즘의 실행법을 보여주는 Verse 스니펫이 포함되어 있습니다. 아래 단계를 따라 이 튜토리얼의 6단계에 있는 전체 스크립트를 복사합니다.
팀을 올바르게 구성하려면 다음 단계를 따릅니다.
-
새 함수 SetupTeams()를 생성합니다. 여기에서는 사물이 처치되는 시점에 대한 함수, 플레이어가 게임에 참가할 때 하는 일에 대한 함수 등 나중에 정의할 함수에 대해 다양한 구독을 구성합니다.
# 라운드가 시작되면 팀 장치를 구독하고, 헌터 에이전트를 랜덤으로 선택하고, 헌터 타이머를 활성화하고, 사물 에이전트를 설정하고, 게임 영역으로 순간이동시킵니다. SetUpTeams()<suspends>:void = Logger.Print("Setting up teams.") -
먼저 사물 팀의 점수 타이머 SuccessEvent(사물 팀 TeamManager의 처치됨 이벤트)를 구독하고, 점수 관리 장치의 부여 점수를 설정합니다.
# 라운드가 시작되면 팀 장치를 구독하고, 헌터 에이전트를 랜덤으로 선택하고, 헌터 타이머를 활성화하고, 사물 에이전트를 설정하고, 게임 영역으로 순간이동시킵니다. SetUpTeams()<suspends>:void = Logger.Print("Setting up teams.") # 사물 팀 점수 타이머를 구독하고, 점수 보상을 설정하고, 사물 팀의 처치됨 이벤트를 구독합니다. PropTeam.ScoreTimer.SuccessEvent.Subscribe(PropTeam.OnPropsScore) PropTeam.ScoreManager.SetScoreAward(PropTeam.ScorePerSecond) PropTeam.TeamManager.TeamMemberEliminatedEvent.Subscribe(OnPropEliminated) # 사물 에이전트가 처치될 때 발생합니다. -
다음으로는, 헌터 팀에도 동일한 작업을 수행합니다. 그런 다음 헌터 팀의 대기 타이머에 헌터들에게 부여할 만큼의 생성 지연을 설정합니다.
# 라운드가 시작되면 팀 장치를 구독하고, 헌터 에이전트를 랜덤으로 선택하고, 헌터 타이머를 활성화하고, 사물 에이전트를 설정하고, 게임 영역으로 순간이동시킵니다. SetUpTeams()<suspends>:void = Logger.Print("Setting up teams.") # 사물 팀 점수 타이머를 구독하고, 점수 보상을 설정하고, 사물 팀의 처치됨 이벤트를 구독합니다. PropTeam.ScoreTimer.SuccessEvent.Subscribe(PropTeam.OnPropsScore) PropTeam.ScoreManager.SetScoreAward(PropTeam.ScorePerSecond) PropTeam.TeamManager.TeamMemberEliminatedEvent.Subscribe(OnPropEliminated) # 사물 에이전트가 처치될 때 발생합니다. # 헌터 팀의 대기 타이머를 구독하고 지속 시간을 설정합니다. 또한 헌터 팀의 처치 이벤트도 구독합니다. HunterTeam.WaitTimer.SuccessEvent.Subscribe(HuntersGo) HunterTeam.WaitTimer.SetMaxDuration(HunterTeam.SpawnDelay) HunterTeam.TeamManager.EnemyEliminatedEvent.Subscribe(OnHunterEliminated) # 헌터 에이전트가 사물 에이전트를 처치할 때 발생합니다. -
계속
SetupTeams()내에서 시작하는 헌터 및 사물 에이전트 배열을 초기화한 다음, 게임을 시작하기에 충분한 수의 플레이어가 있는지 확인하는 동안 대기 HUD를 활성화합니다. 플레이어 수가 충분하면 대기 HUD를 비활성화합니다.# 시작하는 헌터 및 사물 에이전트 배열을 초기화합니다. 서버에서 플레이어를 얻고 플레이어 수를 찾습니다. var StartingHunterAgents:[]agent = array{} var StartingPropAgents:[]agent = array{} var Players:[]player = GetPlayspace().GetPlayers() # 플레이어를 기다리는 데 적절한 HUD를 활성화합니다. HUDControllerWaiting.Enable() # 라운드를 시작하기에 충분한 수의 플레이어가 있는지 확인합니다. set Players = WaitingForMorePlayers.WaitForMinimumNumberOfPlayers(Players) Logger.Print("Round started.") # 대기 HUD를 비활성화하고 다음으로 우선순위가 높은 HUD를 사용합니다. HUDControllerWaiting.Disable() -
이제 라운드가 시작되었으니, 플레이어가 매치에 참가하거나 매치에서 제거되었을 때 일어나는 일을 처리해야 합니다. 여기에서 구독을 구성하며, 이 함수들은 나중에 정의합니다.
# 이제 라운드가 시작되었으니, 매치에 추가되거나 매치에서 제거되는 플레이어를 처리해야 합니다. 해당 이벤트를 구독합니다. GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded) GetPlayspace().PlayerRemovedEvent().Subscribe(OnPlayerRemoved) -
시작하는 헌터의 수는 게임 내 플레이어 수에 기반합니다. 헌터 1명이 10명의 플레이어를 처리하게 할 수는 없으므로, 공식을 바탕으로 헌터의 수를 설정하는 함수를 구성해 보겠습니다. 공식에 사용하기 위해 플레이어 수를 플로트로 변환합니다.
# 플레이어 수와 플레이어 수당 헌터 에이전트의 수를 기반으로 게임에서 시작하는 헌터 에이전트의 수를 계산합니다. NumberOfPlayers:float = 1.0 * Players.Length # 다음 Ceil 함수에 사용할 수 있도록 Players.Length를 플로트로 변환합니다. -
이제 시작하는 헌터의 수를 다음 공식의 상한으로 설정합니다. 그런 다음 초기 헌터가 플레이어 목록에서 랜덤으로 선택되도록 모든 플레이어의 배열을 셔플합니다.
# 플레이어 수와 플레이어 수당 헌터 에이전트의 수를 기반으로 게임에서 시작하는 헌터 에이전트의 수를 계산합니다. NumberOfPlayers:float = 1.0 * Players.Length # 다음 Ceil 함수에 사용할 수 있도록 Players.Length를 플로트로 변환합니다. if (NumberOfStartingHunters:int = Ceil[NumberOfPlayers / Max(1.1, HunterTeam.HunterAgentPerNumberOfPlayers)]): # 플레이어를 셔플한 다음, 시작하는 헌터 에이전트를 얻기 위해 배열을 슬라이스합니다. 남은 플레이어는 시작하는 사물 에이전트가 됩니다. var RandomizedPlayers:[]agent = Shuffle(Players) -
0과 시작하는 헌터 수 사이의 크기로 랜덤화된 배열을 슬라이스합니다. 이는 초기 헌터 팀이 되므로, StartingHunterAgents로 설정합니다. 나머지 플레이어는 초기 사물 팀이 되므로 StartingPropAgents로 설정합니다.
# 플레이어 수와 플레이어 수당 헌터 에이전트의 수를 기반으로 게임에서 시작하는 헌터 에이전트의 수를 계산합니다. NumberOfPlayers:float = 1.0 * Players.Length # 다음 Ceil 함수에 사용할 수 있도록 Players.Length를 플로트로 변환합니다. if (NumberOfStartingHunters:int = Ceil[NumberOfPlayers / Max(1.1, HunterTeam.HunterAgentPerNumberOfPlayers)]): # 플레이어를 셔플한 다음, 시작하는 헌터 에이전트를 얻기 위해 배열을 슬라이스합니다. 남은 플레이어는 시작하는 사물 에이전트가 됩니다. var RandomizedPlayers:[]agent = Shuffle(Players) if (set StartingHunterAgents = RandomizedPlayers.Slice[0,NumberOfStartingHunters]) {} if (set StartingPropAgents = RandomizedPlayers.Slice[NumberOfStartingHunters,RandomizedPlayers.Length]) {} # 시작하는 헌터 에이전트를 반복작업하여 헌터 팀에 할당합니다. 그런 다음 헌터 대기 타이머를 시작합니다. Logger.Print("Setting {StartingHunterAgents.Length} hunter agent(s).") for (StartingHunterAgent : StartingHunterAgents): HunterTeam.InitializeAgent(StartingHunterAgent) HunterTeam.WaitTimer.Start() # 시작하는 사물 에이전트를 반복작업하여 사물 팀에 할당합니다. 플레이 영역으로 순간이동시킵니다. Logger.Print("Setting {StartingPropAgents.Length} prop agent(s).") -
팀이 설정되면, 대기실 순간이동 장치를 활성화하여 사물을 시작 방 외부로 순간이동하고 심장 박동을 활성화합니다. 그런 다음 대기실 순간이동 장치는 이제 필요하지 않으므로 비활성화합니다. 마지막으로 PropsRemainingTracker에서 남은 사물 수를 사물 팀 크기로 설정합니다.
LobbyTeleporter.Enable() for (StartingPropAgent : StartingPropAgents): PropTeam.InitializeAgent(StartingPropAgent) PropTeam.HeartBeat.SetUpUI(StartingPropAgent) LobbyTeleporter.Activate(StartingPropAgent) LobbyTeleporter.Disable() # 남은 사물 추적기의 목표 및 값을 현재 사물 수로 설정합니다. # 향후 사물이 처치되면 값만 업데이트할 것입니다. PropTeam.PropsRemainingTracker.SetTarget(PropTeam.Count()) PropTeam.UpdatePropsRemainingTracker()
플레이어 처치 관리하기
헌터는 모든 사물을 처치하여 헌터로 바꾸면 승리합니다. 사물이 처치될 때 헌터에게 점수를 부여하고, 처치된 사물을 헌터 팀으로 옮기려면 다음 단계를 따릅니다.
-
OnHunterEliminated()로 명명된 함수를 생성합니다. 앞서 헌터 팀 관리 장치 EnemyEliminatedEvent를 이 함수에 구독했으므로, 이 함수는 헌터가 사물을 처치할 때마다 활성화됩니다.
# 헌터 에이전트가 사물 에이전트를 처치하면 점수를 부여합니다. 점수는 남은 사물 에이전트 수로 나뉩니다. OnHunterEliminated(HunterAgent:agent):void = Logger.Print("Hunter agent eliminated a prop agent.") -
먼저 남은 사물 에이전트의 수에 비례하여 헌터들에게 점수를 부여해야 합니다.
PropTeamSize로 나뉜MaxEliminationScore와 동일한 변수EliminationAward를 생성합니다. 헌터 팀 점수 관리 장치를 해당 점수로 설정한 다음, 처치를 기록한 헌터에게 점수를 부여합니다.# 헌터 에이전트가 사물 에이전트를 처치하면 점수를 부여합니다. 점수는 남은 사물 에이전트 수로 나뉩니다. OnHunterEliminated(HunterAgent:agent):void = Logger.Print("Hunter agent eliminated a prop agent.") PropTeamSize := PropTeam.Count() if (EliminationAward := Floor(HunterTeam.MaxEliminationScore / PropTeamSize)): Logger.Print("Awarding {EliminationAward} points.") HunterTeam.ScoreManager.SetScoreAward(EliminationAward HunterTeam.ScoreManager.Activate(HunterAgent) -
또한 사물이 처치될 때 사물 팀에 일어나는 일도 처리해야 합니다. OnPropEliminated()로 명명된 함수를 생성합니다. OnHunterEliminated()와 마찬가지로, 앞서 이 함수를 구독했습니다. 사물이 처치되면 PropTeam의 EliminateAgent() 함수를 사용하여 처치된 사물을 사물 팀에서 제거한 다음, HunterTeam의 InitializeAgent() 함수로 해당 사물을 헌터로 초기화해야 합니다.
# 사물 에이전트가 처치되면 사물 팀에서 해당 사물을 제거하고, 라운드 종료를 확인하고, 헌터로 설정합니다. OnPropEliminated(PropAgent:agent):void = Logger.Print("Prop agent eliminated.") spawn{ PropTeam.EliminateAgent(PropAgent) } HunterTeam.InitializeAgent(PropAgent)
게임에 참가 및 퇴장하는 플레이어 관리하기
플레이어가 라운드 중간에 게임에 참가하는 경우, 해당 플레이어는 헌터로 생성되어야 합니다.
-
이를 처리할 OnPlayerAdded() 함수를 생성합니다. 이 함수는 참가하는 플레이어를 헌터로 초기화하기만 합니다.
# 플레이어가 라운드 중간에 매치에 참가하는 경우, 해당 플레이어를 헌터로 만듭니다. OnPlayerAdded(Player:player):void = Logger.Print("A player joined the game.") HunterTeam.InitializeAgent(Player) -
매치에서 나가는 플레이어의 경우 조금 더 복잡합니다. 플레이어가 매치에서 나가면 소속 팀에서 해당 플레이어를 제거해야 하며, 해당 플레이어가 나가는 것으로 인해 게임이 종료되는지도 확인해야 합니다. 나가는 플레이어가 마지막 사물 또는 유일한 헌터일 수 있기 때문입니다. 이 로직은 각 팀에서 EliminateAgent() 함수에 의해 처리되므로, 제거된 플레이어가 어떤 팀 소속이었는지에 따라 해당 함수의 인스턴스를 생성합니다.
# 플레이어가 매치에서 나갈 때 플레이어가 소속됐던 팀을 확인한 다음, 라운드 종료를 확인합니다. OnPlayerRemoved(Player:player):void= Logger.Print("A player left the game.") if (PropTeam.FindOnTeam[Player]): Logger.Print("Player was a Prop.") spawn{ PropTeam.EliminateAgent(Player) } if (HunterTeam.FindOnTeam[Player]): Logger.Print("Player was a Hunter.") spawn{ HunterTeam.EliminateAgent(Player) }
라운드 종료
모든 팀이 구성되었다면, 각 팀의 크기를 모니터링하여 라운드 종료를 확인해야 합니다. 게임은 둘 중 한 팀이 빈 상태가 되거나 라운드 시간이 다 되면 종료되므로, 둘 중 어느 상황이 먼저 일어났는지 확인하기 위해 race 표현식을 사용합니다.
-
OnBegin() 함수 끝의 race 표현식에서 Await()은 헌터 팀과 사물 팀의 TeamEmptyEvent를 모두 대기하며, 그런 다음 RoundTimer의 AwaitEnd() 함수가 옵니다. 경합이 끝나면 다음 단계에서 정의할 EndRound() 함수를 호출합니다.
# 사물 또는 헌터 에이전트가 더는 없는 경우(어느 쪽이 먼저 일어나든 관계없음), 라운드 타이머가 종료되는 경우, 또는 라운드가 종료되는 경우입니다. race: PropTeam.TeamEmptyEvent.Await() HunterTeam.TeamEmptyEvent.Await() RoundTimer.AwaitEnd() Logger.Print("Round ending.") EndRound() -
EndRound() 함수에서 사물 팀의 각 플레이어에 대해 심장 박동 센서를 비활성화하고 RoundSettings 장치에서 EndRound()를 호출해야 합니다. RoundSettings 장치의 EndRound() 함수에는 플레이어를 전달해야 하므로, 플레이어 배열에서 첫 번째 플레이어를 얻어 인스티게이터로 전달합니다.
# 심장 박동 VFX를 지운 다음, 라운드를 종료합니다. EndRound():void= PropTeam.HeartBeat.DisableAll() # EndRound에 전달할 아무 플레이어나 얻습니다. Players:[]player = GetPlayspace().GetPlayers() if (RoundEndInstigator := Players[0]): Logger.Print("Round ended.") RoundSettings.EndRound(RoundEndInstigator)