이 섹션에서는 Verse 스크립트를 추가하고 Verse 장치를 배치하여 게임플레이를 커스터마이징하는 방법을 설명합니다.

Verse > Verse 익스플로러(Verse Explorer) 로 이동하여 Verse 스크립트를 생성합니다.

그런 다음 프로젝트 파일 이름을 우클릭하고 프로젝트에 새 Verse 파일 추가(Add new Verse file to project) 를 선택합니다.

Verse 장치(Verse Device) 를 선택하고 이름을 지정한 다음 생성(Create)을 클릭합니다. 이 튜토리얼에서는 Verse 장치의 이름을 'Stronghold_Game_Manager'로 지정했습니다.

장치의 Verse 파일을 더블클릭하여 Verse 스크립트를 불러옵니다. 아래 코드를 복사하여 붙여 넣습니다.
using { /Fortnite.com/AI }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }
# 성채는 삼엄한 경비가 있는 성채에서 모든 적을 처치하는 것이 목표인 게임 모드입니다.
# 성채 게임 관리 Verse 장치는 성채에서 AI를 관리하고, 모니터링하고, 제어하는 데 사용됩니다.
stronghold_game_manager := class(creative_device):
# 경비 처치를 위해 추적해야 할 경비 생성 장치 레퍼런스
@editable
GuardsInitialSpawners:[]guard_spawner_device := array{}
# 멀티플레이어 확장용 경비 처치를 위해 추적해야 할 경비 생성 장치 레퍼런스
@editable
GuardsInitialSpawnersAdditional:[]guard_spawner_device := array{}
# 성채 경비가 플레이어의 존재를 알게 되면 트리거되는 지원 경비 생성 장치에 대한 레퍼런스
@editable
GuardsReinforcementSpawners:[]guard_spawner_device := array{}
# 멀티플레이어 확장용 성채 경비가 플레이어의 존재를 알게 되면 트리거되는 지원 경비 생성 장치에 대한 레퍼런스
@editable
GuardsReinforcementSpawnersAdditional:[]guard_spawner_device := array{}
# 목표 표시 및 추적을 위한 장치 레퍼런스
@editable
ObjectiveTracker:tracker_device := tracker_device{}
# 게임 내 지원군 메시지를 표시하는 장치 레퍼런스
@editable
MessageDeviceReinforcement:hud_message_device := hud_message_device{}
# 게임 내 예비 메시지를 표시하는 장치 레퍼런스
@editable
MessageDeviceFallback:hud_message_device := hud_message_device{}
# 플레이어가 탐지되지 않고 성채를 완료하는 경우 승리로 게임을 종료하는 장치 레퍼런스
@editable
EndGameVictoryDeviceUndetected:end_game_device := end_game_device{}
# 플레이어가 탐지된 상태에서 성채를 완료하는 경우 승리로 게임을 종료하는 장치 레퍼런스
@editable
EndGameVictoryDeviceDetected:end_game_device := end_game_device{}
# 플레이어의 재시도 횟수가 부족할 경우 게임을 실패로 종료하는 장치 레퍼런스
@editable
EndGameFailDevice:end_game_device := end_game_device{}
# 플레이어 생명 수 조정 가능
@editable
var PlayerRetries:int = 2
# 성채 구속 위치를 참조하는 장치
@editable
ReinforcementLeashReference:stronghold_leash_position := stronghold_leash_position{}
# 예비 구속 위치를 참조하는 장치
@editable
FallbackLeashReference:stronghold_leash_position := stronghold_leash_position{}
# 예비 전환 후 비활성화해야 하는 구속
@editable
LeashesToDisableForFallback:[]stronghold_leash_position := array{}
# 폭발을 위한 장치
@editable
ExplosiveDevice:explosive_device := explosive_device{}
# 경비 인식은 이 스크립트에 의해 모니터링되며, 다른 스크립트는 해당 이벤트를 등록할 수 있습니다.
# 경비가 지원 요청을 할 때 브로드캐스트되는 이벤트
ReinforcementsCalledEvent:event(agent) = event(agent){}
# 경비가 성채 중앙을 방어할 때 브로드캐스트되는 이벤트
FallbackEvent:event() = event(){}
# 경비가 의심하게 되면 브로드캐스트되는 이벤트
GuardsSuspiciousEvent:event(agent) = event(agent){}
# 모든 경비가 인식하지 못할 때 브로드캐스트되는 이벤트
GuardsUnawareEvent:event(agent) = event(agent){}
# 플레이어가 탐지되면 브로드캐스트되는 이벤트
PlayerDetectedEvent:event(agent) = event(agent){}
# 모든 경비가 목표물을 놓쳤을 때 브로드캐스트되는 이벤트
PlayerLostEvent:event(agent) = event(agent){}
# 특정 경계 상태에서 인식 변화를 모니터링하는 경비 목록
# 지원 경비를 저장하는 변수
var<private> NumGuardsSpawned:int := 0
# 모든 성채 경비를 저장하는 변수
var<private> StrongholdGuards:[]agent := array{}
# 지원 경비를 저장하는 변수
var<private> ReinforcementGuards:[]agent := array{}
# 현재 의심 상태인 경비 목록
var<private> SuspiciousGuards : []agent = array{}
# 현재 플레이어의 존재를 아는 경비 목록
var<private> AlertedGuards : []agent = array{}
# 현재 조사 중인 경비 목록
var<private> InvestigatingGuards : []agent = array{}
# 초기 경비 생성 장치, 멀티플레이어 세션이 있는 추가 생성 장치 포함
var<private> GuardsInitialSpawnersInternal:[]guard_spawner_device = array{}
# 지원 경비 생성 장치, 멀티플레이어 세션이 있는 추가 생성 장치 포함
var<private> GuardsReinforcementSpawnersInternal:[]guard_spawner_device = array{}
# 게임플레이 로직 변수
# 모든 성채 경비 생성 장치의 제거 횟수를 추적하는 변수
var<private> GuardsEliminated:int := 0
# 지원이 호출되었는지 여부를 추적하는 변수
var<private> ReinforcementTriggered:logic := false
# 예비 이벤트가 트리거되었는지 추적하는 변수
var<private> FallbackTriggered:logic := false
# 경비에게 탐지된 첫 번째 플레이어 에이전트를 저장하는 변수
var<private> DetectedPlayer:?player := false
# 실행 중인 게임에서 장치가 시작되면 실행됩니다.
OnBegin<override>()<suspends>:void=
# 난이도 조절을 위한 활성 플레이어 확인
AllPlayers := GetPlayspace().GetPlayers()
NumberOfActivePlayers := AllPlayers.Length
set GuardsInitialSpawnersInternal = GuardsInitialSpawners
set GuardsReinforcementSpawnersInternal = GuardsReinforcementSpawners
# 플레이어가 2명을 초과할 때 경비 생성 장치 추가
if (NumberOfActivePlayers > 2):
set GuardsInitialSpawnersInternal += GuardsInitialSpawnersAdditional
set GuardsReinforcementSpawnersInternal += GuardsReinforcementSpawnersAdditional
var NumInitialGuards:int = 0
for (GuardSpawner : GuardsInitialSpawnersInternal):
GuardSpawner.Enable()
SubscribeToGuardSpawnerEvents(GuardSpawner);
set NumInitialGuards += GuardSpawner.GetSpawnLimit()
ObjectiveTracker.SetTarget(NumInitialGuards)
for (GuardReinforcementSpawner : GuardsReinforcementSpawnersInternal):
SubscribeToGuardSpawnerEvents(GuardReinforcementSpawner);
# 지원 생성 이벤트 등록
GuardReinforcementSpawner.SpawnedEvent.Subscribe(OnReinforcementSpawned)
GuardReinforcementSpawner.AlertedEvent.Subscribe(OnReinforcementAlerted)
GuardReinforcementSpawner.UnawareEvent.Subscribe(OnReinforcementUnaware)
# 플레이어 처치 이벤트 등록
for (StrongholdPlayer : AllPlayers, StrongholdPC := StrongholdPlayer.GetFortCharacter[]):
StrongholdPC.EliminatedEvent().Subscribe(OnPlayerEliminated)
StartGameplay()
SubscribeToGuardSpawnerEvents(SpawnerDevice:guard_spawner_device):void =
SpawnerDevice.SpawnedEvent.Subscribe(OnGuardSpawned)
SpawnerDevice.EliminatedEvent.Subscribe(OnGuardEliminated)
SpawnerDevice.SuspiciousEvent.Subscribe(OnGuardSuspicious)
SpawnerDevice.AlertedEvent.Subscribe(OnGuardAlerted)
SpawnerDevice.TargetLostEvent.Subscribe(OnGuardLostTarget)
SpawnerDevice.UnawareEvent.Subscribe(OnGuardUnaware)
# 처치된 경비 추적 시작 및 폭발 트리거
StartGameplay()<suspends>:void =
ObjectiveTracker.AssignToAll()
Sleep(3.0)
if (FirstPlayer:=GetPlayspace().GetPlayers()[0]):
ExplosiveDevice.Explode(FirstPlayer)
# 경비 생성 장치가 경계 이벤트를 수신하면 실행되며 첫 번째 경고 이벤트만 고려합니다.
OnGuardAlerted(InteractionResult:device_ai_interaction_result):void=
if:
not ReinforcementTriggered?
set DetectedPlayer = option{player[InteractionResult.Target?]}
Guard:=InteractionResult.Source?
then:
var NumGuards:int = ObjectiveTracker.GetTarget()
# 경비 생성 장치에 설정된 경비 수만큼 생성되도록 지원 경비 생성 장치 활성화
for (GuardReinforcementSpawner : GuardsReinforcementSpawnersInternal):
GuardReinforcementSpawner.Enable()
set NumGuards += GuardReinforcementSpawner.GetSpawnLimit()
ObjectiveTracker.SetTarget(NumGuards)
# 게임 내 메시지 표시 및 지원 도착 시 알림 메시지 표시
MessageDeviceReinforcement.Show()
set ReinforcementTriggered = true
# 신호 지원 이벤트
ReinforcementsCalledEvent.Signal(Guard)
# 경비가 이전에 추가되지 않은 경우 경계 상태의 경비 목록에 추가
if(Guard:=InteractionResult.Source?):
if (not AlertedGuards.Find[Guard]):
set AlertedGuards += array{Guard}
option {set SuspiciousGuards = SuspiciousGuards.RemoveFirstElement[Guard]}
option {set InvestigatingGuards = InvestigatingGuards.RemoveFirstElement[Guard]}
# 경비가 플레이어의 존재를 알게 되면 플레이어 탐지 이벤트 브로드캐스트
if (AlertedGuards.Length = 1):
PlayerDetectedEvent.Signal(Guard)
# 지원 경비 생성 장치가 경계 이벤트를 수신하면 실행됩니다.
OnReinforcementAlerted(InteractionResult:device_ai_interaction_result):void=
if:
not FallbackTriggered?
Guard:=InteractionResult.Source?
then:
# 경계 상태의 지원 경비가 목표물을 공격하도록 구속 해제
ReinforcementLeashReference.ClearLeashOnGuard(Guard)
# 지원 경비 생성 장치가 미인식 이벤트를 수신하면 실행
OnReinforcementUnaware(Guard:agent):void=
if (not FallbackTriggered?):
# 구속 다시 설정
ReinforcementLeashReference.ApplyLeashOnGuard(Guard)
# 경비 생성 장치가 미인식 이벤트를 수신하면 실행
OnGuardSuspicious(Guard:agent):void=
if (not SuspiciousGuards.Find[Guard]):
set SuspiciousGuards += array{Guard}
# 경비 1명이 의심 상태가 되면 의심 이벤트 브로드캐스트
if:
SuspiciousGuards.Length = 1
AlertedGuards.Length = 0
InvestigatingGuards.Length = 0
then:
GuardsSuspiciousEvent.Signal(Guard)
# 경비 생성 장치가 미인식 이벤트를 수신하면 실행
OnGuardUnaware(Guard:agent):void=
option {set AlertedGuards = AlertedGuards.RemoveFirstElement[Guard]}
option {set SuspiciousGuards = SuspiciousGuards.RemoveFirstElement[Guard]}
option {set InvestigatingGuards = InvestigatingGuards.RemoveFirstElement[Guard]}
# 의심, 경계 또는 조사 중인 경비가 없는 경우 미인식 이벤트 브로드캐스트
if:
SuspiciousGuards.Length = 0
AlertedGuards.Length = 0
InvestigatingGuards.Length = 0
then:
GuardsUnawareEvent.Signal(Guard)
# 경비가 플레이어를 놓치면 경계 상태의 경비 목록에서 삭제하고, 모든 경비가 플레이어를 놓쳤을 때 이벤트를 알립니다.
OnGuardLostTarget(InteractionResult:device_ai_interaction_result):void=
if (Guard := InteractionResult.Source?):
if (not InvestigatingGuards.Find[Guard]):
set InvestigatingGuards += array{Guard}
# 경계 상태의 경비가 없는 경우 플레이어 실종 이벤트 브로드캐스트
if (set AlertedGuards = AlertedGuards.RemoveFirstElement[Guard]):
if (AlertedGuards.Length = 0):
PlayerLostEvent.Signal(Guard)
# 지원 경비가 생성될 때 실행됩니다. 각 지원 경비는 성채에 경고를 보낸 플레이어를 공격하도록 강제됩니다.
OnReinforcementSpawned(Guard:agent):void=
set ReinforcementGuards += array{Guard}
ReinforcementLeashReference.ApplyLeashOnGuard(Guard)
# 성채 경비에게 경고한 플레이어를 목표로 지정합니다.
if (Target := DetectedPlayer?):
for (GuardReinforcementSpawner : GuardsReinforcementSpawnersInternal):
GuardReinforcementSpawner.ForceAttackTarget(Target, ?ForgetTime:=30.0)
# 성채에서 경비가 생성되면 실행됩니다.
OnGuardSpawned(Guard:agent):void=
set StrongholdGuards += array{Guard}
set NumGuardsSpawned += 1
# 초기 또는 지원 경비 생성 장치가 제거될 때 실행됩니다.
OnGuardEliminated(InteractionResult:device_ai_interaction_result):void=
set GuardsEliminated += 1
if (EliminatedAgent := InteractionResult.Target?):
# 경계 상태의 경비 목록에서 처치된 경비 제거
option {set AlertedGuards = AlertedGuards.RemoveFirstElement[EliminatedAgent]}
option {set SuspiciousGuards = SuspiciousGuards.RemoveFirstElement[EliminatedAgent]}
option {set InvestigatingGuards = InvestigatingGuards.RemoveFirstElement[EliminatedAgent]}
option {set StrongholdGuards = StrongholdGuards.RemoveFirstElement[EliminatedAgent]}
if (EliminationAgent := InteractionResult.Source?):
# 처치 시마다 추적기 장치의 진행률 값 증가
ObjectiveTracker.Increment(EliminationAgent)
if (ReinforcementTriggered?):
if (NumGuardsSpawned - GuardsEliminated = 3):
StartFallback()
# 지원 경비를 제외하고 모든 경비가 처치된 경우 게임 모드 종료
if (GuardsEliminated >= NumGuardsSpawned):
EndGameVictoryDeviceDetected.Activate(EliminationAgent)
else:
# 지원 경비를 포함하여 모든 경비가 처치된 경우 게임 모드 종료
if (GuardsEliminated >= NumGuardsSpawned):
EndGameVictoryDeviceUndetected.Activate(EliminationAgent)
# 성채 중앙을 방어할 경계 상태의 경비가 몇 남았을 때 새로운 예비 경비 지정
StartFallback():void=
# 성채 건물 내부로 후퇴하는 경비에게 게임 내 메시지 표시
MessageDeviceFallback.Show()
set FallbackTriggered = true
for (LeashDevice : LeashesToDisableForFallback):
LeashDevice.DisableLeashAndPatrolPaths()
FallbackLeashPosition := FallbackLeashReference.GetTransform().Translation
FallbackEvent.Signal()
for (Guard : StrongholdGuards):
FallbackLeashReference.ApplyLeashOnGuard(Guard)
# 플레이어 처치 이벤트 수신 시 실행
OnPlayerEliminated(EliminationResult:elimination_result):void=
set PlayerRetries -= 1
if (PlayerRetries = 0, Agent := EliminationResult.EliminatedCharacter.GetAgent[]):
EndGameFailDevice.Activate(Agent)

