前回までのスクリプトではチップをDestroyした時に、相手側からその動きが見えていませんでした。今回はその同期の取り方と、チップのカウントの仕方について考えました。
まずは同期の取り方ですが、下のサイトに凄く詳しくのっていたので、それを参考にスクリプトを書いてみました。
【Unity】僕もPhotonを使いたい #08 RPC() PhotonTargets編
私が説明する余地がないくらい詳細の解説が載っているので、説明は割愛します。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class ChipCreate : MonoBehaviour, IPointerClickHandler { ChipCalculator chipCalculator; Vector3 temp; Vector3 position; private PhotonView m_photonView = null; //RPCを使うときに書き加える void Awake() { m_photonView = GetComponent<PhotonView>();//RPCを使うときに書き加える } public void OnPointerClick(PointerEventData eventData) { if (eventData.clickCount > 1) { temp = this.transform.position; GameObject pokerchip = (GameObject)PhotonNetwork.Instantiate("pokerchip2", temp, Quaternion.identity, 0); m_photonView.RPC("DestroyChip", PhotonTargets.All);//RPCを実行 } } [PunRPC] //RPC本体 private void DestroyChip() { Destroy(gameObject); } }
これで、Destroyが実行されると、双方のプレイヤー画面で実行されることが確認できました。
次に、チップのカウントです。まずは立面のチップにタグをつけました。タグ付けされているチップをカウントしています。
通常では相手のチップまで一緒にカウントしてしまうため、IsMineを使って自分のチップのみタグを残し、自分のウィンドウの相手のチップのタグは全部Untaggedにしてしまいます。
void Start() { if (photonView.isMine != true) { GetComponent<Chipcreate2>().enabled = false; gameObject.tag = "Untagged"; } }
これによって、チップのカウントをする準備ができました。
チップのカウントはChipCalculator.csにまとめてあります。
まず部屋に入ったら現在のチップを表示する必要があるので、初期値をRoomCustomPropertyに送り、Screenにも代入して、現在の点数をテキストで表示します。
次に、void Updateの中で常にチップの枚数をタグを用いて監視し、それが、現在表示されている点数と違う場合のみ、データをRoomCustomPropertyに送り、現在の点数をテキストで書き直します。
プレイヤー1の場合と2の場合と別々のパターンを想定してデータの送受信を行っています。
void OnJoinedroom()//部屋に入ったら下記を実行 { //room.custom.propertiesにチップの枚数を送る var properties = new ExitGames.Client.Photon.Hashtable(); properties.Add(PhotonNetwork.player.ID + "pokerpoint", pokerpoint); PhotonNetwork.room.SetCustomProperties(properties); screen = pokerpoint + "point"; //現在のscreenのstring } void Update() { tagObjects100 = GameObject.FindGameObjectsWithTag("Hozchip100");//100チップを数える tagObjects500 = GameObject.FindGameObjectsWithTag("Hozchip500");//500チップを数える pokerpoint = tagObjects100.Length * 100 + tagObjects500.Length * 500;//描画されているチップの枚数 tempscreen = pokerpoint + "point";//新しいscreenのstring if (screen != tempscreen)//現在のscreenと新しいscreenに違いがあれば { if (PhotonNetwork.inRoom == true) { //データをルームプロパティに送る var properties = new ExitGames.Client.Photon.Hashtable(); properties.Add(PhotonNetwork.player.ID + "pokerpoint", pokerpoint); PhotonNetwork.room.SetCustomProperties(properties); if (PhotonNetwork.player.ID == 1) { if (PhotonNetwork.room.customProperties[2 + "pokerpoint"] != null) { opponentscreen = (int)PhotonNetwork.room.customProperties[2 + "pokerpoint"] + "point"; } } else { if (PhotonNetwork.room.customProperties[1 + "pokerpoint"] != null) { opponentscreen = (int)PhotonNetwork.room.customProperties[1 + "pokerpoint"] + "point"; } } } screen = tempscreen; } }
最初はこれだけで解決すると思ったのですが、実際にプレイしてみると、相手のチップが更新された場合に、自分も更新しない限り、データの送受信がされないという問題が起こりました。
そこで、RoomCustomPropertiesのコールバックメソッドを調べ、データが書き換えられた場合に呼ばれる関数OnPhotonCustomRoomPropertiesChangedを使用しました。
下記のサイトが参考になりました。
【Unity、PUN】Photon Unity Networkingのコールバックメソッド一覧
下記のスクリプトを足すことで、双方のプレイヤーのチップが更新されるようになりました。
これもプレイヤーが入れ替わる事を想定して書いています。
void OnPhotonCustomRoomPropertiesChanged() { if (PhotonNetwork.player.ID == 1) { if (PhotonNetwork.room.customProperties[2 + "pokerpoint"] != null) { opponentscreen = (int)PhotonNetwork.room.customProperties[2 + "pokerpoint"] + "point"; } } else { if (PhotonNetwork.room.customProperties[1 + "pokerpoint"] != null) { opponentscreen = (int)PhotonNetwork.room.customProperties[1 + "pokerpoint"] + "point"; } } }
表示するテキストも二か所用意して、入れ替わる想定でスクリプトをアタッチしてあります。
using UnityEngine; using UnityEngine.UI; public class pokepoint2 : MonoBehaviour { ChipCalculator chipCalculator; float temp; Vector3 current; void OnPhotonCustomRoomPropertiesChanged() { if (PhotonNetwork.player.ID == 1) { ChipCalculator chipCalculator = GameObject.Find("ChipCalc").GetComponent<ChipCalculator>(); this.GetComponent<Text>().text = chipCalculator.opponentscreen; } else { ChipCalculator chipCalculator = GameObject.Find("ChipCalc").GetComponent<ChipCalculator>(); this.GetComponent<Text>().text = chipCalculator.screen; } } }
お互いのチップがカウントされ、更新されるのが確認できました。
もしよろしければ、Photonについて私が知りえる限りの情報を徹底的にまとめてみたので、下記の記事も読んで下さいね!