이 문서에서는 Unity 웹 프로젝트를 최적화하는 방법에 대한 팁을 제공합니다.
이전에는 'WebGL'이라고 불렸던 Unity 웹 플랫폼 지원에는 더 많은 기기에서 마찰을 줄이고 최신 그래픽 API를 활용하여 가장 야심찬 웹 게임에서도 부드러운 프레임 속도와 뛰어난 성능을 보장하는 주요 개선 사항이 포함되어 있습니다.
여기에는 2D 및 3D 그래픽을 브라우저에 고속으로 렌더링하는 JavaScript API인 WebGL에 대한 지원이 포함됩니다. 구글 크롬, 모질라 파이어폭스, 사파리, 마이크로소프트 엣지는 모두 WebGL 2 콘텐츠를 지원합니다. WebGL 2는 OpenGL ES 3.0을 기반으로 합니다.
그래픽 API에 관계없이 웹사이트와 소셜 미디어에 효율적으로 배포하고 임베드할 수 있도록 Unity 웹 게임의 크기를 작게 만드는 것을 목표로 해야 합니다. 또한 다른 플랫폼을 대상으로 하는 경우에도 간편한 배포가 중요한 프로토타이핑과 게임 잼, 테스트에 웹 빌드를 사용할 수 있습니다.
웹 게임은 로컬 파일이나 하드웨어에 액세스할 수 없으며 일반적으로 네이티브 컴파일된 게임보다 성능이 약간 낮습니다.
참고: 새로운 API인 WebGPU는 Unity 6 베타(2023.3.0b1 베타)에서 얼리 액세스 버전으로 제공됩니다. WebGPU는 아직 개발 중이며 프로덕션 사용 사례에 사용하지 않는 것이 좋습니다.
WebGPU는 최신 GPU 기능을 웹에 활용하고 노출하는 것을 목표로 설계되었습니다. 이 새로운 웹 API는 다이렉트X12, 벌칸, 메탈과 같은 네이티브 GPU API를 통해 내부적으로 구현되는 최신 그래픽 가속 인터페이스를 제공합니다. 구체적인 네이티브 구현은 브라우저의 플랫폼과 사용 가능한 그래픽 드라이버에 따라 달라집니다. 시작하는 방법에 대한 자세한 내용과 추가 WebGPU 데모는 그래픽 포럼에서 확인할 수 있습니다.
Unity 웹 플랫폼에 배포하려면 먼저 Unity 에디터에 웹 모듈을 추가하여 웹 빌드를 생성해야 합니다. Unity 허브에서 설치 파일을 찾아 설정 아이콘을 클릭하고 모듈 추가를 선택합니다.
새 대화 상자에서 아래로 스크롤하여 웹 빌드 지원을 찾아 선택한 다음 완료를 클릭합니다.
프로젝트를 다시 열고 파일 > 빌드 설정에서 대상 플랫폼을 전환합니다. 게임을 개발하는 동안 개발 빌드 옵션을 사용합니다. 스택 추적, 자세한 오류 메시지, 로깅 정보와 같은 추가 디버깅 정보를 제공하여 문제를 해결하고 게임을 변경하는 데 도움이 됩니다. 게임 코드, 에셋 또는 설정을 조금만 변경한 다음 전체 빌드 프로세스 없이 브라우저에서 변경 사항을 빠르게 다시 빌드하고 테스트할 수 있습니다.
최종 게시된 빌드의 빌드 설정에서 개발 빌드 옵션을 선택 해제하세요.
빌드 및 실행을 선택하여 플레이 테스트를 위해 브라우저에서 실행되는 게임 버전을 생성합니다. 구글 크롬은 다양한 개발자 도구를 제공하기 때문에 플레이 테스트에 적합한 선택입니다.
빌드할 위치를 선택하라는 메시지가 표시됩니다. 빌드 파일에는 웹에서 문서의 구조와 콘텐츠를 구성하는 객체의 데이터 표현인 DOM(문서 객체 모델)에 HTML5 캔버스 요소를 추가하는 index.html 파일이 포함되어 있습니다. 게임이 이 캔버스에 렌더링됩니다. 빌드 파일에는 템플릿 데이터 폴더와 빌드 폴더도 포함됩니다. TemplateData 폴더에는 브라우저 주소 표시줄에 사용되는 파비콘과 페이지의 HTML 마크업에 사용되는 이미지 등 페이지에서 사용되는 HTML 자산이 포함되어 있습니다.
자동 빌드를 설정할 수도 있는데, Unity 빌드 자동화는 이를 위한 옵션 중 하나입니다.
웹 게임에는 기본 제공 렌더 파이프라인 또는 유니버설 렌더 파이프라인(URP)을 사용할 수 있습니다. 하지만 여러 하드웨어 장치에 콘텐츠를 효율적으로 사용자 지정하고 확장할 수 있는 URP를 권장합니다.
전자책을 통해 빌트인 렌더 파이프라인에서 URP로 프로젝트를 이동하는 방법에 대한 심층적인 지침을 확인하세요. 고급 Unity 크리에이터를 위한 유니버설 렌더 파이프라인 소개.
콘솔을 타겟팅할 때는 메모리와 CPU 및 GPU 사용량에 대한 정확한 사양이 필요합니다. 웹은 완전히 다른 존재입니다. 더 많은 사람들이 게임을 이용할 수 있도록 하려면 제한된 메모리 환경에서도 게임이 제대로 작동하는지 확인해야 합니다.
다음은 저사양 하드웨어에서 게임을 원활하게 실행하는 방법에 대한 몇 가지 팁으로, 전자책에서 발췌한 내용입니다. 모바일 게임 성능 최적화.
1. 게임 에셋 최적화
텍스처 및 모델과 같은 에셋을 웹용으로 최적화합니다(예: 압축 텍스처 사용, 모델에서 폴리곤 수 줄이기 등 해당되는 경우). 정해진 규칙은 없지만, 팀에서 몇 가지 일반적인 가이드라인에 합의하여 일관성 있는 성과를 보장하세요.
2. 개체 풀링 사용
오브젝트 풀링은 오브젝트를 새로 생성하고 파괴하는 대신 재사용하여 성능을 개선하는 데 도움이 되는 기술입니다. 이는 스폰과 디스폰이 많은 게임에 유용할 수 있습니다. 플라이휠과 같은 다른 프로그래밍 디자인 패턴도 도움이 될 수 있습니다. 전자책 보기 게임 프로그래밍 패턴으로 코드 수준 높이기에서 Unity 프로젝트에서 디자인 패턴을 구현하는 방법에 대한 고급 팁을 확인하세요.
3. 유니버설 렌더 파이프라인 및 SRP 배처 사용
씬에 따라 CPU 렌더링 속도를 높여주는 유니티의 SRP 배처 배 칭 시스템으로 성능을 개선하세요. 셰이더 및 텍스처와 같은 공유 머티리얼 속성을 기반으로 드로 콜을 함께 그룹화하여 렌더링 중에 필요한 상태 변경 횟수를 줄이는 방식으로 작동합니다.
4. 오클루전 컬링 사용
유니티의 오클루전 컬링 시스템은 플레이어에게 보이는 오브젝트만 렌더링하여 퍼포먼스를 개선할 수 있습니다. 오클루전 컬링은 복도로 연결된 방처럼 작고 잘 정의된 영역이 솔리드 게임 오브젝트로 서로 분리된 씬에서 가장 잘 작동합니다.
5. 기본 제공 LOD(레벨 오브 디테일) 시스템 사용
유니티의 내장 LOD 시스템은 플레이어에서 멀리 떨어져 있는 오브젝트의 복잡도를 줄여 성능을 향상시킵니다. 카메라와 오브젝트 사이의 거리가 멀어지면 LOD 시스템이 오브젝트의 디테일이 높은 버전을 디테일이 낮은 버전으로 자동 교체하여 렌더링 작업량을 줄이면서 일관된 외관을 유지합니다.
6. 가능한 경우 조명을 굽습니다.
라이트맵과 라이트 프로브를 사용하여 씬의 조명 정보를 미리 계산하여 성능을 개선하세요.
7. 불필요한 문자열 생성 또는 조작 감소
C#에서 문자열은 값 유형이 아닌 참조 유형입니다. JSON 및 XML과 같은 문자열 기반 데이터 파일은 구문 분석하지 말고 대신 스크립터블오브젝트나 MessagePack 또는 Protobuf와 같은 형식으로 데이터를 저장하세요. 영구 게임 데이터 저장(게임 저장)과 같은 경우에는 바이너리 형식을 고려할 수도 있습니다. 런타임에 문자열을 빌드해야 하는 경우 StringBuilder 클래스를 사용합니다.
8. 어드레서블 에셋 시스템(Addressable Asset System) 사용하기
어드레서블 에셋 시스템은 '주소' 또는 별칭으로 에셋 번들을 로드하여 콘텐츠를 관리하는 간소화된 방법을 제공합니다. 이 통합 시스템은 로컬 경로 또는 원격 콘텐츠 전송 네트워크(CDN)에서 비동기적으로 로드됩니다.
9. 후처리 효과 제한
전체 화면 포스트 프로세싱 효과는 성능을 저하시킬 수 있으므로 게임에서 아껴서 사용하세요.
Unity 웹 빌드를 생성할 때 Unity는 템플릿을 사용하여 게임을 표시할 웹 페이지를 생성합니다.
기본 템플릿은 다음과 같습니다:
- 기본적으로 회색 캔버스에 로딩 막대가 있는 흰색 페이지
- 최소: 게임 실행에 필요한 최소한의 상용구
- 프로그레시브 웹 앱(PWA): 여기에는 웹 매니페스트 파일과 서비스 워커가 포함됩니다. 적합한 데스크톱 브라우저에서는 주소 표시줄에 플레이어의 실행 가능한 애플리케이션에 게임을 추가할 수 있는 설치 버튼이 표시됩니다.
자신만의 커스텀 HTML 페이지를 만드는 가장 쉬운 방법은 <UnityInstallation>/PlaybackEngines/ WebGLSupport/ BuildTools/ WebGLTemplates/ 에서 찾을 수 있는 세 가지 템플릿 중 하나를 사용하여 시작하는 것입니다. Mac의 경우 응용 프로그램 폴더에서 Unity 설치 폴더를 찾을 수 있습니다.
템플릿을 복사하여 프로젝트/자산/웹GL템플릿 폴더에 저장하고 나중에 식별할 수 있도록 이름을 변경합니다. 이제 게임 콘텐츠, 배포 사이트, 대상 플랫폼에 맞게 커스터마이징할 수 있습니다.
프로젝트의 WebGLTemplates 폴더에 있는 템플릿은 편집 > 프로젝트 설정... > 플레이어 > 해상도 및 프레젠테이션 패널에 나타납니다. 템플릿의 이름은 해당 폴더와 동일합니다. 이 옵션에 쉽게 참조할 수 있는 썸네일 이미지를 제공하려면 템플릿 폴더에 128 x 128픽셀 이미지를 추가하고 이름을 thumbnail.png로 지정합니다.
빌드 프로세스 중에 Unity는 템플릿 파일을 전처리하고 해당 파일에 포함된 모든 매크로와 조건부 지시문을 평가합니다. 모든 매크로 선언을 찾아서 에디터가 제공하는 값으로 바꾸고 템플릿 폴더의 모든 .html, .php, .css, .js 및 .json 파일을 자동으로 사전 처리합니다.
예를 들어 다음 코드 줄을 살펴보세요:
<canvas id="unity-canvas" width={{{ WIDTH }}} height={{{ HEIGHT }}} tabindex="-1"></canvas>
해상도 및 프레젠테이션 패널에서 기본 캔버스 너비가960, 기본 캔버스 높이가 600으로 설정되어 있으면 전처리 후 코드는 다음과 같이 표시됩니다:
<canvas id="unity-canvas" width="960" height="600" tabindex="-1"></canvas>.
중괄호 세 개는 컴파일러가 지정된 변수의 값을 찾도록 지시합니다.
조건부 지시문의 기본 템플릿에서도 #if, #else 및 #endif를 사용하는 예제를 찾을 수 있습니다:
#if 표현식
//표현식이 진실한 값으로 평가되는 경우
#기타
//표현식이 진실한 값으로 평가되지 않는 경우
#endif
커스텀 템플릿을 사용하려는 경우 Unity 에셋 스토어에서 다양한 옵션을 제공합니다.
반응형 디자인에 맞게 브라우저 창 크기를 조정하려면 로딩 코드를 조정해야 하는 경우가 많습니다. 이를 위해 자바스크립트에서 아직 완료되지 않았지만 향후 완료될 것으로 예상되는 작업을 나타내는 "약속"을 사용할 수 있습니다.
각 템플릿의 index.html 페이지(아래 코드 예시 참조)에서 script.onload를 찾습니다. script.onload는 Unity 엔진 스크립트 로딩이 완료되면 트리거되는 이벤트입니다. 그 직전에 두 개의 글로벌 변수가 있는데, Unity 인스턴스에 대한 참조를 보유하는 myGameInstance와 게임 로드가 완료되었는지 여부를 나타내며 기본값은 false인 myGameLoaded가 있습니다. 변수로 선언되어 전역 범위를 가지며 스크립트 내 어디에서나 액세스할 수 있습니다.
Unity 게임의 새 인스턴스를 생성하기 위해 createUnityInstance() 함수가 호출됩니다. 이 함수는 게임이 완전히 로드되고 렌더링할 준비가 되면 확인되는 프로미스(createUnityInstance 프로미스의 다음 블록)를 반환합니다.
then() 내부에서 myGameInstance에 Unity 인스턴스가 할당되고 myGameLoaded가 true로 설정되어 게임이 준비되었음을 나타냅니다. 그런 다음 resizePage() 함수를 호출하여 게임 크기를 처음 설정하고 창 크기 조정 이벤트에 이벤트 리스너를 추가하여 창 크기가 조정될 때마다 게임 크기를 업데이트할 수 있도록 합니다. 아래 코드 스니펫을 참조하세요.
그런 다음 다음 코드 스니펫에 표시된 것처럼 스크립트 하단에 창 크기에 맞게 게임 크기를 조정하는 데 사용되는 resizePage 함수가 있습니다. 게임이 로드되면 게임을 표시하는 캔버스의 스타일 값을 창 크기와 일치하도록 설정하여 창을 채우도록 합니다:
function resizePage(){
if (myGameInstance !== 정의되지 않음 && myGameLoaded === true)
{
canvas.style.width = window.innerWidth + 'px';
canvas.style.height = window.innerHeight + 'px';
}
}
브라우저를 대상으로 하는 많은 게임은 사용자 로그인, 최고 점수 표 등을 지원하거나 브라우저 DOM과 상호 작용하기 위해 웹 서비스를 호출할 수 있도록 자바스크립트 코드와 상호 작용해야 합니다. C# 스크립트에서 호출할 수 있도록 직접 추가하는 모든 JavaScript는 확장자가 .jslib여야 하며 Assets/Plugins 폴더에 배치해야 합니다. mergeInto 메서드로 래핑해야 합니다. 이를 위해서는 두 가지 매개 변수가 필요합니다: LibraryManager.library를 생성한 다음 하나 이상의 함수가 포함된 JavaScript 객체를 생성합니다. 함수는 표준 자바스크립트입니다. 아래는 간단한 JSON 전달 웹 서비스를 사용하는 방법을 보여주는 GetExchangeRates입니다.
빌드를 생성하면 빌드/<게임 이름>.framework.js 파일에 이러한 함수가 추가됩니다. 이 코드 예시와 같이 함수를 DllImport로 선언하여 C# 스크립트에서 이러한 함수를 호출할 수 있습니다:
공용 클래스 SphereController : 모노비헤이비어
{
[DllImport("__Internal")]
private static extern void GetExchangeRates();
private void Start()
{
GetExchangeRates();
}
}
추가 정보
C#이 자바스크립트 함수를 호출하는 것 외에도 자바스크립트는 C# 메서드를 호출할 수 있습니다. 관련 메커니즘은 메시징 프로토콜을 사용합니다:
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, 5)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, ‘A string’)
SendMessage를 사용하려면 범위 내 게임 인스턴스에 대한 참조가 필요합니다. 일반적인 방법은 앞서 살펴본 것처럼 전역 변수를 추가하고 이를 스크립트.onload 프로미스의 다음 블록에 할당하여 index.html을 편집하는 것입니다. 이 간단한 함수는 Sphere라는 게임 오브젝트에 연결된 모노비헤이비어 컴포넌트의 일부로 추가됩니다.
public void SetHeight( float height )
{
Vector3 pos = transform.position;
pos.y = height;
transform.position = pos;
}
F12를 사용하여 Chrome의 콘솔을 열고 직접 입력할 수 있습니다:
myGameInstance.SendMessage('Sphere', 'SetHeight', 3)
Enter 키를 눌러 구 이동 함수를 호출합니다. 백그라운드에서 실행을 설정했거나 Application.runInBackground를 true로 설정한 경우에만 움직임이 렌더링에 반영됩니다. 기본적으로 렌더링은 캔버스 창에 포커스가 있을 때만 발생하기 때문입니다.
브라우저 플랫폼에서 디버깅할 때는 Debug.Log를 사용하세요. 모든 메시지는 브라우저 콘솔로 전송됩니다. Chrome의 경우 F12를 누르고 콘솔 탭으로 전환하면 이 기능을 찾을 수 있습니다. 하지만 디버그 클래스는 더 많은 옵션을 제공합니다. Debug.LogError를 사용하면 콘솔에서 스택 추적이 제공되므로 도움이 될 수 있습니다.
추가 정보
개발 중에는 개발 빌드 옵션을 사용하는 것이 좋지만, 게임을 라이브 사이트에 배포할 때는 이 옵션을 선택 취소하는 것이 좋습니다. 릴리스 빌드의 경우 압축 옵션이 있습니다. 압축을 사용할 때 서버에서 설정을 조정해야 할 수 있으며, 이 방법에 대한 팁은 매뉴얼을 참조하세요.
개발 주기 전반에 걸쳐 프로젝트를 프로파일링하여 성능 문제를 제때 파악하는 것이 중요합니다. Unity 프로파일러는 게임의 성능 병목 현상을 파악하고 수정하는 데 유용한 툴입니다. CPU와 메모리 사용량을 추적하여 게임에서 최적화가 필요한 부분을 파악할 수 있도록 도와줍니다. 프로필 분석기, 메모리 프로파일러, 웹 진단 오버레이를 함께 사용할 수도 있습니다.
전자책 다운로드 Unity 게임 프로파일링에 대한 궁극의 가이드 를 다운로드하여 Unity의 프로파일링에 대해 자세히 알아보세요.
Unity 웹 빌드 프로파일링을 시작하기 위한 몇 가지 팁을 살펴보겠습니다.
Unity 프로파일러 활성화
에디터에서 파일 > 빌드 설정으로 이동하여 개발 빌드 및 자동 연결 프로파일러를 선택하여 웹 빌드와 함께 프로파일러를 사용합니다.
CPU 사용량 모듈을 선택합니다.
이 모듈을 사용하여 코드의 성능을 분석하고 성능 문제를 일으키는 영역을 식별하세요. 함수 호출, 스크립트 실행, 가비지 수집과 같은 요소를 분석합니다.
메모리 프로파일러 모듈 선택
Unity 웹 빌드는 다른 플랫폼에 비해 메모리 리소스가 제한되어 있습니다. 이 모듈을 사용하여 애플리케이션의 메모리 사용량을 분석하고 최적화할 영역을 식별하세요.
Chrome 개발자도구 성능 패널 사용
Chrome 개발자 도구에는 게임의 병목 현상을 자세히 살펴볼 수 있는 성능 패널이 포함되어 있습니다. 여러 기능 중에서도 자바스크립트 파일에 중단점을 추가할 수 있는 소스 패널과 디버그 메시지를 보고 자바스크립트 코드를 입력할 수 있는 콘솔 패널을 제공합니다.
다양한 디바이스에서 성능 측정
이렇게 하면 특정 기기나 브라우저에 특정한 성능 문제를 파악하고 그에 따라 게임을 최적화하는 데 도움이 됩니다.
추첨 요청 횟수 줄이기
드로우 콜은 Unity 웹 빌드의 주요 성능 병목 현상 중 하나입니다. Unity 프로파일러를 사용하여 드로 콜 수가 많은 영역을 식별하고 이를 줄여 보세요.
저사양 디바이스에서 성능 분석
저사양 기기에서 테스트하여 애플리케이션이 다양한 하드웨어에 최적화되었는지 확인하세요.
프로파일링 중 '백그라운드에서 실행' 활성화
WebGL 플레이어 설정에서 백그라운드에서 실행을 활성화하거나 Application.runInBackground를 활성화하면 캔버스 또는 브라우저 창이 포커스를 잃어도 콘텐츠가 계속 실행되므로 프로파일링 시 유용할 수 있습니다.
Unity 웹 빌드는 게임을 많은 사용자에게 배포할 수 있는 좋은 방법입니다. 개발 중에는 지오메트리와 텍스처를 적당한 크기로 유지하고, 드로 콜을 줄이며, 다양한 디바이스에서 프로파일링 및 테스트하는 것을 목표로 삼아야 합니다. 마지막으로 URP를 사용하여 가장 광범위한 하드웨어에서 견고한 성능을 보장하세요.
추가 정보
Unity 2023.3의 새로운 WebGPU 백엔드 얼리 액세스
공식 웹 런타임 업데이트는 여기에서 확인할 수 있습니다: 브라우저를 한 단계 업그레이드하세요
유니티의 모든 고급 전자책과 문서는 유니티 베스트 프랙티스 허브에서 확인할 수 있습니다.