Please enable Javascript to view the contents

PUN2實作玩家自選地區進行連線

 ·  ☕ 4 分钟  ·  👩🏿‍🚀 伊琉沙 AKA 哇咔咔

實作環境

  • Unity2018.3.0f2
  • PUN 2.17
  • Photon lib 4.1.3.0
  • Photon Cloud Realtime App

PUN2 相關筆記

連線前設定

由於咱的PUN專案為了提供中國內地網友測試,所以開通了Photon的中國伺服器(中國地區的連線服務需要額外向Photon申請才能使用),由於這項功能是針對單一應用程式使用,所以為了將中國伺服器的連線納入使用,因此會有兩組appId。

導入Realtime的命名空間

在本次的實作中會使用到RegionHandler,必須在連線腳本中導入相關的命名空間。

1
using Photon.Realtime;

設定應用程式ID(AppId)

AppId一般都直接在PhotonServerSettings設定,無須在代碼中重新設定,除非遊戲還進行分區限制,例如開通了中國地區的伺服器,此時可以在正式連線前讓玩家進行選擇,請在調用連線方法前加入下列代碼,即可重新指定AppId

1
2
3
4
// 重設 AppId
PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime = "replace with your own AppId";
// 初始化 AppId,這一行無論有沒有重設 AppId 都是必要的。
PhotonNetwork.NetworkingClient.AppId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime;

設定名稱伺服器(NameServerHost)

連線前必須指定名稱伺服器,請在調用連線方法前加入下列代碼:

1
PhotonNetwork.NetworkingClient.NameServerHost = "ns.exitgames.com";

若使用中國地區伺服器,名稱伺服器則為:

1
PhotonNetwork.NetworkingClient.NameServerHost = "ns.photonengine.cn";

如果不加這一段代碼,預設的NameServerHost會是 ns.exitgames.com

連接名稱伺服器

完成前面的設定後,即可透過下列代碼調用與名稱伺服器的連線。

1
PhotonNetwork.NetworkingClient.ConnectToNameServer();

此時觀察ClientState會變成ConnectingToNameServer,當連線與加密完成後會變成ConnectedToNameServer

選擇名稱伺服器

透過遊戲介面的設計來調用不同的連線設定,即可讓玩家自行選擇名稱伺服器,參考以下範例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public void ConnectInternationServer()
{
    PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime = "6799355d-d8ce-4acd-b64f-688c4a368ccf"; // TODO: replace with your own AppId
    PhotonNetwork.NetworkingClient.AppId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime;
    PhotonNetwork.NetworkingClient.NameServerHost = "ns.exitgames.com";
    PhotonNetwork.NetworkingClient.ConnectToNameServer();
}

public void ConnectChinaServer()
{
    PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime = "4f3da426-b335-47c1-ab69-7dd9e6578c10"; // TODO: replace with your own AppId
    PhotonNetwork.NetworkingClient.AppId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime;
    PhotonNetwork.NetworkingClient.NameServerHost = "ns.photonengine.cn";
    PhotonNetwork.NetworkingClient.ConnectToNameServer();
}

連線後設定

在連上名稱伺服器的同時會在LoadBalancingClient內部調用OpGetRegions方法取得地區列表,這個列表儲存在RegionHandler裡面並透過回傳方法OnRegionListReceived取得。

1
void OnRegionListReceived (RegionHandler regionHandler);

以下是RegionHandlerRegion類的常用變數與方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class RegionHandler
{
    //這份列表記錄了該名稱伺服器底下的可用地區
    List<Region> EnabledRegions
    
    // 回傳ping值最低的地區
    Region BestRegion

    // 總結BestRegion與EnabledRegions的結果
    string SummaryToCache

    // 測試並找出ping值最低的地區
    bool PingMinimumOfRegions
}

class Region
{
    // 地區名稱,例如:asia,au,cae,eu,in,jp,kr,ru,rue,sa,us,usw,za
    string Code

    // 地區ping值
    int Ping 
}

測試各地區的ping值

  1. 首先透過覆寫OnRegionListReceived取得RegionHandler
  2. 再調用RegionHandler裡面的PingMinimumOfRegions方法。
  3. 新增一個方法OnRegionPingCompleted來接收回傳的RegionHandler,回傳方法可按需求自由命名。
1
2
3
4
5
6
7
public override void OnRegionListReceived(RegionHandler regionHandler)
{
    regionHandler.PingMinimumOfRegions(this.OnRegionPingCompleted, null);
}

// callback function
private void OnRegionPingCompleted(RegionHandler regionHandler){}

讀取各地區的ping值

接續上一步,從回傳的方法得到的RegionHandler已記錄了各地區的ping值,此時就可以讀取並顯示各地區的ping值讓玩家決定連線的地區伺服器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private void OnRegionPingCompleted (RegionHandler regionHandler)
{
    int countRegion = regionHandler.EnabledRegions.Count;
    for (int i = 0; i < countRegion; i++)
    {
            Debug.Log (regionHandler.EnabledRegions[i].Code + ": " + 
                       regionHandler.EnabledRegions[i].Ping);
    }
    Debug.Log ("BestRegion: " + regionHandler.BestRegion);
    Debug.Log ("RegionPingSummary: " + regionHandler.SummaryToCache);
}

輸出結果:

eu: 300
us: 217
usw: 166
cae: 274
asia: 70
jp: 50
au: 177
sa: 334
in: 113
ru: 307
rue: 231
kr: 107
za: 389
BestRegion: jp[5.8.70.143:5055]: 50ms 
RegionPingSummary: jp;50;asia,au,cae,eu,in,jp,kr,ru,rue,sa,us,usw,za

選擇地區伺服器

現在玩家知道了所有地區的ping值大小,最後一步就是連上地區伺服器,此時只要在玩家選擇地區的方法中傳入地區參數region並調用ConnectToRegionMaster即可。

1
PhotonNetwork.NetworkingClient.ConnectToRegionMaster(region);

當然,如果想讓玩家直接選一個最快的伺服器可以直接在OnRegionPingCompleted調用ConnectToRegionMaster

1
2
3
4
private void OnRegionPingCompleted (RegionHandler regionHandler)
{
    PhotonNetwork.NetworkingClient.ConnectToRegionMaster(regionHandler.BestRegion.Code);
}

注意事項

根據經驗,使用BestRegion連接地區伺服器,在台灣有時候會連到jpasia甚至rue三個不同的地區伺服器,而不同地區伺服器的玩家是無法共同進行遊戲的!
透過PhotonServerSettings設定Fixed Region並透過ConnectUsingSettings連線,可確保連線至固定的地區伺服器。

分享

伊琉沙 AKA 哇咔咔
作者
伊琉沙 AKA 哇咔咔
遊戲開發者 / 密室機關師