PUNのコールバックを受け取れるようにするためにはMonoBehaviourPunCallbacks
を継承する方法が最も簡単ですが、MonoBehaviour
を継承しないクラスなどではこの方法は使えません。任意のクラスでPUNのコールバックを受け取れるようにしたい場合は、PUN2で用意されているコールバックインターフェースを実装することになります。
MonoBehaviourPunCallbacksのコードを読む
MonoBehaviourPunCallbacks
がどのような実装になっているかを確認してみましょう。
以下のコードは、上記のファイルからMonoBehaviourPunCallbacks
に関連する部分を抜粋、簡略化してコメントを追加したものです。これらの実装を補うことで、どんなクラスでもPUNのコールバックを受け取れるようにすることができます。
public class MonoBehaviourPun : MonoBehaviour
{
// photonViewプロパティの追加
public PhotonView photonView { get; }
}
public class MonoBehaviourPunCallbacks : MonoBehaviourPun,
IConnectionCallbacks,
IMatchmakingCallbacks,
IInRoomCallbacks,
ILobbyCallbacks,
IWebRpcCallback,
IErrorInfoCallback
{
public virtual void OnEnable() {
// PUNのコールバック対象に登録する
PhotonNetwork.AddCallbackTarget(this);
}
public virtual void OnDisable() {
// PUNのコールバック対象の登録を解除する
PhotonNetwork.RemoveCallbackTarget(this);
}
// 各コールバックインターフェースの空実装
public virtual void OnConnected() {}
public virtual void OnLeftRoom() {}
public virtual void OnMasterClientSwitched(Player newMasterClient) {}
public virtual void OnCreateRoomFailed(short returnCode, string message) {}
public virtual void OnJoinRoomFailed(short returnCode, string message) {}
public virtual void OnCreatedRoom() {}
public virtual void OnJoinedLobby() {}
public virtual void OnLeftLobby() {}
public virtual void OnDisconnected(DisconnectCause cause) {}
public virtual void OnRegionListReceived(RegionHandler regionHandler) {}
public virtual void OnRoomListUpdate(List<RoomInfo> roomList) {}
public virtual void OnJoinedRoom() {}
public virtual void OnPlayerEnteredRoom(Player newPlayer) {}
public virtual void OnPlayerLeftRoom(Player otherPlayer) {}
public virtual void OnJoinRandomFailed(short returnCode, string message) {}
public virtual void OnConnectedToMaster() {}
public virtual void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) {}
public virtual void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) {}
public virtual void OnFriendListUpdate(List<FriendInfo> friendList) {}
public virtual void OnCustomAuthenticationResponse(Dictionary<string, object> data) {}
public virtual void OnCustomAuthenticationFailed(string debugMessage) {}
public virtual void OnWebRpcResponse(OperationResponse response) {}
public virtual void OnLobbyStatisticsUpdate(List<TypedLobbyInfo> lobbyStatistics) {}
public virtual void OnErrorInfo(ErrorInfo errorInfo) {}
}
コールバックインターフェースの実装
サンプルプロジェクト(🎮)のSampleScene
スクリプトで、MonoBehaviourPunCallbacks
を継承せずにコールバックインターフェースを実装してみましょう。ここで重要なポイントは以下の2点です。
-
SampleScene
に必要なコールバックインターフェースを実装する -
SampleScene
をPUNのコールバック対象に登録する
using System.Collections.Generic;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
-public class SampleScene : MonoBehaviourPunCallbacks
+public class SampleScene : MonoBehaviour, IConnectionCallbacks, IMatchmakingCallbacks
{
+ private void OnEnable() {
+ // PUNのコールバック対象に登録する
+ PhotonNetwork.AddCallbackTarget(this);
+ }
+ private void OnDisable() {
+ // PUNのコールバック対象の登録を解除する
+ PhotonNetwork.RemoveCallbackTarget(this);
+ }
private void Start() {
PhotonNetwork.NickName = "Player";
PhotonNetwork.ConnectUsingSettings();
}
- public override void OnConnectedToMaster() {
+ void IConnectionCallbacks.OnConnectedToMaster() {
PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default);
}
- public override void OnJoinedRoom() {
+ void IMatchmakingCallbacks.OnJoinedRoom() {
var position = new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f));
PhotonNetwork.Instantiate("Avatar", position, Quaternion.identity);
if (PhotonNetwork.IsMasterClient) {
PhotonNetwork.CurrentRoom.SetStartTime(PhotonNetwork.ServerTimestamp);
}
}
+ void IConnectionCallbacks.OnConnected() {}
+ void IConnectionCallbacks.OnDisconnected(DisconnectCause cause) {}
+ void IConnectionCallbacks.OnRegionListReceived(RegionHandler regionHandler) {}
+ void IConnectionCallbacks.OnCustomAuthenticationResponse(Dictionary<string, object> data) {}
+ void IConnectionCallbacks.OnCustomAuthenticationFailed(string debugMessage) {}
+ void IMatchmakingCallbacks.OnFriendListUpdate(List<FriendInfo> friendList) {}
+ void IMatchmakingCallbacks.OnCreatedRoom() {}
+ void IMatchmakingCallbacks.OnCreateRoomFailed(short returnCode, string message) {}
+ void IMatchmakingCallbacks.OnJoinRoomFailed(short returnCode, string message) {}
+ void IMatchmakingCallbacks.OnJoinRandomFailed(short returnCode, string message) {}
+ void IMatchmakingCallbacks.OnLeftRoom() {}
}
PUNのコールバックは、用途に応じて複数のインターフェースに定義が分けられているので、必要なインターフェースを選択して実装するようにしましょう。
名前 | 主なコールバック | 説明 |
---|---|---|
IConnectionCallbacks |
OnConnectedToMaster() 、OnDisconnected() など |
接続関連のコールバック |
IMatchmakingCallbacks |
OnCreatedRoom() 、OnJoinedRoom() 、OnLeftRoom() など |
マッチメイキング関連のコールバック |
ILobbyCallbacks |
OnJoinedLobby() 、OnLeftLobby() 、OnRoomListUpdate() など |
ロビー関連のコールバック |
IInRoomCallbacks |
OnPlayerEnterdRoom() 、OnRoomPropertiesUpdate() など |
ルーム関連のコールバック |
特別なコールバックインターフェース
MonoBehaviourPunCallbacks
には実装されていないPUNのコールバックもいくつか存在します。これらを使用する場合には、かならずコールバックインターフェースを実装する必要があります。
ネットワークオブジェクトが生成された時のコールバック
ネットワークオブジェクトのスクリプトにIPunInstantiateMagicCallback
インターフェースを実装すると、ネットワークオブジェクトが生成された時のコールバックを受け取ることができます。このインターフェースに限り、コールバック対象の登録をしなくても動作することに注意してください。
using Photon.Pun;
using UnityEngine;
public class InstantiateCallbackSample : MonoBehaviour, IPunInstantiateMagicCallback
{
// ネットワークオブジェクトが生成された時に呼ばれるコールバック
void IPunInstantiateMagicCallback.OnPhotonInstantiate(PhotonMessageInfo info) {
if (info.Sender.IsLocal) {
Debug.Log("自身がネットワークオブジェクトを生成しました");
} else {
Debug.Log("他プレイヤーがネットワークオブジェクトを生成しました");
}
}
}
ネットワークオブジェクトが破棄される直前のコールバック
ネットワークオブジェクトのスクリプトにIOnPhotonViewPreNetDestroy
インターフェースを実装すると、ネットワークオブジェクトが破棄される直前のコールバックを受け取ることができます。スクリプトは、PhotonNetwork.AddCallbackTarget()
ではなくphotonView.AddCallbackTarget()
で、PhotonView
のコールバック対象に登録します。
using Photon.Pun;
using UnityEngine;
public class DestroyCallbacksSample : MonoBehaviourPun, IOnPhotonViewPreNetDestroy
{
private void OnEnable() {
// PhotonViewのコールバック対象に登録する
photonView.AddCallbackTarget(this);
}
private void OnDisable() {
// PhotonViewのコールバック対象の登録を解除する
photonView.RemoveCallbackTarget(this);
}
// ネットワークオブジェクトが破棄される直前に呼ばれるコールバック
void IOnPhotonViewPreNetDestroy.OnPreNetDestroy(PhotonView rootView) {
Debug.Log($"{rootView.name}({rootView.ViewID}) が破棄されます");
}
}
ネットワークオブジェクトの所有者が変更された時のコールバック
ネットワークオブジェクトのスクリプトに、IOnPhotonViewOwnerChange
インターフェースを実装するとネットワークオブジェクトの所有者が変更された時のコールバックを、IOnPhotonViewControllerChange
インターフェースを実装するとネットワークオブジェクトの管理者が変更された時のコールバックを受け取ることができます。こちらもPhotonView
のコールバック対象に登録しましょう。
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
public class OwnerChangeCallbacksSample : MonoBehaviourPun, IOnPhotonViewOwnerChange, IOnPhotonViewControllerChange
{
private void OnEnable() {
// PhotonViewのコールバック対象に登録する
photonView.AddCallbackTarget(this);
}
private void OnDisable() {
// PhotonViewのコールバック対象の登録を解除する
photonView.RemoveCallbackTarget(this);
}
// ネットワークオブジェクトの所有者が変更された時に呼ばれるコールバック
void IOnPhotonViewOwnerChange.OnOwnerChange(Player newOwner, Player previousOwner) {
string objectName = $"{photonView.name}({photonView.ViewID})";
string oldName = previousOwner.NickName;
string newName = newOwner.NickName;
Debug.Log($"{objectName} の所有者が {oldName} から {newName} に変更されました");
}
// ネットワークオブジェクトの管理者が変更された時に呼ばれるコールバック
void IOnPhotonViewControllerChange.OnControllerChange(Player newController, Player previousController) {
string objectName = $"{photonView.name}({photonView.ViewID})";
string oldName = previousController.NickName;
string newName = newController.NickName;
Debug.Log($"{objectName} の管理者が {oldName} から {newName} に変更されました");
}
}