퀵스타트

이 페이지에서는 Strix로 온라인 게임을 만드는 법을 간단히 설명합니다. Strix의 주요 기능과 그것을 게임에서 이용하는 방법도 간단히 설명합니다.

준비

먼저 "Strix Cloud 설정"에 나와 있는 순서에 따라 Strix 서버를 클라우드에서 실행합니다.

Unreal Engine을 시작하고 3자 템플릿(스타터 콘텐츠 포함)으로 새 프로젝트를 만듭니다. 이것은 이 설명 부분에만 해당하는 것으로, 원하는 게임 타입 어디서나 Strix를 이용할 수 있습니다.

본 설명에 필요한 프로젝트를 만들었으면 Unreal Editor를 끄고 "SDK 설치"의 설명에 따라 Unreal 프로젝트에 Strix Unreal SDK 플러그인을 설치합니다.

참고

이번 설명은 Unreal Engine 4.21로 작성한 것입니다. Unreal Engine은 계속 발전하기 때문에 Unreal Engine 버전이 다르면 Unreal Editor의 UI가 다르게 보일 수 있습니다. 이번 설명에서는 4.21을 이용하는 것이 제일 좋습니다.

초기 설정

새 프로젝트에서는 먼저 최초 연결을 담당할 GameInstance 클래스를 만듭니다.

  • Unreal 프로젝트를 엽니다.

  • 현재 브라우저에서 새로 추가하기 메뉴로 이동하여 기본 자산 만들기 아래 블루프린트 클래스를 선택합니다.

    ../../_images/addgameinstance1.png
  • 여기서는 GameInstance 클래스를 확대하겠습니다. 따라서 모 클래스 선택 창에서 GameInstance를 검색하여 선택합니다.

    ../../_images/addgameinstance2.png
  • 콘텐츠 브라우저에 새 GameInstance가 생깁니다. 여기에 StrixGameInstance처럼 설명식 이름을 붙입니다.

  • 설정 > 게임별 설정 > 프로젝트 설정에서 맵 & 모드 아래 GameInstance를 검색합니다. 검색을 마치면 현재 GameInstance가 지정되어 있는 드롭다운 상자가 보입니다. GameInstnace를 새 StrixGameInstance로 설정합니다. 이렇게 하면 Unreal이 StrixGameInstance를 GameInstance로 이용합니다. 더 복잡한 게임이라면 서버 브라우저 구현과 같은 것에는 GUI 위젯으로 연결 로직을 구현하기를 권장합니다. 단, 이번 예에서는 GameInstance를 이용합니다. 게임 시작 시점에 실행되고 Strix Blueprint 함수는 원하는 곳 어디서나 호출할 수 있기 때문입니다.

  • 콘텐츠 브라우저로 돌아와서, 새 게임 인스턴스를 더블 클릭하여 블루프린트로 열고 다음 변수를 추가합니다. Master Hostname이나 Application ID를 모를 경우, Strix Cloud 설정에서 위치를 확인하시기 바랍니다.

    Master Hostname

    String

    마스터 서버의 호스트 이름입니다. Strix Cloud 페이지에서 확인할 수 있습니다.

    Master Port

    int

    마스터 서버의 포트 번호입니다. Strix Cloud를 이용할 때는 항상 9122입니다.

    Application Id

    String

    애플리케이션의 고유한 애플리케이션 ID입니다. Strix Cloud 페이지에서 확인할 수 있습니다.

    Member Properties

    Strix Property Map

    Strix의 스트럭트 타입 중 하나입니다. 클라이언트 속성을 나타냅니다.

    Room Properties

    Strix Property Map

    방의 속성을 나타내는 것입니다.

  • 변수가 추가되었으므로 이 값을 설정하고 첫 설치를 해보겠습니다. StrixGameInstance 블루프린트에서 먼저 Event Shutdown 이벤트 노드를 추가하고 Stop Strix Network 노드를 아웃풋에 연결합니다. 이어서 Event Init에서 Master Hostname과 Master Port, Application Id 변수를 설정합니다(아직 하지 않은 경우).

    ../../_images/gameinstance1.png
  • 이것이 끝나면 Strix에 필요한 정보를 몇 가지 설정해야 합니다. 먼저 Member PropertiesRoom Properties 모두에 대해 설정 노드를 만듭니다. 다음으로 Make Strix Property Map 함수를 이용하여 속성별로 새 속성 맵을 만듭니다. 아래 그림과 같이 이것들의 아웃풋을 Set String PropertySet Int Property 함수에 따로 입력합니다. 이 속성들이 제대로 작동하기 위해서는 멤버 속성에는 “name”이라고 하는 String(플레이어의 이름)이, 방 속성에는 “capacity”라고 하는 Int와 “name”이라고 하는 String이 필요합니다.

    ../../_images/gameinstance2.png

