유니티에서 하나의 프로젝트로 다양한 플랫폼에 실행할 수 있는 방법을 고안 및 정리해놓은 문서이다.
둘 이상의 플랫폼을 지원하는 것을 뜻한다.
최근들어 모바일 기기의 성능 향상, VR/AR의 등장, 멀티플레이 게임의 발전으로 인해 크로스플랫폼을 지원하는 게임이 증가하게 되었다.
이를 뒷받침하듯 각종 게임엔진에서도 PC, 모바일, 콘솔 등 여러 플랫폼에 빌드할 수 있게 지원을 해주고 있다.
PC, 모바일, VR 크로스플랫폼을 지원하는 애플리케이션을 만들게 되면서 크로스플랫폼을 구현하는 방법을 많이 조사해 보았다.
대체로 하나의 플랫폼당 하나의 프로젝트를 만들어 여러 개의 프로젝트를 관리하는 방법을 사용했다.
위의 방법은 앱의 최적화 및 관리에 강점을 보이지만, 인원과 시간이 많이 든다.
고로 개발자가 나 하나인 현재 프로젝트에서는 하나의 개발 프로젝트로 모든 플랫폼 앱을 빌드할 수 있게 구현함을 목표로 하였다.
앱의 최적화 및 관리는 각각 어드레서블과 에셋 컴프레션, 깃의 적극적 사용으로 일부 해결하였다.
모바일 기기와 PC기기간의 크로스 플랫폼을 수행할 때에는 두 기종간의 성능차가 구현에 큰 발목을 붙잡는다. 따라서 각 기종의 성능에 걸맞게 세팅을 수행해야 한다.
일반적으로 GPU 성능이 많이 낮은 모바일 기기의 특성상 텍스처 화질, 그림자 퀄리티 등 여러 그래픽적 요소에서 최적화를 수행해준다.
여러 플랫폼에 대한 각종 최적화 기법은 해당 문서에 모아두었다.
아래에는 원 빌드 멀티플레이 세팅에 사용되는 추가적인 최적화 방식을 작성하였다.
대체로 모바일 기기는 화면이 작으므로 텍스처의 사이즈를 줄여도 티가 잘 나지 않는다.
따라서 텍스처의 맥스 사이즈를 줄여 GPU의 부담을 줄여준다.
3D 오브젝트의 경우도 위의 텍스처와 같이 기기에 따라 다르게 임포트해야 한다.
이를 메모리 낭비 없이 생성해주는 것이 어드레서블 에셋이다.
원 프로젝트 멀티플랫폼을 구현하기 위해 작성한 코드들과 이에 대한 설명이다.
하나의 프로젝트에서 멀티플랫폼을 구현하기 위해 가장 필요한 작업은 해당 애플리케이션이 어떤 디바이스에서 작동되고 있는지를 파악하는 것이다.
유니티는 여러 인포 클래스를 통해 해당 정보들을 제공해준다.
이를 사용하기 쉽게 다음과 같이 스크립트로 작성할 수 있다.
namespace Utils.Platform
{
public static class CheckPlatform
{
public static bool IsVRPlatForm()
{
return XRSettings.enabled;
}
public static bool IsMobilePlatform()
{
return Application.isMobilePlatform;
}
public static bool IsPCPlatform()
{
if (Application.platform == RuntimePlatform.WindowsPlayer && !IsVRPlatForm())
{
return true;
}
return false;
}
}
}
플랫폼 구분을 하는 가장 큰 이유는 해당 플랫폼에 걸맞는 오브젝트/UI를 소환하기 위해서이다.
플랫폼의 변화에 따라 가장 큰 차이를 내는 것이 바로 플레이어이다. 기기에 따른 인풋 방식의 차이와 이에 따른 움직임 등을 따로 구현해야 하기 때문이다.
본인은 PC/모바일 플레이어와 VR 플레이어를 따로 구현하고, 설치한 플랫폼에 따라 적절한 플레이어 오브젝트를 소환하였다.
PC와 모바일 플레이어의 입력은 인풋 시스템을 이용해 처리하였다.
namespace Manager
{
public class PlayerSpawner : SimulationBehaviour, IPlayerJoined
{
public NetworkObject playerPrefab;
public NetworkObject vrPlayerPrefab;
/// <summary>
/// 플레이어가 플레이어와 같은 게임 오브젝트에 있으면 세션에 참여할 때마다 호출되는 함수
/// </summary>
/// <param name="player">서버가 해당 플레이어를 구분하는데 사용하는 값</param>
public void PlayerJoined(PlayerRef player)
{
if (player == Runner.LocalPlayer)
{
if (CheckPlatform.IsVRPlatForm())
{
Runner.Spawn(vrPlayerPrefab, new Vector3(0, 1, 0), Quaternion.identity, player);
}
else
{
Runner.Spawn(playerPrefab, new Vector3(0, 1, 0), Quaternion.identity, player);
}
}
}
}
}
CharacterController
컴포넌트를 이용해 구현하였고, VR 플레이어 캐릭터는 OpenXR의 XR Origin
을 이용해 구현하였다.기본적으로 유니티는 하나의 프로젝트에 하나의 애플리케이션을 빌드하기를 권장한다. 하지만 다음 방법을 이용해 하나의 프로젝트에서 여러 종류의 애플리케이션을 빌드할 수 있다.
Project Settings - Player - Product Name
을 변경한다.