언리얼 서밋 2017에서는 학생들도 충분히 들을 수 있는 강연들이 많았다. 실무가 익숙한 사람들 뿐만 아니라 개발자를 꿈꾸는 젊은이들도 대학 수업 듣듯 실무자의 생생한 이야기를 들어볼 수 있었다.

그 중 ‘모바일 MOBA 제작하기 1,2’에서는 에픽게임즈 코리아의 신효종 개발자가 언리얼 엔진의 비주얼 스크립팅 시스템인 블루프린트(Blueprint)를 중점으로 모바일 MOBA 샘플을 통해 기초부터 중요한 팁에 대하여 설명했다.

▲ 에픽게임즈 코리아의 신효종 개발자

다수의 플레이어가 동시에 접속해 상호 작용하면서 전개되는 모바일 MOBA 게임에서 가장 중요한 점은 네트워크 기능이다. MOBA 게임의 네트워크 시스템은 블루프린트로 심플하게 조정이 가능하다. 블루프린트는 온라인 MMO의 방대한 양을 처리하기에는 어렵지만 간단한 3-4인이나 8인 협력 플레이를 구성하는 데에는 적합하다.

신효종 개발자는 먼저 엔진 자체에 익숙하지 않을 청강자들을 배려해 기초 설명을 먼저 하고 MOBA 샘플을 통해 개발 툴과 팁을 소개했다.


■ 블루프린트의 용어와 기초


블루프린트의 서버플랫폼은 중앙 서버와 각각의 클라이언트가 여러 대 있는 방식이다. 서버에서 클라이언트로, 클라이언트에서 서버로 각각 통신을 보내는 식으로 네트워크가 이루어진다.

서버의 경우 중요한 노드들을 처리한다. 데미지를 입히거나 본진을 파괴하는 등 중요한 데이터는 각각의 클라이언트에서 처리하게 되면 해킹에 취약해지기 때문에 서버에서만 처리하는 게 옳다. 내 화면에서만 보이면 되는 이펙트 애니메이션이나 UI 등은 다른 클라이언트와는 상관이 없고 중요하지 않기 때문에 각각의 클라이언트에서 처리한다. 서버와 클라이언트 둘 다 처리하는 멀티캐스트도 있다. 한 클라이언트에서 애니메이션을 처리하던 도중 충돌이 일어난 경우와 같이 서버에서 애니메이션을 처리해야 할 필요가 생길 때 이용한다. 이때 클라이언트에서 이펙트가 안 보일 수 있기 때문에 둘 다 실행해준다. 서버에서는 충돌처리를, 클라이언트에서는 애니메이션을 처리하는 식이다.

▲ 서버와 클라이언트는 블루프린트 내에서 아이콘들로 보기 쉽게 표시되어있다

예를 들어, 내 캐릭터의 hp가 줄어들면 함께 플레이하고 있는 다른 플레이어들도 그 사실이 보여야 하기 때문에 우선 서버로 내 캐릭터의 hp가 줄어들었다는 데이터를 서버에 보낸다. 그 후 서버에서는 그 사실이 합당한지 확인하고 결과를 다른 클라이언트에게 보낸다. 이 통신을 리플리케이션이라고 한다.



서버에는 리슨 서버와 데디 서버가 있다. 리슨 서버의 경우 멀티플레이 옵션을 조정하면 싱글플레이와 멀티플레이를 변환할 수 있다. 기본으로 1로 되어있으면 싱글플레이, 그 이상으로 조정하면 멀티플레이로 설정할 수 있다. 별다른 네트워크 처리를 하지 않아도 숫자만 올림으로써 간단히 변환할 수 있다.

데디 서버, 데디케이트 서버의 경우 리슨 서버와 큰 차이는 없다. 테스트하고 싶으면 run 버튼을 누르면 가능하다.


실행은 실행 파일을 따로 해서 할 수 있다. 서버의 경우 바로가기 안에 프로젝트 이름, 넷이름, 리슨이라고 적고, 게임만 실행할 예정이라면 -game을 덧붙이면 된다. 클라이언트의 경우 아이피만 적어주면 서버에 접속할 수 있다.

▲ 함수의 경우 바로 리플리케이션 할 수 없고 커스텀이벤트를 생성해야 한다.


신뢰성의 경우 체크를 하게 되면 데이터가 반드시 클라이언트에 전달된다. 이 부분은 한번 적용하고 끝나는 것이 아니라 계속 적용을 해줘야 하기 때문에 모든 것을 다 처리할 필요는 없다. 예를 들어 '파티클을 날려라'라는 명령이 있을 때 꼭 보여주지 않더라도 주요 데이터에 영향이 없기 때문에 신뢰성을 빼주는 경우가 있다. 하지만 중요한 데이터는 신뢰성을 반드시 체크해줘야 한다.