참고

찾기 힘든 버그를 막기 위해 속성 이름은 대소문자를 구분합니다. 대부분은 속성의 표시 이름이 사용될 이름과 다릅니다. 타입도 마찬가지입니다. String 속성에 정수를 설정하려고 하면 요청은 서버 측에서 실패합니다.

서버에 연결하기

변수를 설정했으므로 Strix에 연결을 시도할 차례입니다.

  • 다음으로 실행할 함수는 Initialize Strix Network 함수입니다. 이 함수는 애플리케이션 ID를 가져와서 Strix 서비스를 설정합니다. 다음으로, Connect to Master Server 노드를 추가합니다. 이때 마스터 호스트 이름과 호스트 포트는 지정된 상태입니다. 이 노드에는 성공 콜백과 실패 콜백의 두 가지 콜백이 있습니다. 콜백 각각에서 드래그하여 이벤트 추가아래 커스텀 이벤트 만들기를 선택합니다. 이들 콜백에 설명식 이름을 붙입니다. 예컨대 성공 콜백에는 OnMasterConnectSuccess, 실패 콜백에는 OnMasterConnectFailure를 붙이는 것입니다.

    ../../_images/gameinstance3.png ../../_images/gameinstance4.png
  • Strix는 이벤트 중심이므로 콜백이 자주 출현합니다. 연결하라는 요청을 하고 나면 연결 노드의 아웃풋에서 즉시 실행되지만, 연결 후에 동작이 실행되도록 OnSuccess 이벤트에서 다음 단계를 실행해야 합니다. OnFailure 이벤트에서 나온 실패한 연결을 처리하는 로직을 몇 가지 넣어도 됩니다.

  • 콜백 설정을 마쳤으므로 방 서버에 연결할 수 있습니다. 그 전에 이 연산이 작동하도록 정보를 모아야 합니다. 이를 위해서는 Search Node 함수를 호출해야 합니다. 이번 예에서는 조건을 이용하지 않고 받은 배열에서 첫 노드를 선택합니다. OnSearchNodeSuccess 이벤트에서 Connect To Room Server 함수를 호출합니다. 이 함수는 호스트 이름, 방 포트 번호, 프로토콜 필드, 채널 ID가 필요합니다. 앞에서 했듯이 두 콜백 이벤트를 추가합니다. 하나는 성공, 하나는 실패용입니다.

    ../../_images/gameinstance5.png

