# Unity - 시작하기

실습을 통해 배우고 Edgegap에서 첫 전용 서버를 배포해 보세요. 이 가이드가 끝날 때쯤이면 비용 없이 Edgegap으로 전용 서버를 배포하게 됩니다.

{% embed url="<https://youtu.be/4FR04V4YEUk>" %}

## ✔️ 준비

<details>

<summary><a href="https://github.com/edgegap/edgegap-unity-plugin">Edgegap의 Unity 전용 서버 퀵스타트 플러그인 설치</a></summary>

</details>

{% hint style="info" %}
**서버 빌드에 자신이 있으신가요?** 다음으로 건너뛰기 [#customize-server-image](#customize-server-image "mention") 또는 [고급 기능](/docs.edgegap.com-ko/learn/advanced-features.md) 를 참조하세요.
{% endhint %}

## ⚙️ 1. 계정 연결

☑️ 로그인한 뒤 Unity 콘솔에 Edgegap 플러그인과 관련된 새 오류가 없는지 확인하세요.

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

`!성공: 400 BAD REQUEST - POST | https://api.edgegap.com/v1/wizard/init-quick-start - {"message": "브라우저(또는 프록시)가 이 서버가 이해할 수 없는 요청을 보냈습니다."}`

* ZIP 파일을 복사해서 설치했거나, 이 방식으로 플러그인이 설치된 샘플 프로젝트를 사용했다면 Newtonsoft JSON 라이브러리를 포함한 패키지 종속성을 수동으로 설치해야 합니다. 다음을 참조하세요. [공식 플러그인 저장소](https://github.com/edgegap/edgegap-unity-plugin/tree/main?tab=readme-ov-file#instructions-1).
* 도움이 필요하면 다음에서 저희에게 연락해 주세요 [커뮤니티 디스코드](https://discord.gg/NgCnkHbsGp) 해당되지 않는 경우에 한합니다.

</details>

## 🔧 2. 게임 서버 빌드

Windows, Mac, Linux 중 어떤 머신을 사용하든, **Linux 런타임용으로 서버를 빌드해야 합니다**대부분의 클라우드 제공업체(Edgegap 포함)가 현재 Linux에서 실행되기 때문입니다. 걱정하지 마세요. 저희 플러그인을 사용하면 이를 수행하는 데 Linux 지식이 필요하지 않습니다.

☑️ **필요한 Unity Linux 빌드 도구가 설치되어 있는지 확인하세요.**

☑️ Build Settings를 편집하여 **필수 게임 씬이 모두 포함되었는지 확인하세요**.

{% hint style="info" %}
**고급 Unity 사용자** - 선택적으로 변경 [Unity Build Settings](https://docs.unity3d.com/Manual/BuildSettings.html). 주의! 이로 인해 빌드가 깨질 수 있습니다.
{% endhint %}

☑️ 선택 사항: Edgegap Server Hosting 메뉴에서 초기 서버 씬에 포트 검증 및 환경 부트스트래핑용 netcode 전용 스크립트를 추가하세요(오른쪽 클릭 / :heavy\_plus\_sign: Hierarchy 창에서).

<figure><img src="/files/a812b5091aed52ccbd9d67e09f6fd9c885f11627" alt="" width="360"><figcaption></figcaption></figure>

{% hint style="info" %}
단계 [#id-6.-deploy-to-cloud](#id-6.-deploy-to-cloud "mention")를 완료하면, 포트 검증 스크립트가 netcode 주소 또는 포트가 Edgegap의 [App Version Port Mapping](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#other-parameters-optional) 설정과 일치하지 않을 때 경고를 로그에 남깁니다.
{% endhint %}

{% hint style="success" %}
서버 빌드는 netcode transport에서 주소 `0.0.0.0`  및 포트 `7777`  를 사용해야 합니다. 포트를 사용자 지정한 경우, [앱 및 버전](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#port-mapping) 에서 동일하게 지정해 주세요. [#id-5.-upload-to-edgegap](#id-5.-upload-to-edgegap "mention").
{% endhint %}

☑️ 구성이 만족스러우면 **서버 빌드**를 완료한 뒤 프로세스가 끝날 때까지 기다리고 Unity 콘솔에 새 오류가 없는지 확인하세요. 이 단계를 완료하면 **프로젝트 루트에 새 폴더가 표시됩니다** - `Builds/EdgegapServer/ServerBuild` .

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

Unity: 지원되는 독립 실행형 대상은 OpenXR이 있는 Windows x64와 OSX뿐입니다.

* 서버를 빌드하기 전에 Packages를 열고 OpenXR을 비활성화하세요.
* OpenXR 플러그인은 클라이언트에만 필요하며 Linux 서버 빌드와 호환되지 않습니다. 서버 빌드에서 제외해도 기능은 손실되지 않습니다.

</details>

## 🐋 3. 서버 컨테이너화

개발자 팀에서 일한다는 것은 코드를 공유한다는 뜻입니다. 문제가 생겼을 때 가장 듣기 싫은 말은 “내 컴퓨터에서는 되는데”일 것입니다. 게임 서버는 성공적인 게임의 서버가 전 세계 수천 대의 서버 머신에서 실행되므로 어떤 머신에서든 안정적으로 동작해야 합니다.

서버를 안정적으로 만들기 위해 Docker를 사용합니다. Docker는 서버가 어디서 어떻게 실행되든 운영체제 수준까지의 모든 서버 코드 종속성이 항상 정확히 동일하도록 보장하는 가상화 소프트웨어입니다.

☑️ 우선은 다음을 눌러 시작하세요 **검증** 버튼을 눌러 완료했는지 확인하세요 [개발자 도구](/docs.edgegap.com-ko/unity/developer-tools.md#usage-requirements).

☑️ 다음 옵션을 구성할 수 있습니다(또는 기본값 유지):

* **빌드 경로** 는 서버 빌드 아티팩트의 상대 경로입니다. 일단 기본값을 유지합시다.

{% hint style="warning" %}
**빌드는 프로젝트 폴더 내부에 두세요**, Docker는 프로젝트 루트에 대한 상대 빌드 경로만 허용합니다.
{% endhint %}

* **이미지 이름** 은 선택한 고유 식별자로, 배포 전에 서버 빌드를 표시합니다.
  * 보통 게임 이름이 포함됩니다. 예: “my-game-server”.
* **이미지 태그** 는 이미지의 특정 버전을 가리키는 식별자입니다.
  * “빌드 아티팩트”라는 용어는 특정 버전의 이미지를 지칭하는 데 때때로 사용됩니다.
  * 타임스탬프는 태그로 사용하기에 좋은 옵션입니다. 예: `2024.01.30-16.23.00-UTC` .
* **Dockerfile 경로** 는 이미지 레시피를 사용자 지정하는 데 사용할 수 있습니다.
  * 일단 기본 설정을 유지하는 것을 권장합니다. 자세한 내용은 나중에 섹션에서 읽을 수 있습니다 [#customize-server-image](#customize-server-image "mention").
* **선택적 docker 빌드 매개변수** 는 Docker에 더 세부적인 내용을 추가로 지시하는 데 사용할 수 있습니다.
  * 일단 기본 설정을 유지하는 것을 권장합니다. [나중에 Docker 문서에서 더 읽어보실 수 있습니다](https://docs.docker.com/reference/cli/docker/image/build/#options).

☑️ 구성이 만족스러우면 **Docker로 컨테이너화**를 완료한 뒤 프로세스가 끝날 때까지 기다리고 Unity 콘솔에 새 오류가 없는지 확인하세요. 이 단계를 완료하면 **로컬 머신에 새 이미지가 표시됩니다**. 이는 Docker Desktop의 Local(기본값) 아래 Images 탭이나 docker CLI에서 다음을 실행하여 확인할 수 있습니다 `docker images` .

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

`/bin/bash: docker: command not found` , 또는 `Packages\com.edgegap.unity-servers-plugin\Editor를 찾을 수 없습니다`

* 먼저, 다음을 완료했는지 확인하세요 [개발자 도구](/docs.edgegap.com-ko/unity/developer-tools.md#usage-requirements).
* Edgegap 계정 인증을 완료했는지 확인하세요. 이메일로 인증 링크를 받았어야 합니다.
* Docker Desktop을 업데이트한 후 일부 설정이 초기화되었을 수 있습니다. Docker Desktop 설정 / 고급으로 이동하여 “Docker CLI 도구 설치 구성을 선택하는 방법:”에서 “시스템(비밀번호 필요)”을 선택해 보세요.

***

`docker build에는 인수가 정확히 1개 필요합니다`

* 이미지 태그에 공백 문자(스페이스, 탭)가 포함되지 않았는지 확인하세요. 이미지 태그 값을 다시 입력하면 실수로 그런 문자를 복사하지 않았는지 확인할 수 있습니다.

***

`(HTTP 코드 400) 예상치 못함 - 잘못된 태그 형식`

* 이것은 [macOS Docker 버전 4.33의 알려진 문제입니다](https://github.com/docker/for-win/issues/14258), 4.32로 되돌리거나 4.35로 업그레이드하는 것을 고려해 주세요.

***

`ERROR: failed to solve: ubuntu:22.04: failed to resolve source metadata for http://docker.io/library/ubuntu:22.04: failed to authorize: failed to fetch oauth token`

* 중국에 계신가요? Great Firewall 때문에 연결이 끊길 수 있습니다. 다음을 수동으로 실행해 보세요 `docker pull ubuntu:22.04` 명령줄에서(Win+R을 눌러 명령줄을 연 다음 `cmd` 를 입력하고 Enter).

***

`System.IndexOutOfRangeException: Index가 배열 경계를 벗어났습니다.`

* ZIP을 다운로드하여 Unity 퀵스타트 플러그인을 설치했다면 Unity Editor 캐시가 손상되었을 수 있습니다. 플러그인 복사본을 삭제한 뒤 git URL 또는 Unity Asset Store를 통해 설치해 보세요. 이제 Newtonsoft.JSON 패키지는 다른 소스와 함께 자동으로 포함되므로 더 이상 필요하지 않습니다.

***

Docker 이미지 크기가 엄청나게 큽니다(1GB 초과) / 너무 작습니다(100MB 미만). 괜찮은가요?

* 서버를 실행하고 성공적으로 연결할 수만 있다면 일부 경우에는 괜찮을 수 있습니다(다음을 참조). [#id-4.-test-your-server-locally](#id-4.-test-your-server-locally "mention")). 그렇지 않다면 빌드 옵션을 검토하고 기본값으로 재설정한 뒤, 옵션을 하나씩 추가해 빌드 크기에 어떤 영향을 미치는지 확인해 보세요. 또한 다음도 참조하세요 [#optimize-server-build-size](#optimize-server-build-size "mention").

***

문서 어디에도 언급되지 않은 다른 문제가 발생하고 있습니다.

* 먼저 다음을 시도해 주세요 [Edgegap 플러그인 업데이트](https://github.com/edgegap/edgegap-unity-plugin?tab=readme-ov-file#update-the-plugin-in-unity) 해보세요. 수정 사항이 배포되었을 수 있습니다. 그래도 도움이 되지 않으면 저희 [커뮤니티 디스코드](https://discord.gg/NgCnkHbsGp) 에서 연락해 주시면 신속히 함께 조사하겠습니다.

</details>

## 🧪 4. 서버를 로컬에서 테스트

☑️ 다음 옵션을 구성할 수 있습니다(또는 기본값 유지):

* **서버 이미지 태그** 이전 단계에서의 것입니다.
  * 플러그인으로 빌드한 마지막 태그가 기본값입니다.
* **선택적 docker run 매개변수** 는 여러 포트를 노출하거나 macOS 머신에서 이미지를 실행하는 데 사용할 수 있습니다.
  * 필요한 경우 컨테이너에 여러 포트를 게시할 수 있으며, 매개변수만 추가하면 됩니다 `-p {internal port}/{protocol}` 각각에 대해 예를 들어 `-p 8080/tcp -p 7777/udp` 를 사용해 서버 포트를 게시하고 매핑하여 `8080` TCP 연결용 임의의 외부 포트와 서버 포트 `7777` 를 UDP 연결용 임의의 외부 포트에 동시에 매핑할 수 있습니다.
  * **Transport 또는 netcode 전용 설정에서 서버 포트 구성을 찾으세요.**
  * ARM 아키텍처(macOS M1, M2, M3 등)를 사용하는 머신이라면 선택적 docker 빌드 매개변수에 다음 선택적 매개변수가 포함되어 있어야 합니다: `--platform=linux/amd64` .

☑️ 구성이 만족스러우면 **로컬 컨테이너 배포**를 실행한 뒤 프로세스가 끝날 때까지 기다리고 Unity 콘솔에 새 오류가 없는지 확인하세요. 이 단계를 완료하면 **새 컨테이너가 시작됩니다** 개발 머신에서.

{% hint style="info" %}
자세한 내용은 Docker Desktop / Containers 또는 Docker CLI 명령을 참조하세요 `docker ps` .
{% endhint %}

☑️ 이제 할 일은 **Unity Editor 게임 클라이언트를 로컬 docker 컨테이너에 연결하는 것입니다** 서버 이미지가 제대로 동작하는지 확인하기 위해서입니다. netcode 클라이언트 설정을 찾아 다음을 입력하세요:

* `localhost` 또는 `0.0.0.0` (대부분의 경우 동일함)를 서버 IP 대신 사용하고
* Docker Desktop / Containers / edgegap-server-test에서 찾은 무작위 외부 포트 값을 사용하세요.

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

Unity Editor 게임 클라이언트를 사용해 로컬 docker 컨테이너에 연결할 수 없습니다.

* 먼저 컨테이너 상태가 Up인지, 그리고 Restarting이나 Exited가 아닌지 확인하세요. 이는 런타임 예외를 의미합니다. 컨테이너가 실행 중이 아니라면 Docker Desktop의 Containers 탭에서(컨테이너를 클릭) 또는 다음을 사용해 로그를 확인하세요 `docker logs {container_id} --timestamps` docker CLI를 통해.
* 다음으로 서버 빌드의 Network Manager 포트 설정이 **선택적 docker run 매개변수**의 게시된 포트와 일치하는지 확인하세요. 일치하지 않으면 이 입력 필드의 값을 재설정하거나 수동으로 변경하여 `{container}` 의 포트를 Network Manager 설정과 맞춰 보세요. 프로토콜은 netcode 설정에서 찾을 수 있습니다.
* 마지막으로 Unity Editor 게임 클라이언트 netcode 설정이 **선택적 docker run 매개변수** 에 게시된 포트를 사용하고 있는지 확인하세요(위 스크린샷 참조).

***

`(Segmentation fault) - core dumped`

* ARM 아키텍처(macOS M1, M2, M3 등)를 사용하는 머신이라면 선택적 docker 빌드 매개변수에 다음 선택적 매개변수가 포함되어 있어야 합니다: `--platform=linux/amd64` . 그렇지 않다면 이 입력 필드의 값을 재설정해 보세요.

***

`SceneObjects에서 SceneId 9120233082191360994를 찾을 수 없습니다.`

* 이는 로드하려는 씬이 빌드에 올바르게 포함되지 않았음을 의미할 수 있으며, 이전 플러그인 버전에서 알려진 문제입니다. 해결하려면 netcode 통합 버전을 업데이트하거나 [Edgegap 플러그인 업데이트](https://github.com/edgegap/edgegap-unity-plugin?tab=readme-ov-file#update-the-plugin-in-unity).

***

`http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed`

* 이것은 [Windows용 이전 버전의 Docker Desktop에서 알려진 문제입니다](https://github.com/docker/for-win/issues/13611). Docker Desktop 애플리케이션을 업데이트한 뒤 다시 컨테이너화를 시도해 주세요.

***

`Curl error 35: Cert handshake failed. Fatal error. UnityTls error code: 7`

* 이 오류는 루트 SSL 인증서 검증 문제를 나타내며, 이전 플러그인 버전에서 알려진 문제입니다. 해결하려면 다음을 시도해 주세요 [Edgegap 플러그인 업데이트](https://github.com/edgegap/edgegap-unity-plugin?tab=readme-ov-file#update-the-plugin-in-unity).

</details>

## ☁️ 5. Edgegap에 업로드

☑️ 다음 옵션을 구성할 수 있습니다(또는 기본값 유지):

* **애플리케이션 이름** Edgegap에서는 이미지 이름과 같게 하거나 사용자 지정할 수 있습니다.
  * 일단 이미지 이름을 복사하도록 선택했습니다.
* **애플리케이션 버전** Edgegap에서는 태그와 같게 하거나 사용자 지정할 수 있습니다.
  * 타임스탬프는 앱 버전 이름으로 좋은 선택입니다. 예: `2024.01.30-16.50.20-UTC` .
  * 여러 애플리케이션 버전이 동일한 이미지 태그를 가리킬 수 있습니다. 예: `v1.1.0` 및 `dev` .
  * 자세히 알아보기 [앱 및 버전](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md) 는 나중에 하세요.
* **서버 이미지 이름** 의 단계에서 [#id-3.-containerize-your-game-server](#id-3.-containerize-your-game-server "mention").
* **서버 이미지 태그** 의 단계에서 [#id-3.-containerize-your-game-server](#id-3.-containerize-your-game-server "mention").

{% hint style="success" %}
장치에 저장된 이미지 이름과 태그를 다음 위치에서 찾으세요 **Docker Desktop / Images**.
{% endhint %}

☑️ 구성이 만족스러우면 **이미지 업로드 및 App 버전 생성**를 기다린 뒤 Unity 콘솔에 새 오류가 없는지 확인하세요.

☑️ 이제 다음 화면으로 이동합니다 [대시보드](https://app.edgegap.com/)여기에서 선택적 설정을 구성할 수 있습니다. 이 단계를 완료하면 [새 Application 버전이 생성되고](https://app.edgegap.com/application-management/applications/list)그리고 [빌드 아티팩트에 태그가 지정되어 Edgegap의 Container Registry에 업로드됩니다](https://app.edgegap.com/registry-management/repositories/list).

☑️ 이제 새 Application 버전의 Port를 정의하라는 메시지가 표시됩니다. 단계 [#id-4.-test-your-server-locally](#id-4.-test-your-server-locally "mention") 에서와 같은 서버 포트 값을 반드시 설정하세요.

✅ 이제 다음 단계로 진행할 수 있습니다.

## 🚀 6. 클라우드에 배포

☑️ 이제 최종 테스트를 수행하고 **Unity Editor 게임 클라이언트를 클라우드 배포에 연결하세요**. 배포의 다음 항목에서 게임 클라이언트 연결 세부 정보를 입력하세요:

* **호스트** **URL** 서버 IP를 가리키며, 보통 `NetworkManager` 컴포넌트에 있습니다.
* **외부 포트** 에 매핑되며 [서버의 내부 수신 포트](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#port-mapping)에 해당하고, 보통 Transport 컴포넌트에 있습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

클라이언트를 서버에 연결할 수 없음 - `요청 시간 초과.` , `요청 시간 초과` , `ConnectionFailed` , 또는 `포트 검증 실패`

* 먼저 배포가 준비 완료 상태인지, 그리고 배포 로그에 런타임 예외나 오류가 없는지 확인하세요. 배포가 중지되었다면 로그를 다음에서 확인하세요 [대시보드](https://app.edgegap.com/deployment-management/deployments/list).
* Mirror 넷코드를 사용 중이라면 ["Auto Start Server"](https://mirror-networking.gitbook.io/docs/hosting/edgegap-hosting-plugin-guide#build-and-push) 다음에서 선택해야 합니다 `NetworkManager` , 서버를 다시 빌드하고, 푸시한 다음 재배포하세요.
* FishNet 넷코드를 사용 중이라면 ["Start on Headless"](https://fish-networking.gitbook.io/docs/manual/components/managers/server-manager#settings-are-general-settings-related-to-the-servermanager) 를 활성화해야 합니다 `ServerManager`, 서버를 다시 빌드하고, 푸시한 다음 재배포하세요.
* Photon Fusion 2 넷코드를 사용 중이라면, 서버가 배포의 공용 IP, 외부 포트 및 `roomCode` 를 서버에 전달하고, 클라이언트에서도 동일한 룸 코드를 ["NeworkRunner.StartGame"](https://doc.photonengine.com/fusion/current/manual/network-runner#creating-or-joining-a-room) 매개변수에서 사용하고 있는지 확인하세요 `StartGameArgs`. 배포 ID(예: `b63e6003b19f`)는 전역적으로 고유하고 클라이언트가 [매치메이커](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md) 및 [심층 살펴보기](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#injected-environment-variables).
* 다음으로, 서버 빌드의 넷코드 설정에 있는 포트 설정이 [App 버전](https://app.edgegap.com/application-management/applications/list)의 내부 포트와 일치하는지 확인하세요. 재빌드 없이 포트 매핑을 변경하려면 [App 버전](https://app.edgegap.com/application-management/applications/list) 를 편집하세요. 프로토콜은 넷코드 통합에서 찾을 수 있습니다.
* 게임 클라이언트가 다음에 연결하고 있는지 확인하세요 **외부 포트** 배포 상세 페이지에 표시된 값은 보안상의 이유로 항상 무작위로 할당됩니다.
* 넷코드 통합에서 Secure Websocket(WSS) 프로토콜을 사용 중이라면, [App 버전](https://app.edgegap.com/application-management/applications/list) WSS 포트의 포트 구성에서 TLS 업그레이드가 활성화되어 있는지 확인하세요.
* 중국에 있고 [Smart Fleets](https://docs.edgegap.com/docs/deployment/session/fleet-manager/fleet)을 사용 중이신가요? Great Firewall 때문에 연결이 차단될 수 있습니다. 플릿에 중국에 위치한 서버를 추가하거나, VPN을 사용하여 연결해 보세요.

***

배포가 중지/재시작되어 더 이상 로그에 접근할 수 없습니다.

* 예외로 인해 서버 프로세스가 충돌하는 경우, 시스템이 서버를 자동으로 재시작하려고 시도합니다. 원인을 파악하려면 [서버를 로컬에서 테스트하는 것](#id-4.-test-your-server-locally) 을 고려해 보세요.
* 우리는 배포 기간 동안만 로그를 보관합니다. 배포가 중지된 후 로그를 확인하고 싶다면 [서드파티 로그 저장소를 통합하세요](https://docs.edgegap.com/docs/deployment/endpoint-storage).
* 참조 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped "mention") 배포 중지의 모든 원인을 찾기 위해.

***

내 배포가 X분 후 자동으로 중지되었습니다.

* Free Tier 배포에는 60분 제한이 있으므로 계정 업그레이드를 고려해 주세요.
* 모든 배포는 서버 정리 정책에 따라, 인프라 유지보수를 위해, 그리고 배포가 제대로 종료되지 않았을 때 예상치 못한 비용이 쌓이는 것을 방지하기 위해 실행 후 24시간이 지나면 종료됩니다. 장시간 실행되는 서버의 경우 다음 사용을 고려하세요 [프라이빗 플릿](/docs.edgegap.com-ko/learn/orchestration/private-fleets.md) 와 함께 [지속성](/docs.edgegap.com-ko/learn/orchestration/persistence.md).
* 참조 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped "mention") 배포 중지의 모든 원인을 찾기 위해.

***

내 배포는 준비 완료 상태지만 그 후 몇 분 동안 연결할 수 없습니다.

* 배포가 준비 완료되면 게임 엔진 초기화가 시작됩니다. 이 과정은 몇 초에서 몇 분까지 걸릴 수 있으며, 이 기간 동안 서버는 플레이어 연결을 허용하지 않습니다.
* 이 시간을 줄이기 위해 서버 초기화를 최적화하는 것을 고려하세요.
* 게임 클라이언트는 제한된 시간 동안(초기화 지속 시간에 따라) 1초 간격으로 연결을 재시도한 뒤, 매치메이킹으로 돌아가야 합니다.
* 로딩 씬을 추가하여 서버가 클라이언트와 동시에 초기화를 수행하고(언리얼 엔진의 경우 이동도 포함) 두 상태를 동기화할 수 있도록 고려하세요.

***

내 Meta Quest 기기에서 다음 오류가 발생합니다 `HTTP 0: 대상 호스트를 해석할 수 없음` .

* Android 대상용 Unity 앱을 빌드할 때, 인터넷 액세스 권한이 출력 APK 클라이언트 빌드 아티팩트에서 자동으로 제거될 수 있습니다.
* 다음에서 권한을 다시 추가하세요(이후 클라이언트를 다시 빌드해야 함):
  * 프로젝트 설정 / OpenXR / :gear: Meta Quest 지원 / 인터넷 권한 강제 제거(체크 해제).
  * 플레이어 설정 / 인터넷 액세스(필수로 설정).

***

플레이어가 내 배포를 떠나면 어떻게 되나요?

* 기본적으로 서버는 플레이어 연결을 거부하지 않습니다. 플레이어 인증은 개발자에게 달려 있으며, 다양한 방식과 플레이어 인증 제공자를 사용할 수 있습니다.
* 게임 클라이언트는 예기치 않은 클라이언트 충돌 시 재연결을 시도하기 위해 연결 정보를 로컬에 저장할 수 있습니다.
* 플레이어가 진행 중인 게임에 참여할 수 있도록 하려면 다음 사용을 고려하세요 [심층 살펴보기](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#backfill) 또는 [세션](https://docs.edgegap.com/docs/deployment/session).

***

내 서버는 준비 완료가 된 후 CPU 사용률이 100%로 표시됩니다.

* 게임 엔진은 서버 초기화 동안 CPU 집약적인 작업을 수행하는 경향이 있으므로 이것은 문제가 아닐 수 있습니다. 배포 시작 후 2\~3분이 지나도 CPU 사용량이 줄지 않는다면 서버를 최적화하거나 앱 버전 리소스를 늘려야 할 수 있습니다.
* 틱 레이트를 줄이면 서버가 수행하는 메시징 작업이 줄어들어 CPU 사용량에 영향을 줄 수 있습니다.
* Mirror 넷코드를 사용 중이라면 ["Auto Start Server"](https://mirror-networking.gitbook.io/docs/hosting/edgegap-hosting-plugin-guide#build-and-push) 다음에서 선택해야 합니다 `NetworkManager` , 서버를 다시 빌드하고, 푸시한 다음 재배포하세요.
* FishNet 넷코드를 사용 중이라면 ["Start on Headless"](https://fish-networking.gitbook.io/docs/manual/components/managers/server-manager#settings-are-general-settings-related-to-the-servermanager) 를 활성화해야 합니다 `ServerManager`, 서버를 다시 빌드하고, 푸시한 다음 재배포하세요.
* 무료 티어에서는 1.5 vCPU와 3GB 메모리(RAM)로 제한됩니다.
* 새 앱 버전을 생성할 때 할당된 리소스를 늘릴 수 있습니다. 서버나 이미지를 다시 빌드하지 않고도 대시보드에서 앱 버전을 복제한 뒤 필요에 따라 이 값을 조정할 수 있습니다.

***

배포가 반복적으로 재시작되고 오류가 표시됩니다 `OOM kill`

* 할당된 메모리 양을 초과해서 발생합니다. 오브젝트 풀링, 압축 또는 씬에서 불필요한 오브젝트 제거를 통해 메모리 사용을 최적화하는 것을 고려하세요.
* 프로젝트가 다음을 포함하는 기본 씬을 불러오고 있는지 확인하세요 `NetworkManager` 그리고 해당 씬이 Unity의 빌드 설정에 포함되어 있는지 확인하세요.
* 무료 티어에서는 1.5 vCPU와 3GB 메모리(RAM)로 제한됩니다.
* 새 앱 버전을 생성할 때 할당된 리소스를 늘릴 수 있습니다. 서버나 이미지를 다시 빌드하지 않고도 대시보드에서 앱 버전을 복제한 뒤 필요에 따라 이 값을 조정할 수 있습니다.

***

때때로 서버의 메모리(RAM) 사용량이 높은 값으로 급증하는데, 문제가 되나요?

* 할당된 앱 버전 메모리 양을 초과하지 않는 한, 이것은 문제가 아닙니다.
* 할당된 앱 버전 메모리 양을 초과하면 `OOM kill` 이 발생합니다(위 참조).

***

같은 머신에서 실행 중인 다른 서버들이 내 서버 성능에 영향을 미치나요?

* 아니요, 우리 플랫폼은 할당된 리소스가 다른 스튜디오나 공유 인프라의 다른 서버에 의해 사용되지 않도록 보장합니다. Edgegap에서는 시끄러운 이웃이 없습니다.

</details>

## 👉 다음 단계

### 배포 중지

매치가 끝나거나 플레이어가 떠나면 비용 절감을 위해 배포를 중지할 수 있습니다. [비어 있거나 일부만 채워진 상태로 계속 실행하면 비용이 불필요하게 증가할 수 있습니다!](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)

{% hint style="success" %}
우리의 `DeploymentAgent`  Unity SDK의 예제를 **사용해 서버를 쉽고 안정적으로 중지**.
{% endhint %}

### 주입된 변수

주입된 환경 변수에 접근하여 배포 ID, 서버 IP 주소, 서버 위치 등의 유용한 정보를 읽을 수 있습니다. 각 배포에는 자동으로 다음이 포함됩니다:

* [배포 변수](/docs.edgegap.com-ko/learn/orchestration/deployments.md#injected-environment-variables) - Edgegap에서 자동으로 제공됨,
* [매치메이킹 변수](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#injected-environment-variables) - 사용할 때 Edgegap에서 자동으로 제공됨 [매치메이킹](/docs.edgegap.com-ko/learn/matchmaking.md),
* [앱 버전 변수](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#injected-variables) - 사용자가 구성할 수 있는 사용자 정의 키-값 쌍.

{% hint style="success" %}
우리의 `DeploymentAgent`  Unity SDK의 예제를 **강력한 형식의 변수를 쉽게 읽기**.
{% endhint %}

### 세션 자동화

### 빌드 최적화

**마지막 빌드 이후 변경된 에셋만 다시 빌드합니다.**

다음을 사용하는 것을 고려하세요 [Unity의 증분 빌드](https://docs.unity3d.com/Manual/incremental-build-pipeline.html) 를 사용해 빌드 시간을 단축하세요.

* 다음을 사용하는 것을 고려하세요 [Unity의 증분 빌드](https://docs.unity3d.com/Manual/incremental-build-pipeline.html) 를 사용해 빌드 시간을 단축하세요.

**서버 실행에 절대적으로 필요한 것만 포함하세요.**

* 사용하지 않는 파일을 이미지에 복사하면 이미지 비대화, 업로드 시간 증가, 캐싱 속도 저하, 전반적인 서버 시작 속도 저하가 발생합니다. [Docker 이미지 최적화 제안을 검토하세요](https://docs.docker.com/build-cloud/optimization/#dockerignore-files).

**이미지 크기를 줄이려면 메시의 정적 배칭을 비활성화하세요.**

* [빌드, 업로드, 배포를 더 빠르게 하려면 정적 배칭을 비활성화하세요.](https://docs.unity3d.com/Manual/DrawCallBatching.html)

**이미지 크기를 줄이려면 메시를 압축하세요.**

* [빌드, 업로드, 배포를 더 빠르게 하려면 메시 압축을 High로 설정하세요.](https://docs.unity3d.com/6000.0/Documentation/Manual/compressing-mesh-data-optimization.html)
* 버텍스 압축은 이미지 크기에 영향을 주지 않습니다.

**리소스의 조건부 지연 로딩을 구현하세요.**

* 클라이언트 전용 에셋은 다음으로 제외하세요 [텍스처와 메시의 CPU 읽기/쓰기를 비활성화하여](https://docs.unity3d.com/6000.0/Documentation/Manual/dedicated-server-optimizations.html).
* 다음을 사용하는 것을 고려하세요 [Unity Addressables](https://docs.unity3d.com/Packages/com.unity.addressables@2.1/manual/index.html) 를 클라이언트 빌드에 사용하여 [필요할 때 에셋을 로드함으로써](https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html)빌드 및 배포를 가속화하거나, 다음 존재 여부를 확인해 서버 빌드에서 일부 에셋 로딩을 건너뛰세요 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#injected-environment-variables).

**다음을 사용하는 것을 고려하세요** [**멀티 스테이지 Docker 빌드(링크)**](https://docs.docker.com/build/building/multi-stage/)**.**

* 대용량 서버 종속성을 별도의 이미지로 분리하여 멀티 스테이지 빌드에서 재사용하세요. Docker는 각 레이어를 캐시하고 이전 버전을 단순히 재사용하며, 별도 지시가 없는 한 이 부분의 업로드를 건너뛰므로 대역폭과 업로드 완료 대기 시간을 절약할 수 있습니다.
* Dockerfile 명령 중 하나가 오류를 발생시키는 이유를 모르겠다면, 로컬에서 디버깅해 보세요. 문제가 발생하기 직전에 새 스테이지를 만들고(두 번째 `FROM` 명령을 추가), `--target` 을 사용하여 빌드 프로세스가 문제의 스테이지에서 멈추도록 지시한 다음 `docker exec -it {container} /bin/bash` 를 사용해 컨테이너 내부의 대화형 터미널로 들어가세요. 그다음 베이스 이미지의 셸 명령을 사용해 추가로 조사할 수 있습니다(예: `top` 우분투에서).

### 이미지 사용자 지정

또한 빌드 크기 최적화, 불필요한 종속성, 더 복잡한 시작 과정 때문에 이미지에 대해 더 많은 제어가 필요한 사용자를 위해 자체 Dockerfile을 추가하는 것도 지원합니다. 단계에서 사용자 지정 Dockerfile의 경로를 선택적으로 제공할 수 있습니다 [#id-3.-containerize-your-game-server](#id-3.-containerize-your-game-server "mention"). 이제 몇 가지 “직접 해보는” 팁과 모범 사례를 공유하겠습니다.

**Websockets 또는 HTTPS 요청을 사용할 때 문제가 있나요?**

* 다음 오류가 발생한다면 `Curl error 35: Cert handshake failed. Fatal error. UnityTls error code: 7` 걱정하지 마세요. 이는 만료된 루트 기관 인증서가 포함된 이전 베이스`FROM`이미지에서 알려진 문제입니다. 더 최신 베이스 이미지 버전(예: `ubuntu:22.04`)로 업데이트한 뒤 `update-ca-certificates` 를 실행하면 해결할 수 있습니다. 이를 Dockerfile에 추가하세요:

  ```docker
  FROM ubuntu:22.04

  RUN apt-get install -y ca-certificates && \
      apt-get clean && \
      update-ca-certificates
  ```

{% hint style="info" %}
막다른 길에 부딪혔나요? 저희는 다음에서 도움을 드릴 수 있습니다 [커뮤니티 디스코드](https://discord.gg/MmJf8fWjnt) 그리고 기꺼이 도와드리겠습니다.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgegap.com/docs.edgegap.com-ko/unity.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
