質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

379閲覧

Buttonオブジェクトのprefab化

JectABC

総合スコア34

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2017/06/09 07:28

編集2017/06/09 22:59

###前提・実現したいこと
nameを受けとりButtonを生成し、ボタンの名前を変える関数です。
Buttonのprefabをコードで生成しようとしたところinstantiateにnullが渡せれされているようでprefabが作れません。

お願いします。
###発生している問題・エラーメッセージ
どこで止まっているかという記述はありませんが
下記コードのdebug.logでprefabがnullだったためこの部分だと思います。

ArgumentException: The thing you want to instantiate is null.

###該当のソースコード

C# using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Item : MonoBehaviour { public Button[] items = new Button[10]; public Button prefab ; public Transform itemObjTransform; void Start(){ //prefab = Resources.Load ("prefab2/ButtonItem") as Button; } public int SetItem(string name){ int number = 0; Debug.Log (prefab); for (int i = 0; i < 10; i++) { if (items [i] == null) { number = i; break; } number = i; } items [number] = Instantiate (prefab, new Vector3(1,1,1), Quaternion.identity); items [number].transform.SetParent (itemObjTransform); items [number].transform.localScale = Vector3.one; items [number].GetComponent<Text> ().text = name; return number; }

###試したこと
Start()でコメントアウトしている部分でprefabの初期化をしてみましたがprefabはnullのままでした。

###補足情報(言語/FW/ツール等のバージョンなど)
Itemクラスをアタッチしているオブジェクトのinspector

items
size 10
中身はすべてnone
prefab ButtonItem(Button)

itemObjTransform ImageItem(Rect Transform) ← Buttonオブジェクトの親

アンサー意見への補足
Loadにこだわっているのではなく問題はprefabがnullということです。
itemクラスのinspectorではきちんとprefabとButtonがアタッチされています。
念のためということでLoadで初期化しましたが
これでまだnullなのが不思議です

またパスに間違いはありません。

ご協力お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ButtonクラスはMonoBehaviourの一種で、分類としてはスクリプトコンポーネントになるかと思います。
Resources.Loadで持ってきたプレハブはGameObjectのはずですので、ご提示のコードに出てくるButton型をGameObject型に変えてみるとどうでしょうか。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class Item : MonoBehaviour { 7 8 9 public GameObject[] items = new GameObject[10]; 10 11 12 public GameObject prefab ; 13 14 public Transform itemObjTransform; 15 16 void Start(){ 17 prefab = Resources.Load ("prefab2/ButtonItem") as GameObject; 18 } 19 20 21 public int SetItem(string name){ 22 23 int number = 0; 24 Debug.Log (prefab); 25 for (int i = 0; i < 10; i++) { 26 if (items [i] == null) { 27 number = i; 28 break; 29 } 30 number = i; 31 } 32 33 34 items [number] = Instantiate (prefab, new Vector3(1,1,1), Quaternion.identity); 35 items [number].transform.SetParent (itemObjTransform); 36 items [number].transform.localScale = Vector3.one; 37 items [number].GetComponent<Text> ().text = name; 38 39 40 return number; 41 42 } 43}

また、念のため確認しますが、プロジェクトのフォルダ構成はResources/prefab2/ButtonItemとなっていますでしょうか。もしprefab2フォルダがResourcesフォルダの中にない場合、Resources.Loadでは見つからないかもしれません。

参考1:Unity - スクリプトリファレンス: Button
参考2:Unity - スクリプトリファレンス: Resources.Load