▲ 유투브에 강연들이 잘 정리되어있다



■ 모바일 MOBA 샘플 살펴보기

신효종 개발자는 기본 개념에 이어 MOBA 샘플을 통해 개발 팁을 자세히 짚어주었다. 모바일 MOBA샘플은 1년전 액션RPG 소울던전 개발 당시 장르가 다변화하고 여러 MMO장르가 활성화되면서 모바일의 경우 MOBA장르가 주요해질 것으로 생각하여 만들어진 샘플이다. 친구들이 모여서 함께 게임을 즐기는 모습을 상상하며 만들어졌다고 한다.

▲ 클라이언트 화면: 개발자라 이게 최선의 디자인이었다며, 디자이너가 없으면 역시 힘들다고 한다

콘솔커맨드를 이용해 두 개의 에디터를 실행하면 아이피를 입력하며 접속할 수 있다. 게임 세션의 경우 온라인세션 노드를 이용하면 간편하다. PC의 경우 간단하게 Steam을 이용하여 접속할 수 있지만, 모바일의 경우 지원하지 않기 때문에 아이피를 이용해서 PC간 접속을 해야한다.

캐릭터 선택화면의 경우 IP를 보여줄 필요가 있다. 함수를 쓰면 IP을 얻어올 수 있지만, 블루프린트에서는 지원되지 않으므로 코딩할 필요가 있다.


Team결정의 경우는 들어오는 순서대로 해놨으며, 밸런스를 고려한 샘플이 아니기 때문에 2대1 대전도 가능하다. 클라이언트가 접속하면 OnPostLogin창에서 확인할 수 있다. 플레이어 컨트롤러로 배열을 매번 ADD 해줄 수도 있다. 이때 따로 ADD를 해두면 나중에 모든 캐릭터나 특정 팀에만 업데이트를 할 때 반영을 쉽게 할 수 있다.


혹은 플레이어 어레이의 배열개수를 이용하는 방법도 있다. 플레이어 어레이는 게임 스테이트에서 접근이 가능하며 배열하면 된다. 많은 배열 중에서 나의 캐릭터 스테이트를 선별하기 힘들 때, 본인 플레이어 컨트롤러를 통해 직접 접근해서 편하게 할 수 있다. 이 MyPlayerState를 이용하면 특정 플레이어에게는 다양한 스테이트가 더 필요하겠다 싶을 때 선별해서 추가 가능하다.

캐릭터 고르기의 경우 캐릭터를 골랐을 때 서버로 get owning player 노드를 이용하면 플레이어 컨트롤러에 접근이 가능해진다. 캐릭터 설렉트 서버에서 실행하는 식으로 바꿔준다.


게임을 할 때 또 한 가지 중요한 요소인 세이브도 제공되어 있다. 나만의 세이브 게임을 만들 수 있다. 이때 로컬에 저장할 때 주의해야 하는 점이 있다. 한 PC에서 슬롯 네임을 똑같이 해버리면 정보가 덮어진다. 주로 테스트는 한 PC에서 둘 이상의 클라이언트를 테스트하게 되는데 1P와 2P의 슬롯네임을 같이 해버리면 하나가 사라지므로 서로 다른 이름을 가지도록 변동해주어야 한다.


게임 스타트는 스무스하게 시작되도록 서버에서 관리한다. 앞서 추가한 플레이어 스테이트를 각 진영에 배치하고 태그에 Team1, Team2등을 넣어둔다.

캐릭터 이동에 대하여 탑다운테스트 템플릿이 있다. 여기서 문제인 것이 1P가 움직이는데 2P가 안 움직이는 문제가 생긴다는 것이다. 노드자체가 리플리케이션을 위한 게 아니기 때문이다. 따라서 한 가지 방법으로 AI컨트롤러를 이용하는 방법이 있다. 일반적으로 캐릭터(hero)를 컨트롤러하고 1대1 대응을 시키면 조절이 안 된다. 여기에 hero proxy를 넣어 한 단계를 거쳐서 대응을 시켜야 조절할 수 있다. Hero controller에 hero proxy를 대응시켜 hero character에 대응되어 있는 AI Controller for Player에 연결한다. 다소 복잡해 보인다는 단점이있지만, 캐릭터가 리스폰되는 동안 무언가를 처리하기에 편리하다는 장점이 있다.

▲ 블루프린트에 없는 기능들은 C++로 추가해주어야 한다



■ 게임 속 애니메이션


1부에 이어 2부에서는 애니메이션 기본 개념에 대한 강연이 이어졌다.

