うら干物書き

ゲームを作っています。

【Unity】僕もPhotonを使いたい #11 カスタムプロパティ

 さて、今までいろいろとPhotonの同期を取る方法を調べてきました。
 今回は同期を取る方法としてカスタムプロパティを調査しました。
 カスタムプロパティはハッシュテーブル方式でルームとプレイヤーに設定することが出来ます。

 今回のカスタムプロパティがPhotonで同期を取ってみようシリーズの最終回になります。


この記事にはUnity5.4.1f1及びPUN1.75を使用しています。

カスタムプロパティ

 Photonで同期する方法はいろいろありました。

https://doc.photonengine.com/ja-jp/pun/current/tutorials/synchronization-and-statedoc.photonengine.com

 カスタムプロパティはハッシュテーブルとしてルームとプレイヤーに設定できます。
Photon Unity Networking: Room Class Reference
Photon Unity Networking: PhotonPlayer Class Reference

 カスタムプロパティの一番の魅力は、ルームとプレイヤーという既に用意されたクラスにデータを設定できるという点です。
 設定方法も簡単で、SetCustomProperties()という関数に設定したいハッシュテーブルを渡してあげるだけ。
 変更の受信も簡単です。
 OnJoinedRoom()などのPhotonイベント取得用関数と同じ方式で受信できるため、関数名と引数の型があっていれば、どんなコンポーネントでも取得できます。
 Photonの公式ブログでも使い方が紹介されていました。

blog.photoncloud.jp

 ではルームとプレイヤーに分けて、カスタムプロパティを設定してみましょう。

ルームのカスタムプロパティ

 現在プレイヤーがいるルーム情報はPhotonNetwork.roomのプロパティで取得できます。
 あとはSetCustomProperties()関数に設定した情報を追加したハッシュテーブルを渡してあげればOKです。
Photon Unity Networking: Room Class Reference

 受信する際の関数はOnPhotonCustomRoomPropertiesChanged()です。

void OnPhotonCustomRoomPropertiesChanged( Hashtable propertiesThatChanged )
 Photon Unity Networking: Photon.PunBehaviour Class Reference
 引数のpropertiesThatChangedに設定された情報がハッシュテーブルとして入っています。

 以下がルームのカスタムプロパティの設定のサンプルスクリプトです。
 文字列とプレイヤーのIDを設定しています。

using UnityEngine;
using UnityEngine.UI;

public class DemoObject : MonoBehaviour
{
    [SerializeField]
    private Text    m_strategy  = null;

    private Color[] PLAYER_COLOR    = new Color[] { Color.white, Color.red, Color.green, Color.blue, Color.yellow };

    public void SetRoomStrategy( string i_strategy )
    {
        var properties  = new ExitGames.Client.Photon.Hashtable();
        properties.Add( "Strategy", i_strategy );
        properties.Add( "Sender", PhotonNetwork.player.ID );

        PhotonNetwork.room.SetCustomProperties( properties );
    }

    public void OnPhotonCustomRoomPropertiesChanged( ExitGames.Client.Photon.Hashtable i_propertiesThatChanged )
    {
        {
            object value = null;
            if( i_propertiesThatChanged.TryGetValue( "Strategy", out value ) )
            {
                m_strategy.text     = (string)value;
            }

        }

        {
            object value = null;
            if( i_propertiesThatChanged.TryGetValue( "Sender", out value ) )
            {
                m_strategy.color    = PLAYER_COLOR[ (int)value ];
            }

        }
    }
} // class DemoObject

f:id:urahimono:20160924010250g:plain

プレイヤーのカスタムプロパティ

 自分自身のプレイヤー情報は、PhotonNetwork.playerプロパティから取得できます。
 ルーム同様、SetCustomProperties()関数があるので同じように使えます。
Photon Unity Networking: PhotonPlayer Class Reference

 受信する際の関数はOnPhotonPlayerPropertiesChanged()です。

void OnPhotonPlayerPropertiesChanged( object[] playerAndUpdatedProps )
 Photon Unity Networking: Photon.PunBehaviour Class Reference
 引数がobjectの配列で来ているため、パッと見で使い方が分かりにくそうですが、配列に入っている情報は必ず以下の作りになっています。

  • [0] には影響を受けたPhotonPlayerの情報が入っています。
  • [1] は変更されたプロパティのハッシュテーブルが入っています。

 そのため必ずキャストして使う必要があります。

 以下がプレイヤーのカスタムプロパティの設定のサンプルスクリプトです。
 プレイヤーのカラーのインデックスを設定しています。

using UnityEngine;
using System.Linq;

public class DemoObject : MonoBehaviour
{
    private Color[] PLAYER_COLOR    = new Color[] { Color.white, Color.red, Color.green, Color.blue, Color.yellow };

    public void SetPlayerColor( int i_colorIndex )
    {
        var properties  = new ExitGames.Client.Photon.Hashtable();
        properties.Add( "Color", i_colorIndex );

        PhotonNetwork.player.SetCustomProperties( properties );
    }

    public void OnPhotonPlayerPropertiesChanged( object[] i_playerAndUpdatedProps )
    {
        var player      = i_playerAndUpdatedProps[ 0 ] as PhotonPlayer;
        var properties  = i_playerAndUpdatedProps[ 1 ] as ExitGames.Client.Photon.Hashtable;


        object colorValue   = null;
        if( properties.TryGetValue( "Color", out colorValue ) )
        {
            int colorIndex  = (int)colorValue;

            // ゲーム上のPlayer用のオブジェクトの中からPhotonViewのIDが変更したPlayerと同じオブジェクトの色を変更する。
            var playerObjects   = GameObject.FindGameObjectsWithTag( "Player" );
            var playerObject    = playerObjects.FirstOrDefault( obj => obj.GetComponent<PhotonView>().ownerId == player.ID );
            playerObject.GetComponent<Renderer>().material.color = PLAYER_COLOR[ colorIndex ];
            return;
        }
    }
} // class DemoObject

f:id:urahimono:20160924010251g:plain

おまけ ハッシュテーブルのキー

 以下のリンクの「高度なマッチメイキングとRoomプロパティ」の項目に以下のような記述があります。

Photon Unity Networking: 基本説明

Roomプロパティは、Roomにいるプレイヤーすべてで同期されます。
それは現在のマップ、ラウンド、開始時間などを把握するのに役立ちます。
文字列をキー(短いキーが望ましい)にしたハッシュテーブルとして扱います。

 ハッシュテーブルのキーは短い方がいいみたいですね。
 キーを見てなんの情報がわかる範囲で短くしてみてはいかがでしょうか。

 さて、Photonの使い方について11回に渡って調査してきました。
 次回から調べた情報を元に簡単なゲームを作っていきたいと思います。

 次回 www.urablog.xyz

 前回 www.urablog.xyz