This document is about: PUN 1
SWITCH TO

PUN Classic (v1), PUN 2, Bolt는 휴업 모드입니다. Unity2022에 대해서는 PUN 2에서 서포트하지만, 신기능의 추가는 없습니다. 현재 이용중인 고객님의 PUN 및 Bolt 프로젝트는 중단되지 않고, 퍼포먼스나 성능이 떨어지는 일도 없습니다. 앞으로의 새로운 프로젝트에는 Photon Fusion 또는 Quantum을 사용해 주십시오.

WebGL 백그라운드 탭

사용자들이 복수 브라우저 탭을 오픈 했을때는, 활성(보이는)탭 만이 고속으로 정기적으로 업데이트 됩니다.
비활성(보이지 않는)탭들은 대부분의 브라우저에서 1초에 한번 업데이트 될 뿐 입니다.
이 경우에 있어서 윈도우가 앞에 있는 가시성은 중요하지 않으며 또한 다른 윈도우에 의해 가려지거나 포커스가 없을 수도 있습니다.

이것은 Unity의 WebGL 익스포트에도 적용되며 수신 및 발신 메시지가 1초에 한 번만 처리되므로 문제가 발생 할 수 있습니다.
이 의미는 메시지 큐가 커지게되고 저속으로 업데이트가 되기 때문에 처리를 위해 더 많은 업데이트가 필요하다는 것입니다.
많은 앱들은 탭이 백그라운드에서 작동하는 동안 점점 더 많은 동기화가 이루어지지 않고 연결이 끊어집니다.

WebGL 어플리케이션은 JavaScript를 사용하기 때문에 브라우저에서 메시지를 게임 로직으로 직접 보내기 위해 이러한 빌드들을 확장 할 수 있습니다.
여기에는 게임에서 연결을 끊거나 어플리케이션 탭이 백그라운에 있을 때 낮은 업데이트 속도 사이에 추가 업데이트를 적용 할 수 있는 가능성을 포함하고 있습니다.
이렇게 하기 위해서는 다음의 접근법 중 하나를 따라 할 수 있습니다.

WebGL 빌드 변경

접근법에 대해서 이야기하기 전에 어플리케이션 탭이 백그라운드에 있는지를 결정하는 방법에 대해 먼저 살펴보도록 하겠습니다.
따라서 우리는visibilitychange 이벤트를 후킹하여 변경 사항을 리슨합니다.
다른 두 상태가 있습니다: hidden 과 "any other state".
상태 변화를 감지 할 때 마다 게임 로직에서 게임 객체에 메시지를 보내고 이런 방식으로 함수를 실행할 수 있습니다.
다음 JavaScript 코드 스니펫을 사용하여 보여 줄 수 있습니다.

JavaScript

<script>

document.addEventListener('visibilitychange', function () {
    if (document.visibilityState == "hidden") {
        SendMessage("Receiver", "DoSomething");
    } else {
        SendMessage("Receiver", "DoSomethingElse");
    }
});

</script>

위의 경우에서 'Receiver' 라고 하는 게임 오브젝트에 메시지를 전송하고 있습니다.
이 객체에서는 DoSomething(Else) 라고 하는 함수를 실행하고 있습니다.
이 함수는 게임 객체에 붙여진 어떤 스크립트 내부에서도 위치 시킬 수 있습니다.

WebGL 어플리케이션에서 이 코드를 붙이기 위해서는 빌드를 탐색하여 생성된 index.html 파일을 오픈하세요.
위의 스니펫을 복사하여 붙일 수 있고 html 파일의 34 라인 <body> 태그 내부에 삽입합니다.
'SendMessage' 함수의 매개변수들을 조정하는 것을 잊지 마세요.

첫 번째 방법 - 연결 해제

첫 번째 방법은 WebGL 어플리케이션 탭이 백그라운드로 들어가면 클라이언트를 Photon에서 연결 해제하는 것 입니다.
이것은 어플리케이션이 포어그라운드로 다시 될 때, Photon으로 (재)연결을 시도할 것 입니다.
설명된 시나리오를 처리하기 위해 권장되는 방식입니다.

이렇게 하기 위해서는 index.html 파일에서 위에 나온 코드 스니펫을 사용하여 게임 로직에서 'Disconnect'및 'Reconnect' 함수로 메시지를 전송합니다.
이러한 함수는 다음의 예제와 같이 보일 것 입니다:

C#

public void Disconnect()
{
    PhotonNetwork.Disconnect();
}

public void Reconnect()
{
    if (!PhotonNetwork.connected && wasConnected)
    {
        PhotonNetwork.ReconnectAndRejoin();
    }
    else
    {
        PhotonNetwork.ConnectUsingSettings("1.0");
    }
}

참고: 부울 변수wasConnected는 클라이언트가 이전에 방에 들어 왔을 때 true로 설정됩니다.
이 정보를 가지고 있음으로써 먼서 로비에 참여하는 대신 룸에 다시연결하고 재참여를 직접 시도할 수 있습니다.

ReconnectAndRejoin를 올바르게 사용하기 위해서는 룸과 룸의 옵션들을 올바르게 설정해야 합니다. 이 의미는 PlayerTtl(플레이어가 서버에서 제거되기 전에 연결 해제 후 얼마나 오랫동안 비활성화 될 수 있는지를 나타냅니다. 단위 밀리초)를 0보다 큰 값으로 설정해야 한다는 의미입니다. 빈 룸을 유지하기 원하는 경우에는 EmptyRoomTtl(서버에서 룸이 제거될 때 까지 얼마나 오랫동안 비어있는 룸을 유지할 것인지, 단위 밀리초)를 0보다 큰 값으로 설정해야 합니다.