[追記]
質問者さんのおっしゃる、インスペクタで参照させたはずのButtonがスクリプトから見るとnullになる...という現象についてどうなるか試したのですが、私の環境ではうまく再現できませんでした。
条件としては、

  • Image(名前はImageItem)の下にButton(名前はButtonItem)を配置
  • ButtonItemはスクリプト(Item.cs)をアタッチした上でプレハブ化しており、ヒエラルキー上のButtonItemはプレハブのインスタンスとなり、青い文字で表示されている
  • プロジェクトビュー内のButtonItemプレハブを選択し、インスペクタでItemコンポーネントのprefabに、同じくインスペクタに表示されているButtonコンポーネントをドラッグ(itemObjTransformについてはImageをプレハブ化していないためNoneのままとした...今回の件とはおそらく関係ない?)
  • シーンビュー内のButtonItemインスタンスを選択しインスペクタで内容を確認、Itemのprefabには「ButtonItem (Button)」と表示される(おそらく関係ないが、念のためitemObjTransformにImageItemをドラッグしてセット...項目が太字になってインスタンス固有の値がセットされたことを示していた)
  • Item.csはほぼそのままだが、確認のためにStart内でprefabをコンソールに出力

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class Item : MonoBehaviour 7{ 8 9 public Button[] items = new Button[10]; 10 11 12 public Button prefab; 13 14 public Transform itemObjTransform; 15 16 void Start() 17 { 18 //prefab = Resources.Load ("prefab2/ButtonItem") as Button; 19 Debug.Log(prefab); 20 } 21 22 23 public int SetItem(string name) 24 { 25 26 int number = 0; 27 Debug.Log(prefab); 28 for (int i = 0; i < 10; i++) 29 { 30 if (items[i] == null) 31 { 32 number = i; 33 break; 34 } 35 number = i; 36 } 37 38 39 items[number] = Instantiate(prefab, new Vector3(1, 1, 1), Quaternion.identity); 40 items[number].transform.SetParent(itemObjTransform); 41 items[number].transform.localScale = Vector3.one; 42 items[number].GetComponent<Text>().text = name; 43 44 45 return number; 46 47 } 48}

このような状態でプレイモードボタンを押したところ、コンソール出力は

ButtonItem (UnityEngine.UI.Button) UnityEngine.Debug:Log(Object)

となり、特にnullになってしまっている様子はありませんでした。何か実験条件が違っていますでしょうか?

※実行時の様子(キャプチャの都合上、マウスポインタが二重に表示されてしまいました)
実行時の様子

投稿2017/06/09 20:28

編集2017/06/10 06:11
Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

JectABC

2017/06/09 22:50

丁寧にありがとうございます。 確かにGameObjectにすればおそらく出来ると思います、が prefabを生成するだけではなく あとからOnClick等に関数を追加するため。 GameObjectのままでは不都合が多いです。 たしかGameObjectからはButton型にできなかったと思います
Bongo

2017/06/10 01:03

確かに、ButtonはGameObjectにアタッチされたコンポーネントという位置づけなので、GameObjectをButtonにキャストするわけにはいきませんね。となると、適宜GetComponentで取得すればどうでしょうか。 例えば、 items[number].GetComponent<Button>().onClick.AddListener(コールバック); このような感じでいかがでしょう?
Bongo

2017/06/10 02:01 編集

ご質問者さんの最初のコードでコメントアウトされた部分、Resources.Load ("prefab2/ButtonItem") as Buttonがnullとなったのは、Loadの失敗ではなくasによる型変換の失敗によるものかと思います(Loadが返したのはGameObjectだったが、それを互換性のない型であるButtonにしようとして失敗しnullとなった)。 prefabはButton型のままにしたい場合、Buttonを得るには prefab = (Resources.Load ("prefab2/ButtonItem") as GameObject).GetComponent<Button>(); の形にする必要があるでしょう。
guest

0

僕も初心者なので間違っていたらすいません

Instantiate (prefab, new Vector3(1,1,1), Quaternion.identity);
の第一引数はprefabとなっていますが実際のprefabの名前を指定する必要がありますが
ButtonItem
だったりしませんか?

投稿2017/06/09 07:36

kiryo

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

JectABC

2017/06/09 07:52 編集

実際のprefabはButtonItemという名前ですが、コード上のprefabにアタッチしています。 それではダメなのでしょうか?
JectABC

2017/06/09 17:20

まだ解決していません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問