//tips
//PUNボタン生成
相手側エントリー時に生成される無名ボタンを名付き表示する方法について考える。
activeEntriesの役割は、自身以外のroom情報が更新された場合にOnRoomListUpdate(List<RoomInfo> roomList)で呼ばれることから、自分のシーン上からみたroomの活動状況を観測するものと言える。
Roomにupdateがあれば自分のシーンに反映させる必要があり、room情報を表すボタンに影響が及ばされることになる。
自身の入室ではactiveEntriesに追加されないので、自分のシーンでは別途ボタンの生成手段を考える必要がある。
Prefabから生成されるボタンに対して、roomlistの情報内容を反映させて表示するように変更する。InputfieldButtonスクリプトを修正する。
public void Activate(RoomInfo info)
{
roomname.text = info.Name;
と変更し、Debug.Log(info.Name);から他のプレイヤーが部屋に入るとRoomInfo info更新され、その更新によるボタン生成と連動して行われるInputfield buttonスクリプトのActivate(RoomInfo info)がきちんと呼ばれ、かつ、プレイヤーが入力した部屋の名前でコンソール上には表示された。
ただ、その情報がボタン上には反映されていないのでroomname.text = info.Name;部分が何かおかしいことになる。
roomname.text = info.Name.ToString();に変更してもダメだったので、子要素としてアクセスしてtextコンポーネントを取り直して対応してみた。
Transform roomName = gameObject.transform.Find("Base/InputField/roomname");
Text roomNametext = roomName.GetComponent<Text>();
roomNametext.text = info.Name;
すると、下記のようにテキストコンポーネントが存在していないとのエラーが表示される。
NullReferenceException: Object reference not set to an instance of an object
InputfieldButton.Activate (Photon.Realtime.RoomInfo info) (at Assets/Script/InputfieldButton.cs:58)
下記も試したが、エラーは出ないが文字も表示されない。
gameObject.transform.Find("InputField/roomname").GetComponent<Text>().text = info.Name;
同じprefab内にあるにもかかわらず、[SerializeField]でも、Findでもroomnameのコンポーネントが取得できないというのは理解できないので、質問中。
//prefabのスクリプトを用いた自動生成
今回理解が足りなかったので自動生成するprefabのスクリプトまわりで簡単なシーンを作成してみる。
作成スクリプトは下記。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class PrefabManager : MonoBehaviour
{
public GameObject canvas;//キャンバス
public GameObject text;
public GameObject ImagePrefab;
string test = "testだよ";
void Start()
{
GameObject prefab = (GameObject)Instantiate(text);
prefab.transform.SetParent(canvas.transform, false);
GameObject Image = Instantiate(ImagePrefab, this.transform.position, Quaternion.identity);
Image.transform.SetParent(canvas.transform, false);
Image.transform.Find("ImageText").GetComponent<Text>().text = test;
}
void Update() { }
}
上記作成後、gameObject.transform.Find("InputField/roomname").GetComponent<Text>().text = info.Name;を見返してみて、string変数の代入は活かせそうなので、string InfoName = info.Name.Tostring();と変更を加えてみた。
string InfoName = info.Name.ToString();
gameObject.transform.Find("InputField/roomname").GetComponent<Text>().text = InfoName;
これも効果がなかったので、スクリプトを見直し、gameObject.SetActive(true);を一旦削除してみても、ボタンは生成されたのでgameObjectではなく、prefabそのものを認識させるようにしようと下記に変更したが効果なし。
[SerializeField]
private InputfieldButton roomListEntryPrefab = default; // RoomListEntryのPrefabの参照
roomListEntryPrefab.transform.Find("InputField/roomname").GetComponent<Text>().text = InfoName;
RoomListViewで生成されるentryオブジェクトを取得できるのが一番いいので、方法を考える。また、Objectが果たす役割が曖昧なので、そこも検証する。