방 만들기와 입장하기

  • Strix는 마스터 두 서버 타입을 이용합니다. 마스터 서버는 최초 연결을 처리하고 방 서버는 실제 게임을 플레이하는 방 그룹을 처리합니다. 방에 입장하기 전에 먼저 방을 하나 만들어야 합니다. 이것은 간단한 샘플이므로 그냥 방에 연결해 보겠습니다. 방을 찾지 못하면 하나 만들겠습니다. 시작하기 전에 방 만들 시간을 벌기 위해 지연을 추가한 후 두 번째 플레이어의 인스턴스를 시작하겠습니다. 무작위 지연(이번 예에서는 5초 범위)을 추가한 후 JoinRandomRoom 함수를 호출합니다. 이 함수는 OnRoomServerConnectSuccess에서 나온 채널 ID 아웃풋과 Member Properties를 이용합니다. 연결한 후에는 JoinRandomRoom 함수로 두 호출을 만듭니다.

    ../../_images/gameinstance6.png
  • 성공하면 방에 연결됩니다. 그러나, 첫 클라이언트에는 방이 없으므로 하나 만들어야 합니다. 이를 위해 OnRoomJoinFailure 이벤트에서 Create Room 호출을 추가합니다. 이때 MemberRoom Properties뿐만 아니라, OnRoomServerConnectSuccess 이벤트에서 얻은 채널 ID도 필요합니다. 방 만들기에서 성공과 실패를 추가한 후 일부 정보를 출력하여 확인합니다. 방이 만들어지면 방에 자동으로 입장하므로 여기서 호출할 함수는 더 이상 없습니다.

    ../../_images/gameinstance7.png
  • 이로써 우리 게임의 기본 연결과 입장 기능이 완성되었습니다. 설정이 완료되어 클라이언트가 시작하면 무작위로 방에 연결을 시도하게 됩니다. 클라이언트가 방에 입장하지 못하면 첫 번째 방을 만듭니다. 이번 예는 적절하게 구현되기에는 부족한 점이 많습니다. 일례로 클라이언트 이름이 모두 같습니다. 연결 방법에 관하여 더 궁금한 점이 있으시면 연결방과 매치메이킹을 참조해 주십시오.

참고

GameInstance로 멀티플레이어 기능을 저장하는 것은 샘플과 같은 간단한 게임에만 어울립니다. 일반적으로는 이 로직을 다른 곳, 예컨대 UI 위젯 같은 곳에 넣습니다.

액터에 복제와 동기화 추가하기

  • 이 시점이 되면 Strix 서버에 연결하고 방을 만들어 입장할 수 있습니다. 그러나 게임 자체는 아직 네트워크에 연결된 상태가 아니며, 플레이어들 간의 상호작용도 이루어지지 않습니다. 3자 블루프린트 내용을 수정하여 Strix를 이용하면 이 문제를 해결할 수 있습니다.

  • 먼저 시작 맵을 엽니다. 플레이 버튼을 찾아 멀티플레이어 옵션으로 이동합니다. 여기서 플레이어의 수를 1에서 2로 설정합니다.

    ../../_images/multiplayeroptions.png
  • 이어서, 플레이어 수 설정 아래 고급 설정을 엽니다. 스크롤하여 멀티플레이어 옵션을 찾은 후 Auto Connect To Server의 체크를 해제합니다. Unreal 내장 멀티플레이어가 비활성화됩니다.

    ../../_images/multiplayeroptions2.png
  • 이제 게임을 시작하면 두 개의 창이 보입니다. 한 클라이언트는 첫 번째 방을 만드는 것이고 다른 하나는 기다렸다가 그 방에 입장하는 것입니다. 단 첫 번째 맵은 같을 수도 있지만 동기화나 복제는 아직 설정하지 않았으므로 플레이어 간 상호작용도 이루어지지 않습니다. 이것은 ThirdPersonCharacter 블루프린트를 수정하여 해결할 수 있습니다. 월드 안에서 3자 캐릭터를 클릭한 후 세부정보 패널에서 블루프린트 수정을 클릭하면 됩니다. 이 새 창의 구성요소 패널에서 구성요소 추가 버튼을 클릭하고 StrixReplicator를 검색하여 추가합니다. StrixMovementSynchronizer에 대해서도 마찬가지로 처리합니다.

    참고

    Strix 기능은 블루프린트에서만 작동합니다. 블루프린트가 연결되지 않은 액터와는 호환되지 않습니다. 항상 구성요소를 추가하고 액터의 블루프린트 안에서만 변경해야 합니다.

    ../../_images/character1.png
  • 다시 게임 월드로 돌아갑니다. 플레이를 누르고 각 플레이어로 실행합니다. 연결되면 각 플레이어가 같은 방 안에서 돌아다니는 모습이 보입니다. Strix로 기본 게임이 만들어졌다는 의미입니다.

    ../../_images/game1.png

