Skip to content

Instantly share code, notes, and snippets.

@Luke256
Last active December 28, 2021 10:54
Show Gist options
  • Save Luke256/773af1f585c8b3a04274d05bcd663ffd to your computer and use it in GitHub Desktop.
Save Luke256/773af1f585c8b3a04274d05bcd663ffd to your computer and use it in GitHub Desktop.

Photon SDK をOpenSiv3Dで使う方法

まず、このページから、既にPhotonのセットアップは終了していることを前提にしています。

SceneMaster.hpp の作成

OpenSiv3D上でPhotonを扱うには、mak1aさんが作成したSceneMasterクラスを使用します。ここから引っ張ってきてSceneMaster.hppを作成しておきましょう。


SceneMasterの使用方法

SceneMasterの説明をする前に、一つだけ重要なことがあります。それは、OpenSiv3D側の関数には全て「s3d::」をつけるということです。そうしないと、PhotonとOpenSiv3Dの関数やクラスが衝突してしまい、大量のエラーが発生してしまいます。

では、説明に入ります。
宣言・定義は普通にSceneManagerとほとんど同じですが、引数を二つ取ります。一つ目にはPhotonのAppIDを、二つ目にはバージョンを渡しましょう。 ちなみに、SceneMasterクラスはUtility名前空間で定義されています。 もちろん、自作の構造体を使用したgetData()も使用可能です。
新しいシーンクラスを定義する時は、Utility::SceneMaster<class State>::Sceneを継承して、SceneManagerのようにupdate()draw() const、そしてコンストラクタ(ISceneの初期化も忘れずに!)を再定義(override)してください。
ここまでで、SceneMasterを使った実装をすると、こんな感じになります。

# include "SceneMaster.hpp"

using MyScene = Utility::SceneMaster<s3d::String>;

class Title : public MyScene::Scene {
private:
    // 変数の定義など
public:
    // コンストラクタ
    Title(const InitData& init_) : IScene(init_)
    {

    }

    // 更新関数
    void update() override
    {

    }

    // 描画関数(const 修飾)
    void draw() const override
    {

    }
};

void Main()
{
    MyApp manager(U"/*PhotonのAppID*/",U"1.0");
    
    manager.add<Title>(U"Title");

    while (s3d::System::Update())
    {
        if (!manager.update()) break;
    }
}

Photonとの連携

再定義できる関数

ここでようやくPhotonとの連携に入ります。
Photonへの接続はConnect()、切断はDisconnect()で可能です。
これだけでも動作はすると思いますが、動いていることは実感できないと思います。これは、エンジンであらかじめ用意されている関数を再定義してデバッグ出力をさせることをすれば解決できます。

void ConnectReturn(int errorCode, const ExitGames::Common::JString& errorString, const ExitGames::Common::JString& region, const ExitGames::Common::JString& cluster);


errorCode : 終了コード。0で正常
errorString : エラーの内容(?)
region :
cluster :
概要
Photonサーバーに接続した後に呼ばれる関数です。if (errorCode)で接続が正常に行われたかが確認できます。


void DisconnectReturn();


概要
Photonサーバーから切断した問に呼ばれる関数です。


void JoinRandomRoomReturn(int localPlayerNr, const ExitGames::Common::Hashtable& roomProperties, const ExitGames::Common::Hashtable& playerProperties, int errorCode, const ExitGames::Common::JString& errorString);


localPlayerNr :
roomProperties : 部屋の情報(後述)
playerProperties :
errorCode : 終了コード。0で正常
errorString : エラーの内容(?)
概要
サーバーに接続後、部屋に接続した後に呼ばれる関数です。if (errorCode)で接続が正常に行われたかが確認できます。


void CreateRoomReturn(int localPlayerNr, const ExitGames::Common::Hashtable& roomProperties, const ExitGames::Common::Hashtable& playerProperties, int errorCode, const ExitGames::Common::JString& errorString);


localPlayerNr :
roomProperties : 部屋の情報(後述)
playerProperties :
errorCode : 終了コード。0で正常
errorString : エラーの内容(?)
概要
部屋を新しく作成した後に呼ばれる関数です。if (errorCode)で作成が正常に行われたかが確認できます。


void JoinRoomEventAction(int playerNr, const ExitGames::Common::JVector& playernrs, const ExitGames::LoadBalancing::Player& player);


playerNr :
playernrs :
player : プレイヤーの情報
概要
誰かが新しく部屋に接続してきたときに呼ばれる関数です。


void LeaveRoomEventAction(int playerNr, bool isInactive)


playerNr :
isInactive :
概要
誰かが部屋から切断したときに呼ばれる関数です。


void CustomEventAction(int playerNr, nByte eventCode, const ExitGames::Common::Object& eventContent);


