This document is about: PUN 2
SWITCH TO

PUN Classic (v1)、PUN 2 和 Bolt 處於維護模式。 PUN 2 將支援 Unity 2019 至 2022,但不會添加新功能。 當然,您所有的 PUN & Bolt 專案可以用已知性能繼續運行使用。 對於任何即將開始或新的專案:請切換到 Photon Fusion 或 Quantum。

Cached Events

Photon事件對於遊戲邏輯和房間內的玩家交流具有核心作用。
客戶端調用RaiseEvent(確切的函數或方法名稱可能會有所不同,取決於您的客戶端SDK)來發送數據給房間裡的一個或多個玩家。
所有加入的玩家將能夠立即收到這些事件。
然而,晚加入的玩家將錯過這些事件,除非您使用緩存選項。

當您緩存一個事件時,Photon伺服器會將其保存在房間狀態中,以保証以後加入房間的玩家可以使用。
Photon伺服器將首先把事件發送給加入的玩家,然後再轉發任何最終的 "實時 "事件。

Use case 1:
您可以緩存一個 "開始時間 "事件,其中包含一個回合創建的時間戳作為數據。
這樣,任何加入遊戲的人都會知道這個回合是什麼時候開始的(可能還有什麼時候應該結束)。

有秩序發送是有保証的

加入遊戲的玩家獲得緩存的事件與這些事件到達伺服器的順序相同。
客戶端首先讀取房間和玩家的屬性(所以每個玩家都是已知的),然後獲得緩存的事件。
所有加入後發送的事件都會在之後被傳遞。

所以您可以認為緩存的事件接收順序與它們的傳輸順序相同。
隻有在使用UDP和事件發送不可靠的情況下,才可能出現例外情況。

了解事件是如何被緩存的

在此不做過多贅述,以下是您需要知道的關於事件如何被緩存的內容。

每個被緩存的事件都可以由其代碼、數據和發送者的行為者編號來定義。

事件緩存也可以被分組為兩個 "邏輯分區":

  • "全局緩存":與房間相關的緩存(ActorNr == 0)。
    它包含所有已經用EventCaching.AddToRoomCacheGlobal標志發送的、沒有明確刪除的緩存事件。
    這些緩存的事件不能再被追溯到它們的原始發送者。這就是為什麼這些事件會被發送到任何加入的actor。
  • " Actor緩存":與一個特定的actor編號(ActorNr !=0)相關的緩存。
    它包含所有由該行為體發送的、沒有明確地被添加到全局緩存或從緩存中刪除的緩存事件。
    這些事件被發送到任何加入的角色,除了它們原來各自的發送者。

掌控事件緩存

在C# LoadBalancing API和PUN中,用戶需要向任何 RaiseEvent(確切的函數或方法名稱可能會有所不同,取決於您的客戶端SDK)調用傳遞一個 RaiseEventOptions對象:
這個參數包括一個CachingOption屬性。
讓我們發現每個可能的EventCaching值是如何影響事件緩存的。

  • DoNotCache:這是默認值。它表示要發送的事件將不會被添加到房間的緩存中。
  • AddToRoomCache:這表示要發送的事件將被添加到發送actor的房間緩存中。
    它將被標記為發送actor的編號。
  • AddToRoomCacheGlobal:這表示要發送的事件將被添加到 "全局緩存 "中。
    使用這個值時要小心,因為在這個代碼中,事件只有在您明確要求刪除時才會被刪除。否則,它將擁有與房間相同的時間壽命。
  • RemoveFromRoomCache:這表示所有先前緩存的事件,如果符合指定的 "過濾模式",將從緩存中刪除。
    "過濾模式 "是三個參數的組合:事件代碼、發件人號碼和事件數據。您可以使用一個、兩個或全部三個過濾器。
    • 一個等於0的事件代碼是事件代碼的通配符。
    • 使用目標actor選項(在C#客戶端SDK中,這是用RaiseEventOptions.TargetActors數組完成的)來指定這種情況下的發件人編號。
      發件人號碼可以是0,這意味著您可以從 "全局緩存 "中刪除。
      所以要從全局緩存中刪除,您可以指定0作為發送者編號。
      由於目標actor是一個數組,您可以通過多個actor來過濾,甚至結合全局(ActorNr == 0)和非全局緩存的事件(ActorNr != 0)。
    • 另外,如果您通過事件數據過濾,您可以自由地只發送數據的一部分。
      例如,如果您使用一個Hashtable作為事件數據,您可以只通過指定一個或多個鍵/值對來刪除事件。
  • RemoveFromRoomCacheForActorsLeft:這表示被刪除的actor所發送的緩存事件也應該被刪除。
    如果您在創建房間時將RoomOptions.CleanupCacheOnLeave設置為 "true"(默認值),這不會產生任何影響。
Events will not be added to cache if any of the following conditions is met:
  • RaiseEventOptions.Receivers == ReceiverGroups.MasterClient.
  • RaiseEventOptions.TargetActors != null.
  • RaiseEventOptions.InterestGroups != 0.

Use case 2:
如果您使用Hashtable作為事件內容,您可以用一個 "oid "鍵("ObjectID "的縮寫)和一些值來標記所有屬於某個對象的事件。
當您想清理與特定對象相關的緩存時,您只需發送一個Hashtable(){"oid", <objectId>}作為事件數據過濾器和EventCaching.RemoveFromRoomCache

緩存清理

當一個玩家退出游戲時,他/她的行為通常不再與新玩家相關。
為了避免加入時的擁堵,Photon伺服器默認會自動清理已經離開房間的玩家所緩存的事件。

如果您想手動清理房間的事件緩存,您可以在創建房間時將RoomOptions.CleanupCacheOnLeave設置為假。

特別考慮

  • 只有當actor完全加入時,Photon客戶端才能在房間內開始調用操作(RaiseEvent, SetProperties, 等等)。
    隻有當伺服器發送完所有緩存的事件時,才會認為actor沒有完全加入。
    當試圖在一個房間內調用操作時,在收到所有緩存事件之前,客戶端將收到一個錯誤(OperationNotAllowedInCurrentState (-3))。
  • 緩存的事件也會延遲actor加入房間後發送的實時事件。
  • Photon限制了每個房間的緩存事件總數(actor緩存和全局緩存的組合)。
    如果您達到了限制,伺服器將廣播一個ErrorInfo事件並關閉房間,因此沒有新的actor可以加入。
    已經加入的actor可以保留,而不活躍的actor將無法重新加入。
Back to top