RPC로 게임 기능 추가하기

  • Strix의 기능은 이것뿐만이 아닙니다. 일례로 RPC를 살펴보겠습니다.

  • RPC로는 다른 머신에서 함수를 호출할 수 있습니다. 복제된 플레이어에게 동기화되지 않는 어떤 동작을 하라고 주문하고 싶다면 이렇게 하면 됩니다. 실제로, Movement Synchronizer를 이용하여 점프하며 돌아다닐 때는 RPC를 보내 점프 동작을 하게 합니다.

  • RPC를 이용하기 위해서는 먼저 3자 캐릭터에서 호출할 함수를 정의해야 합니다. 우선 Third Person Character 블루프린트를 열어 내 블루프린트 패널을 찾습니다. 여기서 함수 오른쪽의 + 함수 버튼을 클릭하여 이 새 함수에 MyRPC라는 이름을 붙입니다.

    ../../_images/rpc1.png
  • 그별도 블루프린트로 함수가 열립니다. 이 함수를 이용하여 캐릭터의 컬러를 바꾸겠습니다. 그 전에 인풋을 추가합니다. Strix RPC로 인수를 전달하는 방법이 표시됩니다. 함수 패널에서 함수를 선택하거나 블루프린트에서 함수의 시작 노드를 선택하고, 이어서 세부정보 패널 아래 인풋 섹션에서 + 새 매개변수 버튼을 클릭합니다.

    ../../_images/rpc2.png
  • 새 매개변수가 하나 생깁니다. 여기에 Color라는 이름을 붙이고 타입은 Float라고 하겠습니다.

    ../../_images/rpc3.png
  • 우리 함수 노드에는 Color라고 하는 인수가 생겼습니다. 캐릭터의 컬러를 바꿀 때는 Create Dynamic Material Instance 노드를 추가하고 부모를 캐릭터의 몸 머티리얼(M_UE4_MAN_BODY)로 설정하면 됩니다. 이것의 리턴값을 Set Vector Parameter Value 노드에 부여합니다. 매개변수 이름은 BodyColor입니다. Make LinearColor 스트럭트를 추가하고 MyRPC 함수 노드에서 Make LinearColor 스트럭트에 있는 컬러 값 중 하나(이 경우 파란색)로 Color 인수를 전달합니다. 리턴값을 취하여 Set Vector Parameter Value 노드에서 Value 인풋에 연결합니다. Set Material 노드를 만듭니다. 이때 Target은 액터의 메쉬가 되고 머티리얼Create Dynamic Material Instance 노드의 리턴값이 됩니다. 아래 이미지에서 블루프린트를 확인합니다.

    ../../_images/rpc4.png
  • 이미 알고 있는 것일 수도 있습니다. 지금까지 한 일은 모두 함수 만들기입니다. 단, 우리 RPC로 이 함수를 이용할 수 있습니다. 먼저 RPC를 등록해야 합니다. 우선 구성요소 패널에서 Strix Replicator 요소를 선택합니다. 여기서 세부정보 패널을 보면 이벤트 목록이 보입니다. On Sync Begin 이벤트를 클릭하면 이것이 블루프린트에 추가됩니다. 이 이벤트는 액터가 동기화 준비를 마치면 Strix에 호출됩니다. 이어서, 이벤트 실행을 Register Strix RPC 함수에 연결합니다. 마지막으로, 대상을 self로 설정하고 함수 이름은 MyRPC로 설정합니다.

    ../../_images/rpc5.png
  • 이로써 RPC 함수가 등록되었습니다. 그러나 아직 호출은 필요합니다. 우리 캐릭터에는 이미 Jump 함수가 있습니다. 따라서 이 로직을 이용하겠습니다. (일단은 키프레스 로직을 이용하고 터치 인풋은 무시하겠습니다.) 이를 위해서는 Jump 노드의 실행 핀에서 드래그하여 MyRPC를 호출해야 합니다. 여기서 Color라는 부동 변수를 만들어 일정한 값으로 설정합니다. 파란색 최대값인 1로 하겠습니다.

    ../../_images/rpc6.png
  • 이제 점프를 하면 캐릭터의 컬러가 파랗게 변하는 것을 볼 수 있습니다. 단, 레플리카에서는 캐릭터가 업데이트되지 않습니다. RPC를 전체로 아직 보내지 않았기 때문입니다. 이를 위해서는 Jump 호출 후에 MyRPC 호출에서 Branch를 만들어야 합니다. 이어서, 구성요소 패널에서 Strix Replicator 요소를 드래그하여 해당 블루프린트에 놓고, 레퍼런스 아웃풋에서 Get Is Owner 노드를 추가합니다. Get Is Owner는 누가 로컬 인스턴스이고 누가 레플리카인지 알려줍니다. 이제 결과를 Branch Condition에 입력합니다. 조건이 참이면 RPC를 호출하고 거짓이면 우리가 레플리카이므로 중복 RPC를 보내지 않습니다. 사실, 이것은 RPC를 호출하기 위해 인풋 이벤트를 이용하고 있기 때문에 절대로 실패하지 않습니다. 즉, 방장 액터만 이 코드에 도달합니다. 방장과 레플리카를 구별하는 방법을 보여주는 것일 뿐입니다.

  • 브랜치 실행 핀에서 Send RPC to All 노드를 만듭니다. 이어서, TargetSelf로 설정하고 Function NameMyRPC로 설정합니다. Color에서 드래그하면 ToStrixRelayArg(float) 변환이 가능합니다. 이 아웃풋을 Send RPC to All에서 Args 인풋에 연결합니다.

    ../../_images/rpc7.png
  • 이제, 상대 플레이어의 창으로 점프하면 우리 플레이어가 파랗게 변합니다. 보시다시피 Strix RPC를 이용할 때 가장 복잡한 부분이 앞으로 이용할 실제 함수를 만드는 것입니다. 실제 RPC 호출은 빠르고 간편합니다. 사용자 편의를 위해 여러 타입의 호출과 인수를 마련해 두었습니다.

    ../../_images/rpc8.png