먼저 기본적으로 캐릭터의 뼈대가 되는 스켈레톤이 있다. 몸체를 형성하고 있는 스켈레톤을 움직이도록 설정하면서 캐릭터 움직임이 구현된다. 특정 행동의 시작과 끝이 존재할 때 구간이벤트로써 움직임을 설정한다. 스타트 노티파이와 엔드 노티파이를 설정하는 식이다. 특정 타이밍에 이루어져야 하는 단발성 이벤트에 적합한 방식이다. 하지만 공격을 하다가 적에게 맞을 경우처럼 스타트 노티파이에는 문제가 없지만 엔드 노티파이가 앞당겨 나와서 중간에 애니메이션이 끊기고 바로 맞는 애니메이션으로 변환되어야 하는 상황에 특정한 설정을 해주어야한다.

애님 노티파이 스테이트를 설정하면 중간에 애니메이션이 전환되더라도 엔드 노티파이가 자동으로 호출되어 전환이 용이하다. 애님 노티파이는 게임 플레이에 맞춰서 퍼포먼스에 따라 달라진다. 하지만 60프레임으로 만들었어도 게임이 무거워져서 프레임이 몇 안 나올 때 시간이 지나간 후에 한 번에 호출되어 브랜치 포인트로 타이밍을 맞춰줄 필요가 있다. 다만 코스트가 높아지기 때문에 중요한 장면에만 쓰는 게 좋다.


애님 몽타주를 사용하면 애니메이션이 점프되면서 빠르게 처리된다. 애님 몽타주는 있는 동작들을 가지고 짜깁기하는 것으로써, 여러 애니메이션을 넣어놓고 연속 콤보같은 빠른 트랜지션에 적합하다.

애니메이션 블루프린트는 애니메이션 전용 블루프린트다. 일반적으로 상체와 하체가 분리되어 설정된다. 애님 그래프와 이벤트 그래프가 적용되며 이벤트 그래프의 경우 일반 블루프린트와 비슷하지만, 애니메이션 블루프린트에만 사용할 수 있는 기능들이 포함되어있다. 캐릭터가 움직일 때 패드를 밀면 스피드는 이벤트 블루프린트에서 업데이트 시킨 다음에 애니메이션 블루프린트에서 애니메이션을 적용하게 된다.


각각의 움직임 노드들은 하나의 스테이트가 된다. 하나의 스테이트(움직임)에서 다른 스테이트로 전환되는 것에는 트랜지션 조건들을 설정하게 된다. 예를 들어 속도가 10보다 커지면 걷는 애니메이션에서 뛰는 애니메이션으로 전환되도록 조건을 걸어두는 것이다. 스테이트를 각각 연결해서 트랜지션 조건을 더블클릭하면 조건을 정할 수 있다.

MOBA 샘플 캐릭터의 안쪽에 대부분의 함수가 적용되어있으며 스테이트 머신은 적용되지 않았다. 캐릭터마다 스켈레톤이 각기 다르기 때문에 애님 블루프린트를 공유할 수 없어서 각기 설정하기가 번거롭기 때문이다. 다만 대부분의 미니언은 때리고 죽고 하는 같은 일을 하므로 공격 시에는 공격 몽타주, 죽을 때에는 죽는 몽타주 등 몽타주만 바꿔서 적용하면 애니메이션을 간단하게 달라지도록 할 수 있기 때문에 애님 몽타주를 대신 이용한다.


애님 몽타주를 이용할시 각자 몽타주의 재생 길이가 달라 재생시간을 알아둘 필요가 있다. 시간을 모르더라도 애님 노티파이를 이용해 애니메이션이 끝날 때 이벤트를 발생시키는 방식이 가능하지만 노티파이 삽입을 잊으면 디버깅에 문제가 생길 수 있다. 몽타주 플레이시 애니메이션이 적용이 안 된다면 슬롯의 문제이니 확인해줄 필요가 있다.


충돌처리에는 크게 Hit와 Overlap이 있다. Hit의 경우는 물리적으로 부딪혔을 때, Overlap은 캐릭터가 서로 겹쳐졌을 때 이용된다. Hit의 경우 적에게 공격을 가할 때 범위를 나타내며 적용되며, Overlap은 아군은 맞지 않고 뚫고 지나가도록 설정할 때 사용된다.


데미지 처리는 서버에서 처리해야 할 중요한 요소이다. 데미지 관련 시스템은 따로 준비되어있으며, 이벤트를 따로 처리해서 클라이언트에 전달하는 방식이다. 플레이 결과 같은 경우도 코어가 파괴되면 서버에서 확인한 후 각각의 클라이언트에 이벤트를 알린다. 리스폰의 경우 시간 카운트를 원래 서버에서 처리했지만, 숫자 카운트가 뚝뚝 끊기는 현상이 생겨 클라이언트와 서버가 각각 시간 계산하고 서버에서 체크 후 리스폰 시키는 방식으로 바뀌었다.



신효종 개발자는 마지막 팁으로 폴더와 파일명이 너무 길면 쿠킹에 실패할 수 있으므로 주의하기를 덧붙였다.