PUN Classic (also called PUN1) is the original and first major version of PUN. It is now replaced by PUN2 which is refactored and enhanced. We highly recommend starting new projects with PUN2 and if possible migrating existing ones from PUN1 to PUN2 by following our "Migration Notes". PUN Classic will be maintained for the coming months. We will fix important bugs and support new Unity versions but new features will be added only to PUN2.

Cached Events

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

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

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

有秩序發送是有保証的

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

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

Back To Top

了解事件是如何被緩存的

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

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

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

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

Back To Top

掌控事件緩存

在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

Back To Top

緩存清理

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

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

Back To Top

特別考慮

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

To Document Top