Help us understand the problem. What is going on with this article?

【Photon Unity Network】ルームのカスタムプロパティをちょこっと解説

記事の環境

Unity 2019.1.0f2
Photon Unity Network(バージョン1.97)

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

端的に説明すると、ルーム内で共有できるハッシュテーブルです。

(注:ハッシュテーブルとはC#で言うDictionaryのこと)

使い方

RoomPropertyTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RoomPropertyTest : MonoBehaviour
{
    // ハッシュテーブルを宣言
    ExitGames.Client.Photon.Hashtable roomHash;

    // ローカルで使っているハッシュをルームにセット
    public void SetRoomProperty()
    {
        // ハッシュに要素を追加(同じ名前があるとエラーになる)
        roomHash.Add("hoge", 0);

        // ハッシュに要素を追加、既に同じ名前のキーがあれば上書き
        roomHash["hoge"] = 1;

        // ルームにハッシュを送信する
        PhotonNetwork.room.SetCustomProperties(roomHash);
    }

    // ルームのハッシュが送信されたら、送信されたハッシュが入ってくる(Photonの機能で戻り値の型、関数名、引数を一致させると勝手に呼ばれる)
    public void OnPhotonCustomRoomPropertiesChanged(ExitGames.Client.Photon.Hashtable changedRoomHash)
    {
        // 変更されたハッシュを受け取る
        roomHash = changedRoomHash;
    }
}

説明

// ハッシュテーブルを宣言
ExitGames.Client.Photon.Hashtable roomHash;

【ExitGames.Client.Photon】とネームスペースから記述しているのはC#にもともとあるHashtableと区別するためです。

public void SetRoomProperty()
{
    // ハッシュに要素を追加(同じ名前があるとエラーになる)
    roomHash.Add("hoge", 0);

    // ハッシュに要素を追加、既に同じ名前のキーがあれば上書き
    roomHash["hoge"] = 1;

    // ルームにハッシュを送信する
    PhotonNetwork.room.SetCustomProperties(roomHash);
}

次にSetRoomProperty関数ですが、これはまぁそのままですね。

このHashtableはDictionaryクラスをまんま継承しているので使い方はDictionaryとなにも変わりません。

唯一目新しいのはこの部分でしょうか

// ルームにハッシュを送信する
PhotonNetwork.room.SetCustomProperties(roomHash);

ここでPhotonの機能を使っています。

ローカルで中身を変更したHashtableを現在自分がいるルームに送信しています。

// ルームのハッシュが送信されたら、送信されたハッシュが入ってくる(Photonの機能で戻り値の型、関数名、引数を一致させると勝手に呼ばれる)
public void OnPhotonCustomRoomPropertiesChanged(ExitGames.Client.Photon.Hashtable changedRoomHash)
{
    // 変更されたハッシュを受け取る
    roomHash = changedRoomHash;
}

最後にOnPhotonCustomRoomPropertiesChanged関数です。

この関数はPhotonが用意している関数でコメントの通り戻り値の型、関数名、引数を一致させると呼ばれます。

Unityのスクリプティングランタイムとはまた少し違った仕組みなのですが、見た目上は完全に同じようなものです

呼ばれるタイミングはルームに新しくハッシュが送信された時です。

以下、流れです。
RoomPropertyのフロー図.png

諸注意

ルームプロパティはルームに設定するプロパティなので、ルームに入ってからセットしないとエラーが出ます。

またPhotonのターンを制御する機能としてPunTurnManagerがありますが、その制御方法にルームプロパティを使っているので新しく値をルームプロパティに設定しようとするとPunTurnManagerクラスを拡張する必要が出てきます。(これは公式のリファレンスにもちょろっと書いてあったと思います)
値を新しく設定する必要があるのであれば独自でターン制御を作ったほうが手っ取り早いかもしれません。

ラッパークラス

毎回プロパティを使うたびに長い関数を書くのは正直しんどいのでラッパークラスを作ることをおすすめします。

一応例を載せさせていただきます。

PhotonProperty.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhotonProperty : MonoBehaviour
{
    // ルームプロパティ用のハッシュ(Dictionary)
    private static ExitGames.Client.Photon.Hashtable roomHash;

    private void Start()
    {
        // ルームプロパティ用のこのプレイヤーのハッシュ(Dictionary)を生成
        roomHash = new ExitGames.Client.Photon.Hashtable();
    }

    // ルームプロパティ ===========================================

    // RoomPropertyが更新された時に呼ばれる
    public void OnPhotonCustomRoomPropertiesChanged(ExitGames.Client.Photon.Hashtable changedRoomHash)
    {
        // 更新したプレイヤーが保持しているハッシュを入れる
        roomHash = changedRoomHash;
    }

    // ルームプロパティのセット -----------------------------------
    // キーが既に存在していたら上書き
    public static void SetRoomProperty<T>(string key, T value)
    {
        roomHash[key] = value;

        // 自身のハッシュをネット上に送信
        PhotonNetwork.room.SetCustomProperties(roomHash);
    }

    // 一次元配列用
    public static void SetRoomPropertyArray<T>(string key, T[] value)
    {
        // 要素数256を超える場合はここをshortなどに変更してください
        for(byte i = 0; i < value.Length; i++)
        {
            roomHash[key + i] = value[i];
        }

        // 自身のハッシュをネット上に送信
        PhotonNetwork.room.SetCustomProperties(roomHash);
    }

    public static void SetRoomPropertyArray<T>(string key, byte arrayNum, T value)
    {
        roomHash[key + arrayNum] = value;

        // 自身のハッシュをネット上に送信
        PhotonNetwork.room.SetCustomProperties(roomHash);
    }

    // キーが既に存在している場合エラーが出る
    public static void SetRoomPropertyAdd<T>(string key, T value)
    {
        roomHash.Add(key, value);

        // 自身のハッシュをネット上に送信
        PhotonNetwork.room.SetCustomProperties(roomHash);
    }

    // ルームプロパティをゲット -----------------------------------
    public static T GetRoomProperty<T>(string key)
    {
        // outを受け取るための変数を用意
        object value;

        // 指定したキーがあれば返す
        if (roomHash.TryGetValue(key, out value))
        {
            // ボックス化解除
            return (T)value;
        }

        // 無かったらnullが返る
        return (T)value;
    }

    // 一次元配列用
    public static T GetRoomPropertyArray<T>(string key, byte arrayNum)
    {
        // outを受け取るための変数を用意
        object value;

        // 指定したキーがあれば返す
        if(roomHash.TryGetValue(key + arrayNum, out value))
        {
            // ボックス化解除
            return (T)value;
        }

        return (T)value;
    }
    // ============================================================
}

以下それぞれの関数の使い方をまとめました

        // 値の設定方法
        // ===============================================================
        // hogeというキーで0をセット
        PhotonProperty.SetRoomProperty("hoge", 0);

        // 一次元配列を作成
        int[] array = { 0, 1, 2, 3 };
        // arrayというキーでarray配列をセット
        PhotonProperty.SetRoomPropertyArray("array", array);
        // ===============================================================

        // 値の取得方法
        // ===============================================================
        // 戻り値の型をint型に指定してキーを入力
        int hoge = PhotonProperty.GetRoomProperty<int>("hoge");

        // 戻り値の型をint型に指定してキーと取得したい要素番号を入力
        int fuga = PhotonProperty.GetRoomPropertyArray<int>("array", 0);
        // ===============================================================

良ければお使いください。

参考サイト

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

suittizihou
東京の専門学校でゲームプログラミングをしております。 最近DirectXを触り始めました。 絶賛就活中の模様。。。 MonoGame/DxLib/Unityなどを触ったことがあります。 C#/Java/VC++/JavaScript/HTMLを触ったことがあります。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした