アマゾンバナーリンク

欠点の多いMonobitEngineをそれでも愛してる理由

2020年11月3日

こんにちは!ジェイです。今回はMonobitEngineでオンラインゲームを作っていた時に苦労した事、大変だった事、注意点などをまとめておきます。

MonobitViewを子オブジェクトに付けられない

MonobitViewはrootのゲームオブジェクトにしかアタッチすることが許されてません。しかし、エラーがでるわけではなく、MonobitEngine.MonobitNetwork.Instantiateでオブジェクトが生成されないので、原因がわかりずらいです。もし、生成されない場合は子オブジェクトにMonobitViewが追加されていないか、確認してみるといいです。ちなみにPhothonでは子オブジェクトに追加しても問題ないようです。

AwakeでMonobitEngine.MonobitNetwork.Instantiateできない

これもMonobitEngineだけですが、Awakeでは、MonobitEngine.MonobitNetwork.Instantiateでゲームオブジェクトを生成することができません。Photonではできます。

オンラインゲームならではの罠

例えば以下の様なコードがあったとします。Rigidbodyを取得してisKinematicをfalseにするという単純なコードですが、オンラインゲームで同じ様に書くと失敗します。

       GameObject go = Instantiate(Prefab);
       go.GetComponent<Rigidbody>().isKinematic = false;

・オンラインゲーム失敗例

         GameObject go = MonobitEngine.MonobitNetwork.Instantiate(Prefab.name, Vector3.zero, Quaternion.identity, 0);
         go.GetComponent<Rigidbody>().isKinematic = false;

なぜ失敗するかというと、MonobitEngine.MonobitNetwork.Instantiateでオンライン上すべてのゲームオブジェクトを生成しますが、go.GetComponent().isKinematic = false;が反映されるのは、生成したコンピューター上だけです。これに対処するには接続コールバックであるOnMonobitInstantiateを使います。

// プレハブがインスタンス化されたときに、デバッグログを出力します。
public void OnMonobitInstantiate(MonobitEngine.MonobitMessageInfo info)
{
    Debug.Log("OnMonobitInstantiate : creator name = " + info.sender.name);
    GetComponent<Rigidbody>().isKinematic = false;
}

このように書いて置ければ、MonobitEngine.MonobitNetwork.Instantiateでゲームオブジェクトが生成された時にネットワーク超しにすべてのコンピューターで同期することができます。

それとMonobitEngine.MonobitNetwork.playerNameでプレイヤー名を設定できますが、MonobitEngine.MonobitNetwork.ConnectServerで接続する前でないとできません。これもPhotonにはない罠なので注意です。

さらにAnimatorでのTriggerにもMonobitEngineだけ対応してませんので注意しましょう。

GetRoomDateが呼ばれない

SceneManager.LoadSceneでシーンまたぐとMonobitNetwork.GetRoomData()でルーム情報を取得できないことがあったので、公式の開発サイトに質問したら、以下のような回答がきました。

その他にもOnReceivaRoomListUpdateが呼ばれなくて、以下のようなコードを書いてなんとかしたりしました。

RoomData[] _RoomData;
int PrevRoomLength = -1;
private void Update()
{
    if (!MonobitNetwork.isConnect && !MonobitNetwork.inLobby && MonobitNetwork.inRoom) return;
    _RoomData = MonobitEngine.MonobitNetwork.GetRoomData();
    if (_RoomData == null) return;
    if (PrevRoomLength == _RoomData.Length) return;
    PrevRoomLength = _RoomData.Length;
    DestroyChildObject(RoomParent.transform);   //RoomElementを削除
    GetRooms();
}
public void GetRooms()
{                         
    //ルームがあればRoomElementでそれぞれのルーム情報を表示
    for (int i = 0; i < _RoomData.Length; i++)
    {
        Debug.Log(_RoomData[i].name + " : " + _RoomData[i].name + "–" + _RoomData[i].playerCount + " / " + _RoomData[i].maxPlayers /*+ roomInfo[i].CustomProperties["roomCreator"].ToString()*/);

        //ルーム情報表示用RoomElementを生成
        GameObject RoomElement = GameObject.Instantiate(RoomElementPrefab);

        //RoomElementをcontentの子オブジェクトとしてセット    
        RoomElement.transform.SetParent(RoomParent.transform);
        //RoomElementにルーム情報をセット
        CRoomElementScript re = RoomElement.GetComponent<CRoomElementScript>();
        if (re != null)
        {
            re.SetRoomInfo(
                _RoomData[i].name,
                _RoomData[i].playerCount,
                _RoomData[i].maxPlayers,
                "Test");
                //room_data[i].customParameters["RoomCreator"].ToString());
        }
    }
}

それでもMonobitEngineを使う理由

以前に書きましたが、PhotonCloudにはメッセージ数の制限があります。

しかし、MonobitEngineにはこのメッセージ数の制限がないのです!これがMonobitEngineを使う最大の理由です

逆にこの制限が気にならない場合はMonobitEngineには違う制約が多いので、PhotonCloudを使うことをおススメします。