NPC 캐릭터의 비헤이비어는 캐릭터의 비헤이비어 스크립트에 의해 정의됩니다. 비헤이비어 스크립트는 캐릭터에게 어디로 갈지, 무엇과 전투할지, 다른 캐릭터와 어떻게 상호작용할지 등 월드에서 취할 비헤이비어를 지시하는 역할을 합니다. 경비와 야생동물과 같은 캐릭터에는 인식, 경계, 고용되거나 길들여지는 능력 등 추가적인 비헤이비어가 있을 수 있습니다.
NPC 비헤이비어는 NPC 캐릭터의 기존 비헤이비어에 부가적인 기능을 추가하는 사용자 정의 Verse 스크립트입니다. npc_behavior API를 통해 NPC 캐릭터가 생성 또는 소멸될 때 실행되는 코드를 정의할 수 있으며, 해당 API를 사용하여 의무병, 상인 또는 보스 등 커스텀 캐릭터를 생성할 수 있습니다. NPC 비헤이비어는 npc_behavior 추상 클래스에서 상속받으며, 사용할 /Fortnite.com/AI 모듈을 임포트해야 합니다.
NPC 비헤이비어 스크립트를 실행하려면 NPC 캐릭터 정의에 어태치해야 합니다. NPC 비헤이비어 스크립트가 캐릭터 정의와 상호작용하는 방식은 NPC 캐릭터 타입에 따라 다릅니다. 커스텀 타입 NPC는 액션 수행을 위한 비헤이비어 스크립트가 필요한 반면, 경비 및 야생동물 타입 NPC는 비헤이비어 스크립트가 주어지지 않은 경우 디폴트 비헤이비어를 실행합니다. NPC 캐릭터 정의 생성 및 다양한 캐릭터 타입에 대한 자세한 내용은 캐릭터 정의 페이지를 참고하세요.
이 튜토리얼에서는 NPC 비헤이비어 스크립트 생성하기의 기초를 살펴보며 NPC 생성 방법과 NPC가 목표를 향해 이동하는 방법을 알아봅니다.
새로운 NPC 비헤이비어 스크립트 생성하기
UEFN에서 경비를 생성하고 두 지점 간에 순찰하게 하는 NPC 비헤이비어 스크립트를 생성하려면 다음 단계를 따르세요.
UEFN에서 프로젝트를 열고 메뉴 바에서 Verse > Verse 익스플로러(Verse Explorer)로 이동합니다.
Verse 익스플로러에서 프로젝트 이름을 우클릭하고 프로젝트에 새로운 Verse 파일 추가(Add new Verse file to project)를 선택하여 Verse 스크립트 생성(Create Verse Script) 창을 엽니다.
Verse 스크립트 생성 창에서 NPC 비헤이비어(NPC Behavior)를 클릭하여 템플릿으로 선택합니다.
NPC 비헤이비어 이름(NPC Behavior Name) 필드의 텍스트를 장치 이름으로 변경하여 NPC 비헤이비어를 명명합니다. 이 예시에서 장치 이름은 my_first_npc_behavior입니다.
생성(Create)을 클릭하면 Verse 파일이 생성됩니다.
Verse 익스플로러에서 Verse 파일의 이름을 더블클릭하여 Visual Studio Code에서 엽니다.
코드를 저장하고 컴파일한 후 새 NPC 캐릭터 정의를 생성합니다. NPC 캐릭터 만들기에 대한 자세한 내용은 캐릭터 정의 페이지를 참고하세요.
my_first_behavior스크립트를 새 캐릭터 정의의 Verse 비헤이비어로 할당합니다.UEFN 툴바에서 세션 시작을 클릭하여 레벨을 플레이테스트합니다. 레벨을 플레이테스트할 때 NPC 생성 장치에서 생성된 캐릭터는 가까운 랜덤 지점을 선택해야 생성 및 이동할 수 있습니다. 해당 지점에 도달하면 일정 시간 동안 대기한 후 시작점으로 다시 돌아갑니다. 섬 설정 장치에서 Verse 디버그 드로 활성화를 선택한 경우 캐릭터가 이동하는 지점을 보여주는 박스와 함께 캐릭터가 포커스하는 지점을 나타내는 화살표도 그려집니다.
Navigatable
Navigatable API를 사용하여 캐릭터가 특정 타깃을 향해 이동하고 순찰, 지점 경비, 다른 캐릭터 따라가기 등의 비헤이비어를 수행하도록 지시할 수 있습니다. 경비 타입 NPC는 AI 순찰 경로 지점을 통해 이 비헤이비어를 할 수 있지만, 여기에서는 Verse 코드를 사용하여 레벨에 다른 추가 장치를 배치하지 않고 이 기능을 모든 타입의 캐릭터로 확장해 보겠습니다. 캐릭터의 navigatable 인터페이스를 통해 agent 또는 position에서 생성할 수 있는 navigation_target을 향해 캐릭터가 이동하도록 할 수 있습니다. 커스텀, 경비, 야생동물 타입 NPC는 모두 navigatable 인터페이스를 사용할 수 있습니다. 캐릭터의 navigatable 인터페이스를 얻으려면 먼저 캐릭터의 fort_character에 대한 레퍼런스를 얻어야 합니다. 이를 위해 GetFortCharacter[]를 호출해야 합니다.
# Get the Navigatable Interface, this allows you to tell it to move.
Navigatable := Character.GetNavigatable[]
템플릿 예시의 코드는 캐릭터가 생성되는 지점의 랜덤 오프셋 위치를 선택해 GoToPoint 변수에 위치를 저장합니다. 그러면 GotToPoint 및 캐릭터의 생성 지점 모두에서 navigatoin_target이 생성됩니다.
# Create a random offset from the spawn point to walk toward.
GoToPoint := NPCSpawnPoint + vector3{X := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
Y := GetRandomFloat(-DistanceFromSpawnPtToMove,DistanceFromSpawnPtToMove),
Z := 0.0 }
if(ShowAIDebug?):
Print(my_first_npc_behavior_message_module.OnNavigateBeginMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
# Create a navigation target from these two positions that the navigation interface can use.
NavTargetStart := MakeNavigationTarget(GoToPoint)
NavigateTo() 함수는 캐릭터가 navigation_target에 도달했는지 여부에 대한 정보가 포함된 navigation_result 열거형을 반환합니다. navigation_result의 값을 확인하여 타깃에 도달했는지 여부를 기반으로 캐릭터 비헤이비어를 부여할 수 있습니다.
# Check to see if something has interfered with the NPC reaching the intended location and print a
# message to the output log.
if (NavResultGoTo <> navigation_result.Reached):
if(ShowAIDebug?):
Print(my_first_npc_behavior_message_module.OnNavigateErrorMessage(Agent,GoToPoint.X,GoToPoint.Y,GoToPoint.Z), ?Duration := AIDebugDrawTime)
else:
# Once it arrives at its location, wait for this duration in seconds
Navigatable.Wait(?Duration := MoveToWaitDuration)캐릭터가 월드를 탐색하는 방식과 캐릭터가 이동할 수 있는 다양한 영역을 시각화하는 방법에 대한 자세한 내용은 내비게이션 메시 페이지를 참고하세요.
포커스
캐릭터가 액션을 수행할 때 캐릭터는 특정 타깃을 주시합니다. 캐릭터가 주시하는 특정 타깃을 캐릭터의 포커스라고 합니다. 캐릭터는 대화 중인 캐릭터, 공격 중인 타깃 또는 이동하려는 위치를 포커스합니다. focus_interface로 캐릭터가 포커스할 특정 타깃을 지정할 수 있습니다. 커스텀, 경비, 야생동물 타입 NPC는 모두 포커스 인터페이스를 사용할 수 있습니다. MaintainFocus() 함수는 캐릭터가 타깃을 포커스할 수 있게 하며, 그러한 타깃은 vector3 위치 또는 agent가 될 수 있습니다. focus_interface는 fort_character 인터페이스의 일부로, GetFocusInterface[]를 사용하여 얻을 수 있습니다.
# Get the Focus Interface, this allows you to tell it to look at something or somewhere.
Focus := Character.GetFocusInterface[]
템플릿 예시에서 캐릭터가 시작 위치로 다시 돌아온 후 코드는 MaintainFocus()를 사용하여 이전 navigation_target을 강제로 포커스하도록 합니다. 이로 인해 캐릭터가 뒤를 향해 걷게 되며 시작점으로 돌아가면서 뒤를 보게 됩니다.
# Leveraging concurrency to wait until the NPC reaches its destination, while the calls to look back at its origin point
# and drawing a debug arrow never completes, continuing, ensures only the NavigateTo can win the race.
NavResultGoToNext := race:
# Move back to its starting position.
Navigatable.NavigateTo(NavTargetEnd)
# Sets NPC to look at its previous position which will make it walk backwards.
# This is meant to show the utility of the focus interface.
block:
Focus.MaintainFocus(GoToPoint)
구속 가능
경비가 목표를 경비할 때 경비가 너무 멀리 벗어나지 않고 목표 주변 영역에 머물도록 해야 합니다. fort_leashable 인터페이스는 경비 타입 NPC 특정 인터페이스로, 이를 통해 경비가 순찰 시 벗어날 수 없는 타깃 주변 반경을 지정할 수 있습니다. 경비를 특정 위치 또는 다른 NPC에 구속할 수 있으며, 경비는 구속 타깃이 움직이면 구속 타깃 근처에 남아 있기 위해 위치를 업데이트합니다. 현재 커스텀 및 야생동물 타입 NPC 캐릭터는 fort_leashable 인터페이스를 사용할 수 없습니다. GetFortLeashable[]을 사용하여 fort_leashable 인터페이스를 얻을 수 있습니다.
# Get the Leash Interface, which lets you confine a guard to a certain area.
Leashable := Character.GetFortLeashable[]
회수 지점을 경비하거나 중요 NPC를 보호하는 것과 같은 경우 경비를 위치나 다른 에이전트에 구속할 수 있습니다. 각 구속에는 InnerRadius 및 OuterRadius가 있으며, 두 값은 경비가 구속 타깃으로부터 각각 얼마나 가까이 또는 얼마나 멀리 있어야 하는지를 cm 단위로 지정합니다. 템플릿 예시에서는 leashable 인터페이스를 사용하지 않지만 나만의 경비 NPC를 생성할 때 유용하게 사용할 수 있습니다.
# Leash the guard to a position so they stay between 500 and 1000
# cm of the position they're leashed to
Leashable.SetLeashPosition(NPCSpawnPoint, InnerRadius := 500.0, OuterRadius := 1000.0)
# Leash the guard to an agent so they stay between 500 and 1000
# cm of the agent they're leashed to
Leashable.SetLeashAgent(AgentToFollow, InnerRadius := 500.0, OuterRadius := 1000.0)
# Clear all leashes on the guard
Leashable.ClearLeash()
디버그 드로
파일 상단에 있는 이 템플릿은 디버그 드로를 위한 전용 채널을 정의합니다. 디버그 드로를 사용하여 테스트 목적으로 특정 게임 데이터를 시각화할 수 있습니다. 예를 들어, 캐릭터의 가시 범위를 시각화하거나 캐릭터가 이동하는 위치 주변에 셰이프를 그릴 수 있습니다. 이러한 디버그 셰이프를 시각화하려면 섬 설정(Island Settings)의 디버그(Debug) 탭에서 Verse 디버그 드로(Verse Debug Draw)를 활성화해야 하며, 이는 퍼블리싱된 경험에는 표시되지 않습니다. 파일 상단의 채널에서 단일 메서드를 통해 채널 내 디버그 셰이프를 숨기거나, 표시하거나, 모두 지울 수 있습니다.
# Create a dedicated debug channel to draw to for this behavior
npc_debug_draw := class(debug_draw_channel) {}
new_npc_behavior 템플릿 클래스는 시각화 및 이동에 사용되는 몇 가지 값을 정의합니다.
MoveToWaitDuration은 캐릭터가 이동 전에 한 지점에서 기다리는 시간(단위: 초)을 정의합니다.Verse# How long to wait in seconds after the NPC navigates to a point before moving on. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5}, MaxValue:=option{10.0} MoveToWaitDuration:float = 5.0DistanceFromSpawnPtToMove는 캐릭터가 이동할 생성 지점의 랜덤 오프셋 범위를 정의합니다.Verse# The negative min and absolute max x & y coordinate offset in centimeters to tell the NPC to move to @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.0} DistanceFromSpawnPtToMove:float = 1500.0ShowAIDebug로직 값으로 에디터에서 디버그 셰이프 그리기를 켜고 끌 수 있습니다.Verse# Whether to draw debug to the NPC channel when Verse Debug Draw is enabled in Island Settings. @editable: Categories:=array{my_first_npc_behavior_message_module.SettingsCategory} ShowAIDebug:logic = trueAIDebugDrawTime플로트로 디버그 드로 위치를 렌더링할 시간을 지정할 수 있습니다.Verse# How long in seconds to render the debug draw location and print text. # It is recommended to keep this in sync with MoveToWaitDuration otherwise the print will not be shown if a previous message is displayed. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5} AIDebugDrawTime:float = 5.0LookAtDebugDrawDuration플로트로 보기 화살표 디버그 드로를 렌더링할 시간을 지정할 수 있습니다.Verse# How long in seconds to render the look at arrow's debug draw. LookAtDebugDrawDuration:float = 0.5DebugDrawNPC채널은 디버그 드로 인스턴스를 정의하며 파일 상단에 정의된 채널을 사용합니다.Verse# How long in seconds to render the look at arrow's debug draw. @editable_number(float): Categories:=array{my_first_npc_behavior_message_module.SettingsCategory}, MinValue:=option{0.5} LookAtDebugDrawDuration:float = 0.5마지막으로
VerticalOffsetToNPCHead는 NPC의 골반부터 머리까지를 기준으로 디버그 보기 화살표를 그리기 위한 오프셋을 정의합니다. 이 오프셋이 없으면 디버그 보기 화살표가 NPC 중앙에서부터 그려집니다.Verse# Used for specifying a point offset from the NPC pelvis to the head to draw the look at arrow from. VerticalOffsetToNPCHead<private>:float = 55.0
new_npc_behavior 템플릿 클래스의 함수 두 개는 디버그 셰이프를 그립니다. DrawDebugLocation() 함수는 특정 위치에서 LookAtDebugDrawDuration 시간 동안 큰 점을 그립니다.
# This function draws a box around a specified position for a finite amount of time.
# NOTE: To see this in game, Verse Debug Draw must be enabled in Island Settings.
DrawDebugLocation(Location:vector3):void =
DebugDrawNPC.DrawPoint( Location,
?Color := NamedColors.SteelBlue,
?Thickness := 100.0,
?DrawDurationPolicy := debug_draw_duration_policy.FiniteDuration,
?Duration := AIDebugDrawTime )
DrawDebugLookAt() 함수를 사용하면 에이전트의 머리부터 보기 지점까지 화살표를 그려 캐릭터가 보고 있는 곳을 시각화할 수 있습니다.
# This function draws an arrow from the Agent's head to its look at point every half a second.
# NOTE: To see this in game, Verse Debug Draw must be enabled in Island Settings.
DrawDebugLookAt(Character:fort_character, LookAtPoint:vector3)<suspends>:void=
loop:
DebugDrawNPC.DrawArrow( Character.GetTransform().Translation + vector3{ Z := VerticalOffsetToNPCHead},
LookAtPoint,
?ArrowSize := 50.0,
?Color := NamedColors.Yellow,
?Thickness := 5.0,
?DrawDurationPolicy := debug_draw_duration_policy.FiniteDuration,
레벨에 캐릭터 추가하기
이제 NPC BehaviorScript에 대해 알아보았으니, 캐릭터를 생성하고 섬에서 스크립트를 사용해 보겠습니다. 다음 워크플로는 경비 타입 캐릭터용으로 디자인되었지만 NPC 비헤이비어 스크립트는 커스텀 및 야생동물 타입 캐릭터에서도 작동합니다.
MyFirstCharacterDefinition으로 명명된 새 NPC 캐릭터 정의를 생성합니다. 새 캐릭터 정의를 클릭하여 캐릭터 정의(Character Definition) 화면을 엽니다.
캐릭터 정의 화면에서 다음 프로퍼티를 수정합니다.
NPC 캐릭터 타입(NPC Character Type)에서 타입(Type)을 경비(Guard)로 설정합니다. 경비 인터페이스를 통해 경비 특정 캐릭터 기능에 액세스할 수 있어, 경비가 경계 또는 의심 상태가 되도록 하는 이벤트를 구성하거나 경비를 아군으로 사용하도록 고용하는 등의 작업을 할 수 있습니다. 경비는 무기를 장착할 수도 있지만 커스텀 및 야생동물 타입 캐릭터는 현재 무기 장착이 불가능합니다. 이름(Name) 탭에서 캐릭터의 이름을 변경할 수도 있습니다.
NPC 캐릭터 비헤이비어(NPC Character Behavior)에서 비헤이비어(Behavior)를 Verse 비헤이비어(Verse Behavior)로 설정합니다. 그런 다음 NPC 비헤이비어 스크립트(NPC Behavior Script)를
my_first_npc_behavior로 설정합니다. 캐릭터는 여전히 경비 인터페이스의 기능에 액세스할 수 있지만OnBegin및OnEnd실행 시 어떤 작업을 할지 결정하는 데 이 Verse 스크립트를 사용하게 됩니다.모디파이어(Modifiers) 탭의 경비 생성 모디파이어(Guard Spawn Modifier)에서 장식(Cosmetic) 탭을 클릭하여 캐릭터의 장식 외형을 변경합니다. 기존 장식 중에 선택하거나, 캐릭터 장식 리타기팅(Character Cosmetic Retargeting)을 활성화하여 커스텀 모델을 사용할 수 있습니다. 경비 및 커스텀 타입 캐릭터만 캐릭터 장식 리타기팅을 사용할 수 있으며, 야생동물 캐릭터는 이를 사용할 수 없습니다. 캐릭터 모디파이어 및 다양한 캐릭터 타입에 적용할 모디파이어에 대한 자세한 내용은 NPC 캐릭터 정의 페이지를 참고하세요.
모디파이어 탭에서 엘리먼트 추가(Add Element)를 클릭하여 캐릭터에 새 모디파이어를 추가합니다. 새 모디파이어의 타입을 인벤토리 모디파이어(Inventory Modifier)로 변경합니다. 인벤토리 모디파이어는 경비병만 사용할 수 있습니다.
인벤토리 모디파이어에서 엘리먼트 추가를 클릭하여 캐릭터의 인벤토리에 새 아이템을 추가합니다. 아이템 정의(Item Definition)를 무기, 아이템 또는 캐릭터가 보유해야 할 다른 무언가로 설정합니다. 캐릭터의 인벤토리에 여러 아이템을 추가할 수 있으며 캐릭터는 무기를 사용하여 싸우고, 아이템을 사용하여 치유합니다.
모디파이어 탭에서 엘리먼트 추가(Add Element)를 클릭하여 캐릭터에 새 모디파이어를 추가합니다. 새 모디파이어의 타입을 UI 모디파이어(UI Modifier)로 변경합니다.
UI 모디파이어에서 이름(Name) 탭을 클릭하여 캐릭터의 이름을 변경합니다. 캐릭터의 이름이 머리 위에 표시됩니다.
NPC 캐릭터 정의를 저장합니다. 콘텐츠 브라우저(Content Browser)에서 NPC 캐릭터 정의를 레벨로 드래그합니다. 이렇게 하면 자동으로 새 NPC 생성 장치가 만들어지고 캐릭터 정의가 할당됩니다.
NPC 생성 장치를 선택합니다. 아웃라이너(Outliner)의 사용자 옵션(User Options)에서 다음을 수행합니다.
생성 수(Spawn Count)를 20으로 설정합니다. 도움을 줄 경비 몇 명이 필요하니 이 값을 최대치까지 높여 마음껏 즐겨 보세요.
UEFN 툴바에서 세션 시작(Launch Session)을 클릭하여 레벨을 플레이테스트합니다. 플레이테스트 시 캐릭터가 생성되어 시작 지점과 근처의 랜덤 지점 사이를 순찰하며 도중에 있는 적과 교전합니다.
직접 해보기
지금까지 이 가이드를 통해 자신만의 커스텀 캐릭터를 만들기 위한 NPC 비헤이비어 스크립트를 생성하는 방법에 대해 배웠습니다. 추가 정보를 읽어보고 특정 타입의 캐릭터와 시나리오를 만드는 방법을 알아보려면 아래에 나와 있는 몇 가지 NPC 비헤이비어 튜토리얼을 확인해 보세요.