다음으로, Verse > Verse 코드 빌드(Build Verse Code) 로 이동하여 Verse 스크립트를 컴파일합니다.

All/프로젝트 이름/CreativeDevices/ 로 이동하여 Verse 장치를 선택합니다.

그런 다음 Verse 장치를 지도로 드래그합니다. Verse 스크립트를 컴파일한 후에만 표시됩니다.
Verse 장치를 선택한 상태에서 디테일(Details) 패널로 이동하여 아래와 같이 사용자 옵션(User Options) 을 업데이트합니다.

옵션 | 값 | 설명 |
---|---|---|
게임 내 표시(Visible in Game) | False | 게임이 진행되는 동안 장치가 표시되지 않습니다. |
Guards_InitialSpawners | 배열 엘리먼트: 3 | 더하기 기호를 클릭하여 이 설정에 세 개의 요소를 추가합니다. |
0 | Guard Spawner | 성채에서 초기 경비를 생성하는 데 사용되는 모든 장치의 배열입니다. |
1 | Guard Spawner Sniper Tower 1 | 성채에서 초기 경비를 생성하는 데 사용되는 모든 장치의 배열입니다. |
2 | Guard Spawner Sniper Tower 2 | 성채에서 초기 경비를 생성하는 데 사용되는 모든 장치의 배열입니다. |
Guards_ReinforcementSpawner | Guard Spawner Reinforcement | 지원 경비를 생성합니다. |
ObjectiveTracker | Tracker | 성채 목표와 처치 횟수를 표시합니다. |
MessageDeviceReinforcement | HUD Message Device Reinforcement | 화면에 지원 메시지를 표시합니다. |
MessageDeliverFallback | HUD Message Device Fallback | 화면에 예비 메시지를 표시합니다. |
EndGameVictoryDeviceUndetected | End Game Device Undetected | 승리 및 미탐지 종료 화면을 표시합니다. |
EndGameVictoryDeviceDetected | End Game Device Detected | 승리 및 미탐지 종료 화면을 표시합니다. |
EndGameFailDevice | End Game Device Fail | 플레이어의 생명이 소진되어 실패한 종료 화면을 표시합니다. |
EliminationCount | 6 | 탐지되지 않고 성채를 완료하는 데 필요한 경비 처치 횟수를 결정합니다. |
EliminationCountWithReinforcement | 10 | 지원 경비가 트리거된 상태에서 성채를 완료하는 데 필요한 경비 처치 횟수를 결정합니다. |
PlayerRetries | 2 | 플레이어가 성채를 성공적으로 완료하기 위해 시도해야 하는 생명 수를 결정합니다. 플레이어의 생명이 소진되면 성채는 실패합니다. |
StrongholdLeashReferernce | Leash Position Stronghold | 구속 위치 장치가 이 위치를 성채 구속의 원점으로 사용합니다. |
FallbackLeashReference | Leash Position Fallback | 구속 위치 장치가 이 위치를 예비 구속의 원점으로 사용합니다. |
StrongholdLeashInnerRadius | 2400.0 | 성채 구속의 내부 반경을 센티미터 단위로 결정합니다. 외부 반경보다 작아야 합니다. |
StrongholdLeashOuterRadius | 2500.0 | 성채 구속의 외부 반경을 결정합니다. |
DefendFallbackLeashInnerRadius | 700.0 | 방어 예비 구속의 내부 반경을 센티미터 단위로 결정합니다. 외부 반경보다 작아야 합니다. |
DefendFallbackLeashOuterRadius | 750.0 | 방어 예비 구속의 외부 반경을 센티미터 단위로 결정합니다. |
다음 섹션
%verse-stronghold-template-4-add-devices-in-unreal-editor-for-fortnite:topic%