//tips
//Photon prefab取り扱い周り
public void Activate(RoomInfo info)のgameObjectの中身を確認するためにDebug.Log(gameObject);を使用すると、
RoomListEntryB(Clone) (UnityEngine.GameObject)
と表され、gameObjectは他の方が入室することで自シーンに生成されるボタンオブジェクトを取れていることがわかる。
gameObject.SetActive(true);を入れなくても、生成された時点ではアクティブな状態なので、このSetActive(true)はボタンリサイクルの際に使用するものと考える。
Clone生成したオブジェクトの孫要素のコンポーネントの取得方法は下記でできることは確認できた。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class PrefabManager : MonoBehaviour
{
public GameObject canvas;//キャンバス
public GameObject ParentPrefab;
string test = "testだよ";
void Start()
{
GameObject prefab = Instantiate(ParentPrefab, this.transform.position, Quaternion.identity);
prefab.transform.SetParent(canvas.transform, false);
prefab.transform.Find("Image/Text").GetComponent<Text>().text = test;
}
void Update() { }
}
だとすれば
gameObject.transform.Find("InputField/roomname").GetComponent<Text>().text = InfoName;
で孫要素roomnameのtext内容を変えられないのは別の問題が生じているのではないかと考えた方が良さそう。
Debug.Log(roomname.text);を追加したところきちんと代入できていないことがわかった。
Debug.Log(info.Name); //aaa
Debug.Log(InfoName); //aaa
Debug.Log(roomname.text); //表示無
gameObject.transform.Find("InputField/roomname").GetComponent<Text>().text = "abcd";
としてもログは無表示なので、gameObject.transform.Find("InputField/roomname").GetComponent<Text>().textでroomname.textが取れていない恐れがある。
Debug.Log(gameObject.transform.Find("InputField/roomname").GetComponent<Text>().text);
としても表示無し。
これはInputFieldコンポーネントのTextComponentにroomnameが登録されているので、入力があってもInputField.textの内容に更新され、消されるということがわかり、
inputField.text = info.Name;
として記載してあげないとダメだったことがわかった。
子要素のtextコンポーネントを参照し、その内容をInput fieldのテキストに反映させる形になっており、シーンでの直接入力の際は子要素のtextで受け取り、Input fieldに渡されるが、スクリプトで 子要素のtextを編集した場合、その内容がInput fieldのテキストに渡らないということがわかった。
//新規roomボタンの作成
新規Roomボタンを作成するためにRoomListViewBスクリプトにボタンから参照できる下記メソッドを追加。ボタンはRoomListViewオブジェクトの子要素として追加した。
public void PushNewButton()
{
Instantiate(roomListEntryPrefab, scrollRect.content);
}
このメソッドを追加したボタンのOnclick設定するれば新規ボタンが簡単に作れる。
//クラスを型に設定する場合についての検証
スクリプトで記述したクラスを型にして変数を設定する場合を見かけるので、そちらの理解を深める。
例えば、単純にprefabを参照する場合でもクラスを型にしたり、GameObjectを型にしたりする。①も②もどちらもprefabを生成している。
①
[SerializeField]
private InputfieldButton roomListEntryPrefab = default; // RoomListEntryのPrefabの参照
InputfieldButton entry;
entry = Instantiate(roomListEntryPrefab, scrollRect.content);
②
public GameObject ParentPrefab;
GameObject prefab = Instantiate(ParentPrefab, this.transform.position, Quaternion.identity);
単一のスクリプトでインスタンスの生成を行うことができれば簡単だが、作成クラスがmainスクリプトの部品の場合、mainクラスでインスタンス化することがあるので、インスタンスする予定のクラスの変数を先に宣言しておく場合が発生する。
下記スクリプトが理解の参考になった。
//Heroクラス
public class Hero {
String name;
int hp;
Sword heroSword;//①sword型のheroSwordフィールドを作成。
void attack(){
System.out.println(this.name +"は"+this.heroSword.name+"で攻撃した!");//③
System.out.println("敵に"+this.heroSword.damage+"ポイントのダメージを与えた!!");//③
}
}
//swordクラス
public class Sword{
String name;
int damage;
}
//mainクラス
public class Main {
public static void main(String[] args) {
Sword sword = new Sword();
sword.name = "炎の剣";
sword.damage = 10;
Hero hero = new Hero();
hero.name = "ミナト";
hero.hp = 100;
hero.heroSword = sword;//②heroインスタンスのheroSord属性に、swordインスタンスを代入する。
hero.attack();
}
}
このようにHeroクラスもswordクラスもmainクラスのスクリプトの中でインスタンス化され、次スクリプトのメソッドを呼びながら実行している。
次はオブジェクトやListを絡めながら検証してみる。