トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

unity_photon_cloud_monobehaviour

Unity内ではじめにすること > LobbyとRoomとPlayerの概念


[Photon Cloud] スクリプト内でやってること/Photon.MonoBehaviour派生クラス


Unity内ではじめにすること」でComponentとして追加した「RandomMatchmaker.cs」で何をしているのか見てみます。

「MonoBehaviour」をラップした「Photon.MonoBehaviour」の派生クラスとしてPhoton専用のコールバックや指定が行われています。

 参考のClass Reference

Unityのメインメニューより「Window」-「Photon Unity Networking」-「PUN Wizard」を選択。
「Open PDF」を選択したPDF内にPhoton.MonoBehaviourのコールバック関数やPhotonNetwork/PhotonViewクラスについてのReferenceがあります。

また、

http://photoncloud.jp/pdf/PhotonNetwork-Documentation_ja.pdf

で日本語ドキュメントをダウンロードできます。

 RandomMatchmaker.cs内を見る


まずは、RandomMatchmaker.cs内の全部の記述です。

using UnityEngine;

public class RandomMatchmaker : Photon.MonoBehaviour {
    private PhotonView myPhotonView;

    // Use this for initialization
    void Start() {
        PhotonNetwork.ConnectUsingSettings("0.1");
    }

    void OnJoinedLobby() {
        Debug.Log("JoinRandom");
        PhotonNetwork.JoinRandomRoom();
    }

    void OnPhotonRandomJoinFailed() {
        PhotonNetwork.CreateRoom(null);
    }

    void OnJoinedRoom() {
        GameObject monster = PhotonNetwork.Instantiate("monsterprefab", Vector3.zero, Quaternion.identity, 0);
        monster.GetComponent<myThirdPersonController>().isControllable = true;
        myPhotonView = monster.GetComponent<PhotonView>();
    }

    void OnGUI() {
        GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString());

        if (PhotonNetwork.connectionStateDetailed == PeerState.Joined) {
            bool shoutMarco = GameLogic.playerWhoIsIt == PhotonNetwork.player.ID;

            if (shoutMarco && GUILayout.Button("Marco!")) {
                myPhotonView.RPC("Marco", PhotonTargets.All);
            }
            if (!shoutMarco && GUILayout.Button("Polo!")) {
                myPhotonView.RPC("Polo", PhotonTargets.All);
            }
        }
    }
}

Photon.MonoBehaviour派生クラスであるのを確認

RandomMatchmakerクラスはPhoton.MonoBehaviourの派生クラスであるのを確認できます。
まずはこれが大事。

初期化処理

アプリ実行時に呼ばれるStart関数内で

PhotonNetwork.ConnectUsingSettings("0.1");

を呼んでます。この記述は必須。
ここでのバージョン文字列は、アプリケーション自身のバージョン指定になります。
自身のアプリケーションが別バージョンで動作する場合はここを"0.2"などに変えることで、異なるバージョンで混在しないような実装ができます。

個々のコールバック関数について

Photon.MonoBehaviourの派生クラスになることによって、
OnJoinedLobby/OnPhotonRandomJoinFailed/OnJoinedRoomというコールバックの関数が追加されています。

OnJoinedLobbyは、Master ServerのLobbyに接続されたときに呼ばれます。
OnPhotonRandomJoinFailedは、ランダムにRoomに入った際に失敗した(Room自身が存在しない、CCU上限を超えた)場合に呼ばれます。
OnJoinedRoomは、Roomに入る際に呼ばれます。

OnJoinedLobby内の記述

PhotonNetwork.JoinRandomRoom();

で、Lobbyに入ってきたアクセスに対して、ランダムにRoomを選んで接続します。
この処理に失敗した場合(Roomが存在しない場合)は、OnPhotonRandomJoinFailed関数がコールバックされます。

PhotonNetwork.CreateRoom("room1");

のようにすると、指定のルームを作成します。この処理に失敗した場合(すでにRoomが存在するなど)はOnPhotonCreateRoomFailed関数がコールバックされます。

OnPhotonRandomJoinFailed内の記述

PhotonNetwork.CreateRoom(null);

一番はじめにアプリを起動させた場合は、Roomは存在しませんのでOnPhotonRandomJoinFailed関数に飛びます。ここで、

PhotonNetwork.CreateRoom(null);

が呼ばれることでRoomが生成され、ここに参加することになります。

OnJoinedRoom内の記述

GameObject monster = PhotonNetwork.Instantiate("monsterprefab", Vector3.zero, Quaternion.identity, 0);
monster.GetComponent<myThirdPersonController>().isControllable = true;
myPhotonView = monster.GetComponent<PhotonView>();

Roomへの接続に成功した場合は指定のキャラクタ(prefab)をGameObjectとして複製して、PhotonViewの参照を保持しています。

現在入っているRoom名は「PhotonNetwork.room.name」で取得できます。

PhotonNetwork.Instantiateで同期を取るキャラクタのGameObjectを生成。
第一引数で指定するprefabは、Resourceフォルダのルートに配置する必要があります。

myPhotonView = monster.GetComponent<PhotonView>();

で、monsterのGameObject内のPhotonViewスクリプトの参照を保持。
PhotonViewは、メッセージを送信する(RPCもしくはOnSerializePhotonView)ために使用されます。

ここでは、サンプルで用意されているmonsterのprefabに割り当てたスクリプトで制御している箇所があるため、独自のキャラクタの同期を取る場合は別途で説明するようにします。

OnGUIは、GUI描画時に呼ばれるUnityの汎用的なコールバックになります。
この中で

PhotonNetwork.connectionStateDetailed.ToString()

は、接続時の情報を文字列で取得。

myPhotonView.RPC("Marco", PhotonTargets.All);

でRPCでメッセージを送信。
第二引数で指定した送信ターゲット(PhotonTargets.Allですべてにブロードキャスト)に対して、第一引数に指定した関数を呼ぶように送信してます。
AudioRpcというのをComponentとしてmonsterのprefabに追加しており、ここで音を鳴らしています。


AudioRpc.cs内は以下の記述。

using UnityEngine;

public class AudioRpc : Photon.MonoBehaviour {

    public AudioClip marco;
    public AudioClip polo;

    [RPC]
    void Marco() {
        if (!this.enabled) return;

        Debug.Log("Marco");

        this.audio.clip = marco;
        this.audio.Play();
    }

    [RPC]
    void Polo() {
        if (!this.enabled) return;

        Debug.Log("Polo");

        this.audio.clip = polo;
        this.audio.Play();
    }

    void OnApplicationFocus(bool focus) {
        this.enabled = focus;
    }
}

[RPC]の記述でRPCで呼び出している関数がありますね。


Unity内ではじめにすること > LobbyとRoomとPlayerの概念


最終更新時間:2014年04月27日 22時37分18秒