Photonでヒエラルキー上のインスタンスを同期する

木内智史之介(シャッチョー)
ミンカさんけっこんしてくださいおねがいします(ズザー
SEGAさん、DIVAの筐体ください(ズザー

ブリーフィング

前回まで

Photonでルームに参加しているメンバーの一覧を出してみる

前回は、ルームに参加しているメンバー名を表示して、他プレイヤーの存在を把握できるところまで実装しました。
今回はもう一歩踏み込んで、お互いの画面上のインスタンスに関して同期してみたいと思います。

今回の課題

  • お互いの画面上のインスタンスを同期する
  • せっかくなのでユニティちゃんを使用してみる

さあ、行ってみましょうか。
ファイッ!

SDユニティちゃんパッケージをインポート

ダウンロード

ダウンロード

上記のURLから、パッケージデータをダウンロードして、インポートまで行ってください。
SDじゃなければAssetStoreからインストールできるんですが、SDは今のところ直接配布のみのようです。

ユニティちゃんを配置する

入室時にユニティちゃんを画面上に配置

まずは、第一歩として、ルームへのイン時に、ユニティちゃんをアバターに見立て、画面上に配置してみましょう。

今回、インスタンスを同期する所までが目標なので、この段階で PhotonNetwork.Instantiate を使用します。
PhotonNetwork.Instantiate でインスタンスを生成する場合は、対象のprefabが PhotonNetwork.PhotonViewをアタッチしておく必要性があります。

逆に、デフォルトではユニティちゃん操作用のGUIが表示されてしまうので、アタッチされているコンポーネントから「GUI」フラグをすべて解除しておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace BEFOOL.PhotonTest
{
    public class TestRoomController : MonoBehaviour
    {
        // ロカールプレイヤーが入室した際のコールバック
        public void OnJoinedRoom()
        {
            // PhotonNetwork.Instantiateは、文字列でしか対象を指定できないので、
            // Instantiateしたいprefabは、Resourcesディレクトリ配下に置く必要性があります
            avatar = PhotonNetwork.Instantiate("SD_unitychan_humanoid", Vector3.zero, new Quaternion(0, 180, 0, 0), 0);
            avatar.transform.parent = stage.transform;
        }
    }
}

ひとまず、これだけで、入室時にユニティちゃんが画面上に配置されるはずです。

うん、かわいい!

基本的な操作が可能な状態にする

つづいて、ユニティちゃんに対して基本的な操作が可能な状態にしておきましょう。

ユニティちゃんに最初からついているコンポーネントは、モーションのスイッチャーだけなので、 Photon付属のControllerと組み合わせて、ひとまずの移動と、ポーズの切り替えを可能にしたいと思います。

アタッチするコンポーネントは、下記の二つです。

myThirdPersonController

現段階では、特にデフォルトの状態からいじらないで大丈夫です。
※ただの「ThirdPersonController」も存在するのですが、今回は「myThirdPersonController」を使用してください。

Character Controller

myThirdPersonControllerコンポーネントが、このコンポーネントを求めてくるのでアタッチします。
(必要なら、Require Attribute付けておいてくれればいいのに…)

こちらは、デフォルトの設定だと、SDユニティちゃんに対して丁度いい感じになってくれなかったので、

  • Center.Y = 0.5
  • Height = 1

に変更しました。

緑の球形の枠が丁度ユニティちゃんを覆う感じになればいいはずです

現段階では、入室時にユニティちゃんが配置され、キーボード操作で位置の移動や、モーションの切り替えが可能なはずです。

他プレイヤーとのインスタンス同期

さて、ようやく今日の本題です!
Photonを通して、お互いのユニティちゃんを同期してみましょう!

追加でアタッチ/調整するコンポーネント

Network Character

ローカルインスタンスの変化をPhotonに通知するためのコンポーネントだと思われます。
PhotonViewのObserved Componentsに登録する必要性があります。

Idle Changer

コンポーネントを無効化しておきます。
有効化のままprefabになっていると、Photonを通して同期されてきたインスタンスに対しても自分のキー操作が影響を与えてしまうためです。

My Third Person Controller

「Idle Changer」と同じ理由から、Is Controllableをオフにしておきましょう。

インスタンス生成時に、Controllableを許可

このままでは、なんのキー操作も受け付けてくれないので、下記のような調整をおこないます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace BEFOOL.PhotonTest
{
    public class TestRoomController : MonoBehaviour
    {
        // ロカールプレイヤーが入室した際のコールバック
        public void OnJoinedRoom()
        {
            avatar = PhotonNetwork.Instantiate("SD_unitychan_humanoid", Vector3.zero, new Quaternion(0, 180, 0, 0), 0);
            avatar.transform.parent = stage.transform;

            // オフにされていた設定を戻す
            // この変更はPhotonを介して同期されない
            avatar.GetComponent<IdleChanger>().enabled = true;
            avatar.GetComponent<ThirdPersonController>().isControllable = true;
        }
    }
}

この状態で、2台のUnityを立ち上げて、それぞれルームに参加すると…

お互いのユニティちゃんが表示されているのではないかなと!

いいですね!しっかり同期されています。

問題点

ただ、現段階ですでにいくつか問題が発生しています。

モーションが同期されていない

位置や、傾きなどは同期してくれているようですが、どうもモーションの遷移などは同期してくれていないようです。
これは、今回アタッチした「Network Character」が変更通知を行ってくれていないからだと思われます。

次回に向けて

次回は、モーションの同期までおこなってみたいと思います。
今回はここまで。

ではでは!