동기화된 속성 이용하기

  • Strix에는 동기화된 속성도 있습니다. 클라이언트 간에 여러 타입의 변수를 동기화할 수 있는 속성들입니다. MyRPC 함수를 다시 이용하여 이것을 보여줄 수 있습니다.

  • 먼저, MyColor라고 하는 부동 변수를 만들고, 세부정보 패널에서 복제Replicated로 설정합니다.

    ../../_images/synccolor.png
  • 이어서, Event Tick에서 컬러를 델타값으로 설정하고 캐릭터의 컬러를 업데이트합니다. Event Tick 노드에서 우리가 전처럼 방장인지 아닌지 확인해 보겠습니다. 아니라면 MyColor를 인풋으로 하여 MyRPC 함수를 호출하겠습니다. 이렇게 하면 그 레플리카의 실제 컬러가 업데이트됩니다. 우리가 방장이라면 MyColor가 1.0 이상인지 확인합니다. 1.0 이상인 경우 MyColor를 0으로 설정하고, 아닐 경우 델타의 값을 거기에 추가합니다. 즉, 컬러는 1초 사이에 최대값으로 늘어났다가 0으로 떨어지기를 반복한다는 뜻입니다. 이제 함수 호출을 다시 연결하여 로컬 플레이어의 컬러가 업데이트되게 합니다.

    ../../_images/colorsynccode.png
  • 게임 속 두 캐릭터의 컬러가 다 변하는 것을 볼 수 있습니다. 이 전환이 완벽하게 원활한 것은 아닙니다. Strix Replicator가 1/5초마다 복제를 하기 때문입니다. 이것은 Replicator의 세부정보 패널에서 바꿀 수 있습니다.

    ../../_images/syncexample.png

수고하셨습니다! 본 문서를 끝까지 읽어 숙련도를 높이시기 바랍니다. 새 샘플 프로젝트로 플레이해 보셔도 좋습니다.

Strix를 찾아주셔서 감사합니다.