이 방법을 사용하여 ReconnectAndRejoin 을 테스트 할 때는 두 값 모두 30,000 (30 초) 또는 심지어 60,000(60 초)로 설정하는 것이 좋을 것 입니다.

두 번째 방법 - 관심 그룹을 사용하고 연결을 살아있는 상태로 유지하기

두 번째 방법은 게임 로직 및 특히 네트워킹 로직에 대한 추가 작업이 필요합니다.
이 접근 방식을 사용하는 것은 게임 관련 메시지를 보내거나 받지 않고 연결을 계속 유지하는 것 입니다.
특정 그룹으로 부터의 빠른 구독 또는 구독해제를 하기 위해 관심 그룹을 사용하여 달성하는 것 입니다.

PUN이 사용하는 기본 그룹은 0입니다. 이 그룹에서는 구독해제를 할 수 없기 때문에, 이것을 사용하여 문제를 해결 할 수는 없습니다.

위에서 설명한 것처럼 이 방식을 사용할 때 다른 관심 그룹이 필요합니다.
다음의 예제에서 그룹 1을 사용하여 이 그룹에서 자유롭게 구독 및 구독해제 하도록 하였습니다.

Photon에 연결할 때 원하는 그룹에서 송신과 수신이 가능한지 확인하세요.
다음을 호출하여 이를 수행할 수 있습니다:

C#

PhotonNetwork.SetReceivingEnabled(1, true);
PhotonNetwork.SetSendingEnabled(1, true);

또한 인스턴스화된 게임 개체 (PhotonView 컴포넌트가 연결된 개체)가 그룹 변수를 원하는 그룹으로 설정했는지 확인하세요. 예를들어:

C#

public void Awake()
{
    GetComponent<PhotonView>().group = 1;
}

대부분의 네트워크 트래픽을 특정 그룹으로 '이동한' 경우 브라우저의 JavaScript에서 호출되는 이 두 가지 함수를 계속 추가 할 수 있습니다.
예제에서는 'Subscribe' 와 'Unsubscribe' 로 이름을 부여했습니다. 두 함수는 다음과 같습니다:

C#

public void Subscribe()
{
    GetComponent<PhotonView>().group = 1;
    
    PhotonNetwork.SetReceivingEnabled(1, true);
    PhotonNetwork.SetSendingEnabled(1, true);
}

public void Unsubscribe()
{
    GetComponent<PhotonView>().group = 2;
    PhotonNetwork.SetReceivingEnabled(1, false);
    PhotonNetwork.SetSendingEnabled(1, false);
}

마지막 단계에서 할 일은 앞서 설명한 두 가지 함수를 호출 할 수 있도록 "index.html" 파일에 추가 할 JavaScript 스니펫을 조정하는 것입니다.

이것은 많은 문제를 일으킬 수 있고 실제로 해결할 수 있는 것보다 많은 문제를 야기 할 수 있기 때문에 이 문제를 해결하기 위한 권장되는 방법은 아닙니다.

세 번째 방법 - 강제 업데이트와 연결 상태 유지

이 방법은 모든 수신 및 발신 메시지의 처리를 강제로 하기 때문에 이전의 두 방식과는 다릅니다.
따라서 기본 자바 스크립트 스니펫을 다음과 같이 조정해야 할 필요가 있습니다:

JavaScript

&lt;script&gt;

var isActive;

document.addEventListener('visibilitychange', function () {
if (document.visibilityState == "hidden") {
    isActive = setInterval(function() { SendMessage("Receiver", "DoSomething"); }, 250);
} else {
    clearInterval(isActive);
    isActive = false;
}
});

&lt;/script&gt;

이것은 현재 보이는 상태를 기반으로 타이머를 생성하고 파괴합니다.
이 타이머가 활성화되면 각 함수는 250 ms 또는 1초에 4회 호출됩니다.
SendMessage 함수의 매개 변수뿐만 아니라 요건에 맞게 간격을 조정할 수 있습니다.

이 업데이트가 있으므로 WebGL 프로젝트도 계속 조정할 수 있습니다.
그러므로 우리는 앞서 소개 한 타이머에서 호출 될 DoSomething 함수를 생성합니다.
이 함수는 다음과 같습니다:

C#

public void DoSomething()
{
    if (!PhotonNetwork.connected || !PhotonNetwork.inRoom)
    {
        return;
    }

    PhotonNetwork.networkingPeer.DispatchIncomingCommands();
    PhotonNetwork.networkingPeer.SendOutgoingCommands();
}

브라우저의 탭이 백그라운드에 있어도 네트워크의 메시지 흐름이 증가합니다.
이것이 좋은 아이디어 인것 같지만 이 방식 역시 큰 단점을 가지고 있습니다.
게임이 실제로 보이지 않을 때 캐릭터를 제어 할 수 없기 때문에 캐릭터의 변형과 관련된 사항은 변경되지 않습니다.
따라서 항상 동일한 정보를 다른 클라이언트에게 보냅니다.
이 의미는 중요한 콘텐츠가 없는 메시지 수가 증가 한다는 것 입니다.
그래서 이 모든 접근법은 모두 권장되지 않습니다.

네 번째 방법 - 세 번째 방법을 조정하여 계속 연결 유지

세 번째 방법을 권장하지 않을지라도 가장 마지막 방식에서 사용할 수 있습니다.
따라서 'DoSomething' 함수를 다음과 같이 변경 합니다:

C#

public void DoSomething()
{
    PhotonNetwork.networkingPeer.SendAcksOnly();
}

이 연결을 유지하기 위해 단순히 서버에 인지를 보냅니다.
추가로 생성 된 간격에 관련된 게임 로직은 처리되지 않습니다.

Back to top