//tips
//photonでのroleの割り当て
Photonのルームで入室したタイミングで各プレイヤーに役割を割り振る機能を作成していく。
photonのcustom propertyを使用することで実現する。
カスタムプロパティとは、ルームやプレイヤーに紐付けできるハッシュテーブル形式の一時的なパラメータで、ルーム/プレイヤーの作成時、SetCustomPropertiesメソッドを用いることでパラメータに設定することが可能。これを呼び出す際はcustomPropertiesメソッドを呼ぶ。
キーとバリューのペアでデータを格納し、インデックス番号を使わずにキーでオブジェクトを管理できるもので、使い方は基本的にDictionaryと同じである。
GamePlayerスクリプトで参加人数の数値を割り振り、シーン上でその数値を参照し、UIを切り替える方法を試す。
各プレイヤーとして生成するGamePlayerスクリプトのスタートメソッドに下記を組み込んだがエラーが発生。
int pnumber = 1;
PhotonNetwork.LocalPlayer.SetCustomProperties(pnumber);
PhotonNetwork.LocalPlayer.SetCustomPropertiesの引数に取れるのはhashtableのみのようなのでHashtableにして設定。
ルームの参加人数をもとに数字を割り振りたいので下記コードを入れて、ルームの参加者人数を撮ろうとしたら、GetRoomList()がエラーとなる。
RoomInfo[] roomInfo = PhotonNetwork.GetRoomList();
if (roomInfo.Length == 0) return;
そもそも生成されるプレイヤーオブジェクトのスクリプトではなく、入室時にプレイヤー自身へ数字を割り振り、シーン遷移の際にランダムくじのスクリプトなどでグループ分けし、そのグループの値をプレイヤーオブジェクトが参照するという形にしたほうが流れとしてわかりやすい。
そのためには、
・プレイヤーの入室タイミングをカウントできること
または、プレイヤーの入室人数をリストから取得できること
・photonに関連する変数などを使い、参加プレイヤーの中で順番に数字の割り振りまたは取得ができること
数字の重複をなくすため
・再度割り振った数字を参照でき、それを条件として別のメソッドを実行できること
の要素が必要となる。
これはPUN2に対する知識の問題となりそうなので、一旦保留し、質問中。
//一定時間ボタンクリックをロックする
ボタンを押すと特定canvas下のボタンの全てを一定時間押せなくする機能を考える。
UI要素をグループ化して共通の処理を加えるためのコンポーネントであるCanvas Groupの中にInteractableがあったのでこちらを利用して、一定時間タップ無効化していく。
まずはdroneplayerUIcanvasにcanvasgroupをアタッチする。
空オブジェクトを作成し、NotPushButtonスクリプトを新たに作成する。下記を作成したがなぜかスタートコルーチンの中身が実行されない。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NotPushButton : MonoBehaviour
{
[SerializeField]
GameObject droneUI;
CanvasGroup canvasgroup;
void Start()
{
canvasgroup = droneUI.GetComponent<CanvasGroup>();
Debug.Log("0");
}
public void CanvasLock()
{
Debug.Log("1");
StartCoroutine("canInt");
Debug.Log("2");
}
IEnumerable canInt()
{
Debug.Log("3");
canvasgroup.interactable = false;
yield return new WaitForSeconds(3);
canvasgroup.interactable = true;
}
}
よくスクリプトを見直してみるとIEnumeratorではなくIEnumerableになっていた。予測変換を使った後にもう一度よく読まないとこのようなトラップにかかる。修正すると無事に稼働した。
これで特定canvas下のUIのタップを3秒間無効にできた。
//photonでのroleの割り当て/続
PhotonNetwork.countOfPlayersから手繰り、Debug.Log("PhotonNetwork.countOfPlayers"+ PhotonNetwork.CountOfPlayers);、そしてPhotonNetwork.PlayerList.Lengthに行き着けた。
PhotonNetwork.PlayerListが現在のroomのプレイヤーリストであるのでちょうどいい。
スクリプトは下記のように追加修正し、
Debug.Log("PhotonNetwork.countOfPlayers"+ PhotonNetwork.PlayerList.Length);
var hashtable = new ExitGames.Client.Photon.Hashtable();
if (PhotonNetwork.PlayerList.Length == 0) return;
RandomNumber(PhotonNetwork.PlayerList.Length);
hashtable["PNumber"] = pnumber;
PhotonNetwork.LocalPlayer.SetCustomProperties(hashtable);
メソッドも下記のものを加えた。
void RandomNumber(int end)
{
for (int i = 0; i <= end-1; i++)
{
numbers.Add(i);
}
int index = Random.Range(0, numbers.Count);
int ransu = numbers[index];
SetNumber(ransu);
Debug.Log(ransu);
numbers.RemoveAt(index);
}
int SetNumber(int number)
{
return pnumber = number;
}
この内容を遷移先のシーンで表示するために新たなスクリプトを作成した。
using System.Collections;
using System.Collections.Generic;
using Photon.Pun;
using UnityEngine;
using Photon.Realtime;
public class NumberProp : MonoBehaviour
{
[SerializeField]
GameObject faceon;
void Update()
{
if (PhotonNetwork.LocalPlayer.CustomProperties["PNumber"] is int pnumber)
{
if (pnumber == 0)
{
faceon.SetActive(true);
}
Debug.Log(pnumber);
}
}
}
これにより0番の時に表示するUIを作成し、photonで同期して実行を行ったが、数字の配分がうまくいかないのか、それとも、一つのUI設定の修正で他の同期先に影響を与えているのか不明だが、前参加プレイヤーで0番の場合のUI表示がなされてしまった。要検証。