Unity Photon(PUN+) の使い方 オブジェクト位置同期編(4/5)
途中でアーバンチャンピオンを作ろうネタを挟んでしまったため、ご無沙汰になってしまい申し訳ありません。
以前はPhotonのロビー・ルーム作成・ルーム入室について解説しました。
sleepnel.hatenablog.com
今回はUnity Photon(PUN+) オブジェクト位置同期のやり方を説明します。
Photonの公式ブログも参考になりますので、ぜひご覧になってはいかがでしょう。
blog.photoncloud.jp
blog.photoncloud.jp
さて、ここからは私なりの説明をしていきたいと思います。
PhotonではオブジェクトにPhotonViewというコンポーネントをつけ、
そのオブジェクトの位置情報をルーム間でやり取りして同期を行います。
同期するオブジェクトにPhotonViewをつけます。
Observed Componentsに自分自身のTransformをドラッグにしてTransformをセットします。
このままだと動きがあまりないのでRigidbodyもつけておきましょう。
できたらAssets/Resoucesフォルダを作って、そこにCubeオブジェクトをドラッグしてPrefab化します。
(あとでPhotonNetwork.Instantiateするための準備です)
ルーム内でPhoton.Instantiateすれば同期が始まります。
では同期オブジェクトを作りましょう。
ルームに入ったら作成しますので、PhotonManagerのOnJoinedRoom内でやりましょう。
同期オブジェクトを作成するには
PhotonNetwork.Instantiate (Prefab名, 初期位置,角度,グループNo)
です。グループNoはまだちょっと使ったことがないのでわからないのですが、とりあえず0にしておきます。
private GameObject cube; //ルーム入室した時に呼ばれるコールバックメソッド void OnJoinedRoom() { Debug.Log ("PhotonManager OnJoinedRoom"); GameObject.Find("StatusText").GetComponent<Text>().text = "OnJoinedRoom"; Vector3 initPos = new Vector3 (6.34f, 3f, 7.17f); cube = PhotonNetwork.Instantiate ("Cube", initPos, Quaternion.Euler(Vector3.zero),0); }
ステージにCubeが出てきましたね。
後から別端末で部屋に入ってみましょう。
photon 他ユーザがinstanciateしたオブジェクトが出てきた https://t.co/9Vq2os8654
— pouhiro@SleepNel (@pouhiroshi) June 9, 2016
先にいたプレイヤーのCubeも見えるし、自分が作ったCubeもステージ上に登場しました。
では自分が作ったオブジェクトを動かして、別端末でちゃんと動くか確認してみましょう。
photon 普通にtransformによる位置同期 https://t.co/a538sh7atL
— pouhiro@SleepNel (@pouhiroshi) June 9, 2016
PC上で動かしたものが、端末側で動いて見えるのが確認できました。
でもちょっとカクツキが激しいですね。
そんなときは同期オブジェクトにPhoton Transform Viewを追加し、
PhotonViewでObserved Componentsで監視させます。
PhotonTransformViewを使った位置同期 https://t.co/EJaPTRj0Bh
— pouhiro@SleepNel (@pouhiroshi) June 9, 2016
ちょっとスムーズになりましたね。
さらにスムーズにするために、オブジェクトのVelocity(速度情報)を同期するという技があります。
PhotonTransformViewのInterpolateOption,ExtrapolateOptionをSynchronize Valuesにします。
これによって後述のphotonTransformView.SetSynchronizedValuesによるVelocityによる位置同期になります。
さらに位置情報を同期するScriptを作り(ここではCubeScriptとします)ます。
CubeScriptは以下のように書きます。
using UnityEngine; using System.Collections; public class CubeScript : Photon.MonoBehaviour { private PhotonView photonView; private PhotonTransformView photonTransformView; // Use this for initialization void Start () { photonTransformView = GetComponent<PhotonTransformView>(); photonView = PhotonView.Get(this); } // Update is called once per frame void Update () { if (photonView.isMine) { //現在の移動速度 Vector3 velocity = gameObject.GetComponent<Rigidbody> ().velocity; //移動速度を指定 photonTransformView.SetSynchronizedValues (velocity, 0); } } }
現在の移動速度をRigidbodyのvelocityで取得し、
Vector3 velocity = gameObject.GetComponent
PhotonTransformViewに移動速度をセットしてあげます。
photonTransformView.SetSynchronizedValues (velocity, 0);
if (photonView.isMine) { が大事で自分が所有しているオブジェクトじゃないとこれは使えないようでisMineでないものに対してSetしようとするとエラーが出るようです。
では、これで実行してみましょう!!
Photon SynchronizedValuesでVelocity同期 https://t.co/kcuVHYgRmW
— pouhiro@SleepNel (@pouhiroshi) June 9, 2016
少し飛んだ部分がありますが、かなりスムーズに動くようになりました!
この技はCubeの位置情報を同期するのではなく、Velocity(移動速度)を同期することで、カクツキを補完するやり方です。
DodgeWarsもこの方法を使ってボール位置の同期を行っています。
あまりオブジェクトが激しく動き回らないゲームの時(Turnbased ユーザが順番に操作を行うカードゲームみたいなやつ)は、普通にTransformやPhotonTransformViewの同期をすれば十分です。
DodgeWarsのように同期オブジェクトが激しく動き回るようなゲームの場合は、最後に紹介したVelocity同期をお勧めします。
次回は、オブジェクト以外の変数同期方法について解説したいと思います。
PUN+はこちらで購入できます!
ではでは、良いインディー開発ライフを!