이 튜토리얼은 Verse 스탠드업 템플릿에 딸린 문서로, 코미디 클럽 내에서 사교 경험이나 시네마틱 경험을 뒷받침하는 장치의 사용법을 다음과 같이 보여줍니다.
디테일한 메타휴먼 애니메이터 에셋을 캐릭터 장치와 함께 사용하기
입력 트리거 장치로 플레이어 입력 바인딩에 게임플레이 이벤트 트리거하기
의자 장치로 플레이어를 한자리에 고정하여 경험 보여주기
Verse 장치는 아래에 설명된 Verse 코드의 핵심 개념을 통해 쇼를 실행합니다.
Verse 스탠드업 템플릿은 포트나이트 언리얼 에디터(Unreal Editor for Fortnite, UEFN)의 기능 예시(Feature Examples) 섹션에서 찾을 수 있습니다.
사용한 장치:
이 튜토리얼에 사용된 Verse 개념은 다음과 같습니다.
구독
If 문
배열
시네마틱 시퀀스
의자 장치 API
입력 트리거 장치 API
장치 상호작용을 위한 대부분의 세팅 수정은 Verse 코드를 통해 이루어지므로, 대다수 장치의 수정된 사용자 옵션은 축소되어 표시됩니다.
Island Settings(섬 설정)
Verse 스탠드업 템플릿용으로 수정된 섬 설정은 다음과 같습니다.
| Option | 값 | 설명 |
|---|---|---|
최대 플레이어(Max Players) | 1 | 이 템플릿은 싱글 플레이어 경험입니다. |
팀 크기(Team Size) | 1 | 한 팀만 필요합니다. |
게임 중 합류(Join In Progress) | Spectate | 플레이어는 이미 시작된 게임에 합류하는 경우 관전합니다. |
마지막 생성 후 이동 위치(After Last Spawn Go To) | 팀 인덱스(Team Index): 1 | 플레이어는 자신의 팀에서 부활합니다. |
음성 채팅(Voice Chat) | 전체 | 플레이어 간 음성 채팅이 허용됩니다. |
곡괭이를 갖고 시작(Start With Pickaxe) | False | 플레이어는 곡괭이 없이 게임을 시작합니다. |
다른 팀 관전 허용(Allow Spectating Other Teams) | 허용 안 함 | 플레이어는 다른 팀을 관전할 수 없습니다. |
시간 제한(Time Limit) | 120 | 시간 제한은 2시간으로 설정됩니다. |
등 장신구 숨기기(Hide Back Bling) | True | 등 장신구는 이 섬에 나타나지 않습니다. |
매달리기/넘기 허용(Allow Mantling/Hurdling) | False | 플레이어는 넘거나 매달릴 수 없습니다. |
전력질주 초당 에너지 소모(Sprinting Energy Cost Per Second) | 2.0 | 전력질주로 소모되는 에너지입니다. |
무적(Invincibility) | True | 플레이어는 무적입니다. |
건설 허용(Allow Building) | None | 플레이어는 건설할 수 없습니다. |
건설 시 환경 파괴(Building Can Destroy Environment) | False | 건설 시 환경이 파괴되지 않습니다. |
환경 피해(Environment Damage) | Off | 플레이어는 환경 피해를 줄 수 없습니다. |
무한 건설 재료(Infinite Building Materials) | False | 이 경험에서 건설은 할 수 없습니다. |
시간(Time of Day) | 00:00 | 밤 시간 설정입니다. |
조명 밝기(Light Brightness) | 0 | 이 경험의 모든 광원은 램프로부터 나옵니다. |
안개 두께(Fog Thickness) | 30% | 안개가 약간 낀 환경입니다. |
안개 색상(Fog Color) | 파란색 | 안개 색상을 결정합니다. |
커스텀 승리 팝업(Custom Victory Callout) | The Cheese Cannery에 와주셔서 감사합니다(Thank you for coming to The Cheese Cannery) | 게임 종료 후 플레이어에게 표시되는 팝업입니다. |
처치 메시지 표시(Show Elimination Feed) | False | 처치는 표시되지 않습니다. |
목재/석재/금속 자원 수 표시(Show Wood/Stone/Metal Resource Count) | False | 자원은 표시되지 않습니다. |
파티 처치 표시(Show Party Eliminations) | False | 파티 처치는 표시되지 않습니다. |
디버그(Debug) | True | 디버그 기능이 활성화됩니다. |
빠른 반복 작업 모드(Fast Iteration Mode) | True | 편집 모드와 플레이 모드 간의 빠른 반복 작업이 활성화됩니다. |
의자 장치
플레이어가 코미디 클럽에 들어오면, 조명을 밝힌 무대 앞에 의자가 하나 보입니다. 플레이어에게 이 의자에 앉으라는 메시지가 표시됩니다. 의자에 앉으면 플레이어는 계속 고정된 위치에 있게 되며, 플레이어를 나머지 경험으로 안내하는 이벤트 체인이 작동합니다.
다음은 의자 장치용으로 수정된 사용자 옵션(User Options)입니다.
| Option | 값 | 설명 |
|---|---|---|
의자 모델(Chair Model) | Custom | 이 경험에서 의자는 실제로 투명하게 제작된 다음, 클럽 환경에 잘 어울리도록 포트나이트 의자 사물로 교체됩니다. |
상호작용 각도(Interaction Angle) | 180도 | 의자 앞을 기준으로 상호작용에 필요한 양방향 각도를 결정합니다. |
상호작용 반경(Interaction Radius) | 1.2m | 플레이어가 의자에 앉을 수 있는 거리를 결정합니다. |
입력 트리거 장치
입력 트리거 장치는 의자 장치와 함께 작동합니다. 플레이어 입력을 다양한 액션에 바인딩하며, 액션은 플레이어가 재할당된 버튼을 누를 때마다 트리거됩니다. 입력 트리거는 퍼포먼스가 일어날 때 플레이어가 카메라를 변경하는 것을 허용하도록 환경설정됩니다.
장치에는 선택할 수 있는 12개의 입력이 포함되어 있습니다. 입력을 선택했으면 새 입력의 액션을 명확히 하기 위해 HUD 설명을 추가할 수 있습니다.
다음은 이 장치용으로 수정된 사용자 옵션입니다. 각 장치는 서로 다른 시네마틱 시퀀스 장치에 바인딩되므로, 장치마다 바인딩과 HUD 설명이 다릅니다.
| Option | 값 | 설명 |
|---|---|---|
포크리 입력(Creative Input) | 커스텀 5 (전력질주) | 이 장치가 수신하는 입력을 정의합니다. |
HUD 설명(HUD Description) | '이전 카메라(Previous Camera)' | 플레이어에게 새 입력을 설명합니다. |
등록 플레이어 행동(Registered Player Behavior) | 등록 필요(Require Registration) |
|
캐릭터 장치
캐릭터 장치로 플레이어나 씬의 다른 캐릭터와 직접 상호작용할 수 있습니다. 이 템플릿은 무대 위 루틴 진행 중에 순환하는 4개의 캐릭터를 사용합니다.
다음은 캐릭터 장치용으로 수정된 사용자 옵션입니다.
| Option | 값 | 설명 |
|---|---|---|
캐릭터(Character) | 캐릭터 선택 | 표시할 캐릭터를 결정합니다. |
커스텀 유휴 상태(Custom Idle) | 앉아 있는 중 | 캐릭터의 커스텀 유휴 상태 자세를 선택합니다. |
무작위 유휴 상태 시작(Random Idle Start) | True | 무작위 위치에서 유휴 상태를 시작할지 설정합니다. |
메인 캐릭터는 계단 백스테이지 위에 앉아 있고, 나머지 캐릭터는 뒤의 작은 방에서 대기하고 있습니다.
캐릭터 드롭다운 메뉴에서 다양한 캐릭터 스킨을 사용해 보면서 무대에서 어떻게 보이는지 확인해 보세요!
이 템플릿은 임포트한 메타휴먼 애니메이션을 사용합니다. 이러한 애니메이션을 캡처 및 임포트한 방법에 대해 자세히 알아보려면 메타휴먼 애니메이션 임포트하기 페이지를 참고하세요.
시네마틱 시퀀스 장치
6개의 시네마틱 시퀀스 장치를 통해 플레이어는 의자 장치에 앉아 다양한 각도에서 쇼를 볼 수 있습니다.
이 페이지에서는 시네마틱 시퀀스 제작을 상세히 다루지는 않습니다. 자세한 내용은 시퀀서와 컨트롤 릭 페이지를 참고하고, 한층 심화된 내용은 언리얼 엔진에서 무비를 제작하는 방법을 확인하세요.
이 장치에서 유일한 수정 사항은 로드된 시네마틱 시퀀스입니다.
Verse의 쇼 실행 방법
이 템플릿은 Verse를 사용하여 플레이어가 의자 장치에 앉으면 쇼를 시작할 뿐만 아니라, 카메라를 TV 모드(TV mode)라는 시네마틱 뷰로 변경합니다. 또한 다양한 보기 경험을 위해 플레이어가 다수의 카메라 간에 전환할 뿐만 아니라 TV 모드 또는 자유 시점(Free Look)으로 돌아갈 수 있도록 해 줍니다.
Verse 익스플로러를 사용하여 show_template_device.verse라는 프로젝트에 새 Verse 장치를 생성하고 템플릿으로 장치를 드래그합니다. Verse 파일을 더블클릭하여 Visual Studio Code에서 엽니다.
스탠드업 쇼를 실행하도록 돕는 템플릿에서 장치를 구성했으니, 이제 코드에서 이러한 장치를 참조해 보겠습니다.
show_template_device 파일에 다음 필드를 추가합니다.
먼저,
show_template_device클래스 정의 위에log_show_template_device로 명명한log_channel을 추가합니다.Verse# Create a custom log channel for the show_template_device. This helps with log filtering in complex games with lots of log sources. log_show_template_device := class(log_channel){} # A Verse-authored creative device that can be placed in a level show_template_device := class(creative_device):이제 어떤
Print()문이 이 장치에서 오는지 알 수 있도록show_template_device클래스 정의 상단에log_show_template_device채널을 사용하는 로거를 추가합니다.Verse# A Verse-authored creative device that can be placed in a level show_template_device := class(creative_device): # Logger that uses custom log channel. Logger:log = log{Channel := log_show_template_device}TheChair로 명명한 편집 가능 의자 장치입니다. 이 의자에 플레이어가 앉으면 스탠드업 쇼가 시작됩니다.Verse# The chair device the player should sit in. @editable TheChair:chair_device = chair_device{}MainSequence및TVModeSequence로 명명한 2개의 편집 가능 시네마틱 시퀀스 장치입니다.MainSequence는 스탠드업 쇼를 실행하는 시네마틱 시퀀스로, 레벨의 캐릭터 장치에서 애니메이션과 오디오를 구동합니다.TVModeSequence는 여러 각도 사이에서 전환하여 플레이어의 카메라를MainSquence를 따라가는 보기 모드로 전환합니다.Verse# The sequence that drives animation and audio on the character device in the level. @editable MainSequence:cinematic_sequence_device = cinematic_sequence_device{} # The sequence that drives the TV mode sequence for viewing in the level. @editable TVModeSequence:cinematic_sequence_device = cinematic_sequence_device{}CameraSwitches로 명명한cinematic_sequence_device의 편집 가능 배열입니다. 이 배열은 쇼 진행 중에 플레이어가 전환할 수 있는 각 카메라에 대한 레퍼런스를 보유합니다.Verse# A list of alternative camera sequences that are provided to view from during the main sequence. @editable CameraSwitches:[]cinematic_sequence_device = array{}4개의 편집 가능
input_trigger_device입니다. 각 장치는 플레이어 입력을 받아 다양한 카메라 모드 간에 전환합니다.ReturnToFreeLook트리거는 플레이어를 기본 카메라로 되돌리는 반면,ReturnToTVMode는 플레이어를TVModeSequence로 되돌립니다.NextCamera및PreviousMode카메라는 플레이어를CameraSwitches배열 내 여러 시네마틱 시퀀스 간에 전환합니다.Verse# An input trigger that will return us to free look while in the chair. @editable ReturnToFreeLook:input_trigger_device = input_trigger_device{} # An input trigger that will return us to TV mode when appropriate in the chair. @editable ReturnToTVMode:input_trigger_device = input_trigger_device{} # An input trigger that will choose the next camera while in the chair. @editableCurrentSequence로 명명한 선택적 시네마틱 시퀀스 장치 변수입니다.TVModeSequence와 같은 시네마틱 시퀀스가 재생 중인 경우, 이 옵션은 그에 대한 레퍼런스를 저장합니다. 캐릭터에 다수의 시네마틱 시퀀스를 한 번에 재생하면 안 되므로, 새 시퀀스로 전환 시 이 옵션을 사용하여 현재 시퀀스를 끌 수 있습니다.Verse# The alternative camera sequence that is playing if valid. var CurrentSequence:?cinematic_sequence_device = falseMainSequencePlaying및InTvMode로 명명한 2개의 로직 변수입니다. 이를 통해MainSequence또는TVModeSequence가 각각 재생 중일 때 추적할 수 있습니다.Verse# Helps us track when the main sequence on the character device is playing. var MainSequencePlaying:logic = false # When we are in TV mode. var InTVMode:logic = falseCurrentCameraIndex로 명명한 변수 int입니다. 현재 재생 중인CameraSwitches배열 내 시네마틱 시퀀스의 인덱스를 추적합니다.Verse# Keeps track of what camera we are viewing when using other cameras besides TV Mode. var CurrentCameraIndex:int = -1이 템플릿에서 참조된 모든 이벤트의 등록을 추적하는 5개의 선택적
cancelable변수입니다. 플레이어가 카메라를 전환하거나, 자유 시점 또는 TV 모드로 되돌리거나, 의자 장치에서 나갈 때 다른 함수를 실행해야 합니다. 이 튜토리얼 뒷부분에서 함수를 트리거하는 이벤트에 함수를 등록하고, 더 이상 필요하지 않을 때 취소할 수 있도록 각 등록에 대한 레퍼런스를 저장해 보겠습니다.Verse# Subscriptions to all the events we listen for while running. var ReturnToFreeLookSubscription:?cancelable = false var NextCameraSubscription:?cancelable = false var PrevCameraSubscription:?cancelable = false var ReturnToTVModeSubscription:?cancelable = false var ChairExitSubscription:?cancelable = falseVisual Studio Code에서 스크립트를 저장하고 컴파일하여 레벨 내 Verse로 제작된 장치를 업데이트합니다.
템플릿에서
show_template_device를 선택합니다. 디테일(Details) 패널에서 각 입력 트리거 및 시네마틱 시퀀스를 비롯한 스크립트 내 각 장치 레퍼런스를 레벨 내 관련 장치에 할당합니다.
시퀀스 트리거하기
플레이어가 의자 장치에 앉으면 쇼가 시작되며, 플레이어가 앉은 후 시네마틱 시퀀스를 시작하는 것이 좋습니다. 플레이어가 의자에 앉을 때 메인 시퀀스를 트리거하고 플레이어가 볼 수 있도록 TV 모드를 시작하려면 다음 단계를 따릅니다.
새 함수
RunSequence()를show_template_device클래스에 추가합니다. 이 함수는 쇼를 시작한 에이전트를 받아 MainSequence 및TVModeSequence를 둘 다 시작합니다. 비동기적으로 실행시키기 위해모디파이어를 RunSequence()에 추가합니다. 다른 코드를 이 함수와 동시적으로 실행하며 플레이어가RunSequence()코드를 방해하지 않고 카메라 뷰를 전환할 수 있도록 이 함수는 비동기식이어야 합니다.Verse# Handles running the main sequence which runs the character and TV mode sequences for viewing and then calls a function to await finishing. RunSequence(Agent:agent)<suspends>:void =RunSequence()에서 잠시 동안Sleep()을 호출하여 쇼 시작 전에 플레이어가 의자에 앉아 있는 애니메이션이 종료되도록 합니다. 그런 다음MainSequence에서Play()를 호출하고,MainSequencePlaying을 true로 설정합니다.Verse# Sleep for a second because we just entered the chair and the animation to sit takes a moment. Sleep(1.0) # Run the Main sequence on the character device and the TV mode viewing sequence. Logger.Print("Main Sequence Playing") set MainSequencePlaying = true MainSequence.Play()TVModeSequence에서Play()를 호출하여 카메라를 시네마틱 뷰로 변경하도록 쇼를 시작한 에이전트를 전달합니다.InTVMode를 true로 설정하고,AwaitMainSequenceEnding()을 호출한MainSequence가 종료되기까지 대기하는 새 함수를 호출하여 에이전트를 전달합니다. 다음 단계에서는 이 함수를 구성합니다. 완성된RunSequence()코드는 다음과 같습니다.Verse# Handles running the main sequence which runs the character and TV mode sequences for viewing and then calls a function to await finishing. RunSequence(Agent:agent)<suspends>:void = # Sleep for a second because we just entered the chair and the animation to sit takes a moment. Sleep(1.0) # Run the Main sequence on the character device and the TV mode viewing sequence. Logger.Print("Main Sequence Playing") set MainSequencePlaying = true MainSequence.Play()새 함수
AwaitMainSequecingEnding()을RunSequence()에서agent를 받는show_template_device클래스에 추가합니다. 이 함수는 백그라운드에서 실행되고MainSequence종료 시 트리거되어야 하기 때문에<suspends>모디파이어도 필요합니다.Verse# When the main sequence finishes, we clear the flag so that if the player sits back down, it will play again. AwaitMainSequencingEnding(Agent:agent)<suspends>:void =AwaitMainSequencingEnding()에서MainSequence.StoppedEvent()의Await()를 호출합니다.MainSequence가 종료되면MainSequencePlaying을false로 설정하고, 의자의Eject()함수를 사용하여 플레이어를 의자에서 내보냅니다. 완성된AwaitMainSequencingEnding()함수는 다음과 같습니다.Verse# When the main sequence finishes, we clear the flag so that if the player sits back down, it will play again. AwaitMainSequencingEnding(Agent:agent)<suspends>:void = MainSequence.StoppedEvent.Await() Logger.Print("Main Sequence Ended") set MainSequencePlaying = false # Kick the player out of the chair after the performance TheChair.Eject(Agent)2개의 새 함수
DoReturnToTVMode()및DoReturnToFreeLook()을show_template_device클래스에 추가합니다. 이러한 함수는 플레이어가 각각 TV 모드 또는 자유 시점으로 돌아갈 때의 로직을 처리하지만, 지금은 빈 상태로 남겨 두고 이후 단계에서 작성하면 됩니다.Verse# Returns us to our TV viewing mode sequence by checking where the main sequence is and aligning our playback to that point. DoReturnToTVMode(Agent:agent):void = Logger.Print("Return to TV Mode") # Determine if we are in TV mode or another camera sequence and return control to the main player camera. DoReturnToFreeLook(Agent: agent):void = Logger.Print("Return to Free Look")TheChair에 앉은 에이전트를 받는show_template_device클래스에 새 함수OnSeated()를 추가합니다.Verse# This function handles the player sitting down and starting up the performance if it isn't already running and setting up the input triggers. OnSeated(Agent:agent):void = Logger.Print("Player sat down")OnSeated()에서MainSequence가 아직 재생 중이 아닌 경우RunSequence()함수를 생성하여 의자 장치에 앉은 에이전트를 전달합니다. 그 외의 경우 동일한 에이전트로DoReturnToTVMode()를 호출합니다.Verse# This function handles the player sitting down and starting up the performance if it isn't already running and setting up the input triggers. OnSeated(Agent:agent):void = Logger.Print("Player sat down") # If the main sequence is not playing on the character device in the level, run it, otherwise if it is running then just return to the TV mode viewing experience. if (MainSequencePlaying = false): spawn{RunSequence(Agent)} else: DoReturnToTVMode(Agent)새 함수
OnChairExited()를 의자에서 벗어난 플레이어를 받는show_template_device클래스에 추가합니다. 이 함수의 로직은 이후 단계에서 작성할 것입니다.Verse# Handles the player leaving the chair and removing access to the input triggers that are available while in the chair. OnChairExited(Agent:agent):void = Logger.Print("Player got up")OnBegin()에서TheChair.SeatedEvent를OnSeated()함수에 등록합니다. 이제 플레이어가TheChair에 앉을 때마다 쇼가 실행됩니다.Verse# Runs when the device is started in a running game. OnBegin<override>()<suspends>:void = Logger.Print("Standup Template device started") TheChair.SeatedEvent.Subscribe(OnSeated)
Visual Studio Code에서 스크립트를 저장하고 컴파일한 후 UEFN 툴바에서 세션 시작(Launch Session)을 클릭하여 템플릿을 플레이테스트합니다. 게임을 실행할 때 의자 장치에 앉으면 쇼가 시작되고 플레이어의 카메라가 시네마틱 모드로 설정됩니다. 쇼가 종료되면 플레이어는 의자에서 내보내집니다.
카메라 전환하기
쇼 진행 중에 TheChair에 앉은 플레이어는 각기 다른 시네마틱 시퀀스로 처리되는 다수의 각기 다른 카메라 뷰 간에 전환할 수 있습니다. 이러한 다른 시퀀스 간 전환 로직을 구성하려면 아래 단계를 따릅니다.
새 함수
DoCameraSwitch()를show_template_device클래스에 추가합니다. 이 함수는 전환 중인 카메라의 에이전트뿐만 아니라CameraSwitches의 시네마틱 시퀀스 인덱스에 해당하는int도 받습니다.Verse# Switches us between camera sequences that have been specified by stopping any current ones and moving to the next appropriate one on the list. DoCameraSwitch(Agent:agent, Value:int):void =DoCameraSwitch()의if문에서,CameraSwitches배열 내 값 인덱스에서 시네마틱 시퀀스를 얻습니다. 그런 다음CurrentSequence에 시네마틱 시퀀스가 포함되어 있는지 여부를 확인하고Stop()을 호출하여 현재 재생 중인 시퀀스를 중지합니다.Verse# Switches us between camera sequences that have been specified by stopping any current ones and moving to the next appropriate one on the list. DoCameraSwitch(Agent:agent, Value:int):void = if (CameraSwitch := CameraSwitches[Value]): Logger.Print("Switching Cameras to {Value}") # Stop any currently playing other camera sequence. if (PlayingSequence := CurrentSequence?): PlayingSequence.Stop(Agent)CameraSwitch의Play()를 호출하여 새 시네마틱 시퀀스 재생을 시작합니다. 그런 다음 현재 재생 중인 시퀀스를 알리도록CurrentSequence를 설정합니다. 마지막으로, 전환하는 카메라의agent를ReturnToTVMode및ReturnToFreeLook입력 트리거에Register()하여 다른 카메라를 볼 때 해당 모드로 돌아가도록 합니다. 완성된DoCameraSwitch()함수는 다음과 같습니다.Verse# Switches us between camera sequences that have been specified by stopping any current ones and moving to the next appropriate one on the list. DoCameraSwitch(Agent:agent, Value:int):void = if (CameraSwitch := CameraSwitches[Value]): Logger.Print("Switching Cameras to {Value}") # Stop any currently playing other camera sequence. if (PlayingSequence := CurrentSequence?): PlayingSequence.Stop(Agent) # Start up the new camera viewing sequence.다음 카메라와 이전 카메라 간에 전환하려면,
DoNextCamera()및DoPreviousCamera()라는 매우 유사한 2개의 함수를 구성해야 합니다. 먼저, 다음 카메라에 대한 로직을 작성하겠습니다. 새 함수DoNextCamera()를show_template_device클래스에 추가합니다. 이 함수는 전환 중인 카메라의agent를 받습니다.Verse# Switches to the next camera on our list, or the first if we are in TV mode. DoNextCamera(Agent:agent):void = Logger.Print("Next Camera")DoNextCamera()에서 플레이어가 현재 TV 모드인지 여부를 확인합니다. TV 모드인 경우TVModeSequence를Stop()하고InTVMode를 false로,CurrentCameraIndex를-1로 설정합니다. 여기에서-1을 사용하는 이유는CameraSwitches배열에서 인덱스가0인 다음 시네마틱 시퀀스로 인덱싱하기 위해서입니다.Verse# If we are currently viewing from TV Mode, end that sequence and clear associated values. if (InTVMode?): TVModeSequence.Stop(Agent) set InTVMode = false set CurrentCameraIndex = -1그런 다음 현재 카메라의 인덱스를 기준으로 전환할 다음 카메라를 알아내야 합니다. 이렇게 하려면 새 변수
NextCameraValue를CameraSwitches.Length및CurrentCameraIndex + 1의Mod에 설정합니다. 이를 통해NextCameraValue를0과CameraSwitches길이 사이의 값으로 범위제한하고,CameraSwitches배열 외부의NextCameraValue를 구하지 않게 됩니다.NextCameraValue를 구했다면CurrentCameraValue를NextCameraValue로 설정하고,agent및CurrentCameraIndex를 전달하는DoCameraSwitch()를 호출합니다. 완성된DoNextCamera()함수는 다음과 같습니다.Verse# Switches to the next camera on our list, or the first if we are in TV mode. DoNextCamera(Agent:agent):void = Logger.Print("Next Camera") # If we are currently viewing from TV Mode, end that sequence and clear associated values. if (InTVMode?): TVModeSequence.Stop(Agent) set InTVMode = false set CurrentCameraIndex = -1이전 카메라로 전환하려면
show_template_device클래스에DoPreviousCamera()로 명명한 새 함수를 추가합니다.DoNextCamera()의 코드를 이 함수로 복사합니다. 플레이어가 TV 모드인지 여부를 확인할 때CurrentCameraIndex를-1이 아닌0으로 설정합니다. 또한NextCameraValue를CameraSwitches.Length및CurrentCameraIndex - 1의Mod로 변경합니다. 완성된DoPreviousCamera()함수는 다음과 같습니다.Verse# Switches us to the previous camera on the list or last camera if we are leaving TV mode. DoPreviousCamera(Agent:agent):void = Logger.Print("Prev Camera") # If we are currently viewing from TV Mode, end that sequence and clear associated values. if (InTVMode?): TVModeSequence.Stop(Agent) set InTVMode = false set CurrentCameraIndex = 0
플레이어가 TheChair에 앉아 있고 CameraSwitches 내 다른 카메라에서 보고 있는 경우, TV 모드 또는 자유 시점으로 돌아갈 수 있습니다. 앞서 DoReturnToFreeLook() 및 DoReturnToTVMode() 함수를 구성했으며, 이제 두 함수를 작성하겠습니다.
DoReturnToFreeLook()함수에서 플레이어가 현재 TV 모드인지 여부를 확인합니다. TV 모드인 경우TVModeSequence를Stop()하고InTVMode를 false로 설정합니다.CurrentSequence에서도 마찬가지로CurrentSequence에 시네마틱 시퀀스가 포함되어 있는지 여부를 확인하여, 포함된 경우Stop()을 호출하고, false로 설정합니다.Verse# If TV Mode is active, stop it. if (InTVMode?): TVModeSequence.Stop(Agent) set InTVMode = false # If we are playing another viewing experience, stop it. if (TempSeq := CurrentSequence?): TempSeq.Stop(Agent) set CurrentSequence = false이제 에이전트를
ReturnToTVMode입력 트리거에Register()하고, 플레이어가 이미 자유 시점인 상태에서 자유 시점으로 돌아가지 않도록ReturnToFreeLook트리거에서Unregister()합니다. 완성된DoReturnToFreeLook()함수는 다음과 같습니다.Verse# Determine if we are in TV mode or another camera sequence and return control to the main player camera. DoReturnToFreeLook(Agent: agent):void = Logger.Print("Return to Free Look") # If TV Mode is active, stop it. if (InTVMode?): TVModeSequence.Stop(Agent) set InTVMode = false # If we are playing another viewing experience, stop it.TV 모드로 돌아갈 때
MainSequence의 현재 시간에TVModeSequence를 시작해야 하므로DoReturnToTVMode()함수에는 더 많은 로직이 필요합니다. 이 함수가 호출되면 먼저 플레이어가 이미 TV 모드인지 여부를 확인합니다. TV 모드인 경우 해야 할 일이 없으므로return합니다. 그런 다음CurrentSequence에 시네마틱 시퀀스가 포함되어 있는지 확인하여 포함된 경우Stop()을 호출하고,false로 설정합니다.Verse# If we are already in TV mode no need to return to it. if (InTVMode?): return # If we have another camera sequence playing, stop it and clear associated values. if (TempSeq := CurrentSequence?): TempSeq.Stop(Agent) set CurrentSequence = false이제
MainSequence의 재생 지점이 어디인지 알아내어 같은 지점에서TVModeSequence를 시작해야 합니다.GetPlayBackTime()을 호출하여MainSequence의 재생 시간을 구하고 변수CurrentSeekTime에 저장합니다.SetPlaybackTime()을 사용하여TVModeSequence의 재생 시간을CurrentSeekTime으로 설정하고, 에이전트를 전달하는 시퀀스를Play()합니다. 그런 다음InTVMode를true로 설정합니다.Verse# Figure out where the main sequence is in its playback and start up the TV mode sequence at the same spot to provide the proper viewing experience. CurrentSeekTime := MainSequence.GetPlaybackTime() TVModeSequence.SetPlaybackTime(CurrentSeekTime) TVModeSequence.Play(Agent) set InTVMode = true마지막으로,
ReturnToTVMode입력 트리거에서 에이전트를Unregister()하고ReturnToFreeLook트리거에Register()합니다. 완성된DoReturnToTVMode()함수는 다음과 같습니다.Verse# Returns us to our TV viewing mode sequence by checking where the main sequence is and aligning our playback to that point. DoReturnToTVMode(Agent:agent):void = Logger.Print("Return to TV Mode") # If we are already in TV mode no need to return to it. if (InTVMode?): return # If we have another camera sequence playing, stop it and clear associated values. if (TempSeq := CurrentSequence?):
모든 요소 연결하기
이 튜토리얼의 앞부분에서 많은 함수를 구성했으니, 이제 해당 함수를 호출하는 다양한 입력 트리거에 모든 함수를 함께 연결할 차례입니다.
OnSeated()에서 에이전트를ReturnToFreeLook,NextCamera,PreviousCamera입력 트리거에Register()합니다. 이 트리거들은 플레이어가 의자에 맨 처음 앉을 때 초기에 액세스하게 되는 트리거입니다. 그런 다음 각 입력 트리거를 관련 함수에 등록하여ReturnToFreeLookSubscription,NextCameraSubscription,PreviousCameraSubscription을 설정합니다. 같은 방식으로ReturnToTVModeSubscription및ChairExitSubscription을 설정합니다.Verse# Register for the input trigger for free look and subscribe to the pressed event when sitting. ReturnToFreeLook.Register(Agent) set ReturnToFreeLookSubscription = option{ReturnToFreeLook.PressedEvent.Subscribe(DoReturnToFreeLook)} # Register for the input trigger for the next camera and subscribe to the pressed event when sitting. NextCamera.Register(Agent) set NextCameraSubscription = option{NextCamera.PressedEvent.Subscribe(DoNextCamera)} # Register for the input trigger for the previous camera and subscribe to the pressed event when sitting. PreviousCamera.Register(Agent)선택적 취소 가능 값을 받는 새 함수
CancelSubscription()을show_template_device클래스에 추가합니다.CancelSubscription()에서Subscription에 값이 포함되어 있는지 여부를 확인합니다. 포함된 경우Cancel()합니다. 완성된CancelSubscription()은 다음과 같습니다.Verse# Cancel a subscription if it is valid. CancelSubscription(Subscription:?cancelable):void = if (SubscriptionToCancel := Subscription?): SubscriptionToCancel.Cancel()플레이어가 의자에서 나갈 때 플레이어의 현재 재생 중인 모든 시퀀스를 중지하고 플레이어가 등록된 입력 트리거의 모든 등록을 취소해야 합니다.
OnChairExited()함수에 대해서는DoReturnToFreeLook()에서처럼 플레이어가 TV 모드인지,CurrentSequence에 시네마틱 시퀀스가 포함되는지 확인합니다. 포함되는 경우 각 시퀀스에서Stop()을 호출하고, 플레이어가 TV 모드인 경우InTVMode를false로 설정합니다. 그런 다음CurrentSequence를false로 설정합니다.Verse# Stop the TV camera view when we leave the chair if it is active. if (InTVMode = true): TVModeSequence.Stop(Agent) set InTVMode = false # Stop the camera sequence we were using if it is active when we leave the chair. if (TempSeq := CurrentSequence?): TempSeq.Stop(Agent) # Clear whatever the current sequence was when we leave the chair.이제 각 등록을
CancelSubscription()함수에 전달하여 모든 플레이어 등록을 취소합니다. 또한 플레이어가 의자를 떠날 때 입력 트리거 버튼에 액세스해서는 안 되므로 각 입력 트리거에서 플레이어를Unregister()합니다. 완성된OnChairExited()함수는 다음과 같습니다.Verse# Handles the player leaving the chair and removing access to the input triggers that are available while in the chair. OnChairExited(Agent:agent):void = Logger.Print("Player got up") # Stop the TV camera view when we leave the chair if it is active. if (InTVMode = true): TVModeSequence.Stop(Agent) set InTVMode = false # Stop the camera sequence we were using if it is active when we leave the chair.
Visual Studio Code에서 스크립트를 저장하고 컴파일한 후 UEFN 툴바에서 세션 시작(Launch Session)을 클릭하여 템플릿을 플레이테스트합니다. 플레이테스트 시 의자 장치에 앉으면 쇼가 시작됩니다. 쇼 진행 중에는 TV 모드, 자유 시점, 다양한 기타 카메라 각도 사이에서 전환할 수 있습니다. TV 모드로 돌아오면 TV 모드 시퀀스가 메인 시퀀스에 맞춰 정렬됩니다. 쇼가 종료되면 자유 시점으로 돌아오고 의자에서 나옵니다.