playerNr :
eventCode:イベントの種類(整数)
eventContent:イベントの情報
何らかのイベントを受け取ったときに呼ばれる関数です。
ExitGames::Common::ValueObject<ExitGames::Common::Dictionary<nByte,int32>>(eventContent).getDataCopy()のようにすると、送られてきたイベントの情報のポインタのハッシュテーブルが得られ、.getValue(const EKeyType& key)でインデックスkeyに格納された値のポインタが取得できます。

// CustomEventAction関数内

// 受け取った情報を変換
auto dic = ExitGames::Common::ValueObject<ExitGames::Common::Dictionary<nByte,int32>>(eventContent).getDataCopy();

// データの取り出し(キー:1)
auto Data = *dic.getValue(1);

void OnMasterClientChanged(int id, int oldID);

id : 新しいホストのID   oldID : これまでのホストのID   概要
部屋のホストが交代したとき、つまりホストが退出したときに呼ばれる関数です。


これらにデバッグ出力などを実装してあげると、いい感じに動いてくれるはずです。


roomPropertiesについて

roomPropertiesExitGames::Common::Hashtableの、部屋の情報を格納したハッシュテーブルです。これを使用することで、同じサーバー内でも複数種類の部屋の識別ができるようになります。


その他使用する関数

以下に、Photonを使用するときに必要になってくる関数をあげておきます。これらの関数に再定義は不要です。

void Connect();


Photonのサーバーに接続します。接続の処理が終わるとConnectReturn関数が呼ばれます。


void CreateRoom(const ExitGames::Common::JString& roomName_, const ExitGames::Common::Hashtable& properties_, const nByte maxPlayers_);


概要
新しく部屋を作成します。
roomName_ : 作成する部屋の名前
properties_ : 部屋の情報
maxPlayers_ : プレイヤーの最大数


void Disconnect();


サーバーから切断します


bool IsConnectingPhoton() const;


概要
Photonサーバーに接続していればtrue、接続していなければfalseを返します。


クライアント関係

クライアントの情報はgetClient()で取得できます。以下に挙げているのは、そのメンバ関数です

bool opJoinRandomRoom(const Common::Hashtable& customRoomProperties=Common::Hashtable(), nByte maxPlayers=0, nByte matchmakingMode=MatchmakingMode::FILL_ROOM, const Common::JString& lobbyName=Common::JString(), nByte lobbyType=LobbyType::DEFAULT, const Common::JString& sqlLobbyFilter=Common::JString(), const Common::JVector<Common::JString>& expectedUsers=Common::JVector<Common::JString>());


概要
ランダムに部屋に接続します。見ての通り、一応何も引数を取らなくても動作はします。
customRoomProperties : 部屋の情報
maxPlayers : プレイヤーの最大数
matchmakingMode :
lobbyName :
lobbyType :
sqlLobbyFilter :
expectedUsers :


MutablePlayer& getLocalPlayer(void);


概要
クライアントのプレイヤー情報を取得します。


void fetchServerTimestamp(void);


サーバーのタイムスタンプを取得しそうですが、SceneMasterのデフォルトだと何もしません。


bool Client::opRaiseEvent(bool reliable, const Ftype& parameters, nByte eventCode, const RaiseEventOptions& options);


概要
イベントを送ります(後述)
reliable :
parameters : 送る情報 eventCode : イベントコード options : オプション(省略可)


イベントの送出方法

イベントを送る時は、Photonで用意されている、ExitGames::Common::Dictionary<EKeyType, EValueType>を使います。これは、EKeyTypeをキー(の型)、EValueTypeを要素(の型)としたハッシュテーブルとして扱います。これにデータを追加する時はput(const EKeyType& key, const EValueType& val)を使います。引数の名前を見てもわかる通り、この関数は第一引数にキー、第二引数に要素を取ります。 そして最後、データの作成が終わり、データを送る時は、GetClient().opRaiseEvent(bool reliable, const Ftype& parameters, nByte eventCode, const RaiseEventOptions& options=RaiseEventOptions());を使用します。第二引数に送る情報、第三引数にイベントコード(イベントの種類)を渡します。第4引数は省略可能です。(第一引数「reliable(=信頼性)」、どういう意味なのか...とりあえずtrueを渡してください。) 少しまとめると、イベントの送信は以下のようになります。

// イベントを送信したいところ

// 送信用ハッシュテーブルの作成
ExitGames::Common::Dictionary<nByte, int32> dic;

// 情報の追加
dic.put(1, 100);
                
// 送信
GetClient().opRaiseEvent(true, dic, 1);

サンプル集

最後に、実際にPhotonを使ったサンプルへのリンクを載せておきます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment