【第04日目】UnityとPUN2による互いのキャラの位置同期とチャットの両立

 

今回は、UnityとPHOTONによる3Dゲームテスト環境の実装の準備をしようと思います。

一度にたくさんの事をやろうとすると、パニックになってしまうので、スモールステップで始めます。

 

今日はまず、チャットする時の首振りを止める、他のプレイヤーを見れるようにするの二本立てとします。

 

それでは、まずは、チャット時の首振りを止めるところから参りましょう。

 

PHOTONチャット時に見回してしまう挙動を止める

現状では、マウスのカーソルの位置情報をもとにカメラのアングルがかわってしまうので、

名前を入れる時などに、カーソルを中心に合わせようとすると、視点が変わってしまっていました。

いちいちタイプするたびにカーソルを移動させる必要があるので、そのたびに視点が変わると不都合です。

 

よって、視点の移動はマウスのドラッグを検知して移動するようにして、それ以外の場合は視点を動かさないようにする仕様に変えたいと思います。

MouseLook.csのLookRotationメソッドを見ると、”Mouse X””Mouse Y”を検知しているのが分かります。

これをIF文でかこってあげて、マウスボタンが押されている場合のみ機能するようにしてしまいます。

 

これで、マウスドラッグの時のみ、首振りをするようになるのでチャットに集中しやすくなりました。

 

PHOTONで他のプレイヤーを見れるようにする

まずは、他のプレイヤーを見れるようにするためには、部屋に入る必要がありそうなので、

PUN2のこのウェブサイトを参考にして、NetworkManagerなるものを作成してゲームオブジェクトにアタッチしておきます。

内容は以下のように書きました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class NetworkManager : MonoBehaviourPunCallbacks
{
    [SerializeField] Transform spawnPoint;
    private void Start()
    {
        // PhotonServerSettingsの設定内容を使ってマスターサーバーへ接続する
        PhotonNetwork.ConnectUsingSettings();
    }

    // マスターサーバーへの接続が成功した時に呼ばれるコールバック
    public override void OnConnectedToMaster()
    {
        // "Room"という名前のルームに参加する(ルームが存在しなければ作成して参加する)
        PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default);
    }

    // ゲームサーバーへの接続が成功した時に呼ばれるコールバック
    public override void OnJoinedRoom()
    {
        GameObject cardCopy = (GameObject)PhotonNetwork.Instantiate("FPSController", spawnPoint.position, spawnPoint.rotation, 0);
    }
}

 

アタッチするオブジェクトは今回はScriptと書いてある、ChatGui.csがくっついている物にしました。

SpawnPointに初期位置のオブジェクトをドラッグアンドドロップします。

初期位置としてReflectionProbeを置いたので、それを今回は使用しています。

 

先ほどのコードの26行目で、ルームに接続されたら、PrefabがInstantiateされる仕組みになっています。

このPrefabとは何かというと、前回作成したFirstPersonControllerをドラッグアンドドロップで、PhotonのResourceフォルダにPrefab化したものです。

元のヒエラルキービューにあったFirstPersonControllerはプレファブ化してから消してしまいます。

そして、このプレファブにはPhotonViewというスクリプトを付けておきます。

Photonではこれが無いと動きません。

それに加えて、PhotonTransformViewというスクリプトもつけます。

これは互いのインスタンシエートされたオブジェクトの同期を取るためのスクリプトになります。

PhotonViewのObservedComponentにPhotonTransformViewが入っていることを確かめます。

 

入っていない場合は自分で追加する必要があります。

これでオブジェクトの準備はできたのですが、この時点では、

自分のオブジェクトと相手のオブジェクトを区別できないため、

キー入力やマウスを動かしたときに、両方のFirstPersonControllerが動いてしまいます。

PHOTONにおけるIsMineで動作を自分のオブジェクトに限定する

そこで利用するのが、PhotonView のIsMineのbool値です。

もし、PhotonViewのIsMineがtrueであれば(自分のオブジェクトであれば)それは動かし、

そうでなければ、動かさないという処理を書き加えてあげる必要があります。

 

上の動画(英語)で詳しくは解説してあるのでご参考まで。

まずはPhton.PunをUsingに加えてPHOTONが使えるようにします。

 

そして、一番最初にPVを定義しておきます。

続いて、AwakeでPhotonView(PV)を取得します。

他人のFirstPersonControllerのカメラや、リジッドボディがあるとダブってしまうので、Destroyで削除してしまいます。

これで、自分のオブジェクトと他人のオブジェクトがはっきりとしました。

ただし、まだ、これではキーの入力を両方とも受け付けてしまいます。

 

よって、今度は動きを規定しているUpdateとFixedUpdateにIF文を差し込んで、自分のオブジェクトの場合のみ動くというように書き換えます。

else内が元の記載されているFirstPersonControllerの原文です。それをIF文でPV.IsMineがFalseの時は行わないようにしてしまいます。

続いてFixedUpdateでも、同様にします。

これで完全に、キー入力が自分のオブジェクトにしか効かなくなるはずです。

お互いの位置の同期と、コントロールを分ける事が出来ました。

試しにビルドして2人のキャラクターを同じ空間で試してみると別々に動きます。

おわりに

これでとりあえず、同じ空間に入って会話をするというのが、技術的に可能になりました。

一つ大きなハードルを越える事が出来たのではないでしょうか。

今後はこの中でゲームをするという事に挑戦したいと思っていますが、できるかどうかはわかりません。

これからも頑張っていきますので、どうぞよろしく応援頂けますと幸いです。

ではでは

 

 

おすすめの記事