対戦カードゲームをunityとC#で作成しています。
前回では13枚のカードをそれぞれのプレイヤーに同じデッキから配りました。
今回は、そのカードを並び替えて役を作るために、ドラッグして手札を動かせるようにします。
例えば下記のようにストレートと2ペアを作るような並び替えを行えるようにしたいと思います。
そこで、オブジェクトのドラッグについて調べてみると、そのまま使えるスクリプトが見つかりました。
2Dゲームでオブジェクトをつかんで、ドラッグで動かして当たり判定を出す方法
当たり判定の所は使用していませんが、PrefabのCardにmouse.csと、Rigidbody2D、boxcolider2Dをつけるだけで、ドラッグして手札を動かすことが出来ます。
IsTriggerにはチェックを入れないと、カード同士がぶつかってしまうので、チェックを入れています。
それから、Gravityは0にしておかないと下にカードが落ちて行ってしまうので、Gravity Scaleの項目には0を入れています。
ここで大きな問題が二つあります。
1.対戦相手のカードも触れてしまう2.自分のカードを触っても、対戦相手にはその情報が伝わっていないので、対戦相手側のウィンドウではカードが動いているように見えない。
そこで、FPSのチュートリアルを参考にお互いのカードの情報の同期をとる方法を考えました。
isMineでdisabledされたものをenableする
まず、インスペクター上でCardPrefabのBoxCollider2DをDisabledします。これによりデフォルトではカードを触れなくなります。
次に、CardPrefabに、新しいスクリプトPlayerNetworkMover.csをアタッチします。
内容は以下のようにBoxCollider2DをEnabledしてあげます。ただし、photonView.isMineがtrueであるとき(自分のオブジェクトの場合)のみ、スクリプトを実行するようにしてあげます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerNetworkMover : Photon.MonoBehaviour { void Start () { if (photonView.isMine) { GetComponent<BoxCollider2D>().enabled = true; } } }
これによって、自分のカードは触れても、相手のカードには触れる事は出来なくなります。次は、同期のとり方をチュートリアルを見ながら考えます。
簡単にCardの位置の同期を取るには、インスペクター上で、CardPrefabのTransformをPhotonViewのObservedComponentの欄にドラッグアンドドロップしてあげればOKです。
ドラッグアンドドロップでお互いのカードの場所の同期は取れました。下のチュートリアルでは、もう一歩進めてスクリプトによる同期のとり方を説明しています。
同期のとり方
この説明を聞いてもどの様に同期を取っているのかよくわかりませんでしたが、PlayerNetworkMover.csを下記のように書き換えて、CardPrefabのPhotonViewのObservedComponentの欄にPlayerNetworkMover.csをドラッグアンドドロップしてあげれば、より滑らかに同期を取ってくれるのが確認できます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerNetworkMover : Photon.MonoBehaviour { Vector3 position; float smoothing = 1f; void Start() { if (photonView.isMine) { GetComponent<BoxCollider2D>().enabled = true; } else { StartCoroutine("UpdateData"); } } IEnumerator UpdateData() { while (true) { transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * smoothing); yield return null; } } void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.isWriting) { stream.SendNext(transform.position); } else { position = (Vector3)stream.ReceiveNext(); } } }
カードを動かすことと、お互いのカードが動いている事を確認することが出来ました。
もしよろしければ、Photonについて私が知りえる限りの情報を徹底的にまとめてみたので、下記の記事も読んで下さいね!