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

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

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

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

Q&A

解決済

1回答

1638閲覧

Unity 動的に追加したButtonコンポーネントのOnclickの処理で別コンポーネントで扱っている変数に代入したい

AyumuYoshikawa

総合スコア5

Unity

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

0グッド

0クリップ

投稿2020/02/17 14:40

編集2020/02/17 14:55

動的に追加したButtonコンポーネントのOnclickの処理で別コンポーネントで扱っている変数に代入したい

現在Unity 2Dでノベルゲームを製作しており、
ヒエラルキー

このようなhierarchyでコンポーネントを配置しています。

コンポーネント名概要
GameContorollerGameObject場面の管理やセリフの更新などを行う。
OptionPanelPanel選択肢を表示するボタンを入れるパネル
OptionButtonButton選択肢を表示するボタンの雛形。prefabにしてもよかったが、こちらにした

GameCotorollerクラス内でOptionPanel内に動的に選択肢ボタンを追加し、
OnClickで呼び出した関数でGameContorollerクラス内の変数に代入を行いたいと思っています。

代入を行いと思っている変数は下記SceneクラスのCurentSceneというクラス変数NextSceneIDです。
ViewOption内で動的に生成したButtonのOnClickにclickHandler関数を割り当て、代入したいと考えており、次のようなコードを書きました。

C#

1public class GameController : MonoBehaviour 2{ 3 4 /* 略 */ 5 6 public class Scene 7 { 8 public string ID; 9 public string NextSceneID; 10 public Queue<string> Texts = new Queue<string>(); 11 public List<Option> Options = new List<Option>(); 12 public Queue<string> BackGround = new Queue<string>(); 13 public Queue<ActionType> Actions = new Queue<ActionType>(); 14 15 } 16 17 public class Option 18 { 19 public string OptionText; 20 public string val; 21 public Action Action; 22 } 23 24 public Scene CurrentScene; 25 26 /* 略 */ 27 28 void ViewOption(){ 29 30 TextPanel.SetActive(false); 31 OptionPanel.SetActive(true); 32 foreach (Option o in CurrentScene.Options) 33 { 34 35 //Button b = Instantiate(Resources.Load("Button" , typeof(Button) ) ) as Button; 36 Button b = Instantiate( OptionButton ); 37 b.transform.SetParent(OptionPanel.transform , false ); 38 b.transform.localScale = new Vector3( 1F , 1F , 1F ); 39 b.onClick.AddListener( () => o.Action() ); 40 b.transform.FindChild("Text").GetComponent<Text>().text = o.OptionText; 41 b.transform.FindChild("Text").GetComponent<Text>().fontSize = 75; 42 43 } 44 45 } 46 47 public void clickHandler (string id ){ 48 Debug.Log(id); 49 CurrentScene.NextSceneID = id; 50 SetNextAction(); 51 } 52}

o.Actionについては

C#

1Option op = new Option(){ 2 OptionText = sp[0], //spはそれぞれ入力確認できています 3 val = sp[1], 4 Action = () => clickHandler(sp[1]) 5 };

という処理をしています。

発生している問題・エラーメッセージ

ここでViewOptionが実行された際、

![イメージ説明]

このようにOptionPanel内にOptionButtonは追加され、clickHandlerが実行され、
idも適切に渡せている(Debug.Logで確認)のですが、

NullReferenceException: Object reference not set to an instance of an object

とエラーが出ます。

該当のソースコード

エラー発生箇所は、

C#

1CurrentScene.NextSceneID = id;

であり、

C#

1Debug.Log(CurrentScene.NextSceneID);

C#

1Debug.Log(CurrentScene);

でも同様のエラーが出たことから、CurrenSceneの参照ができていないことが原因だと考えています。
OnClickで呼ばれるclickHandlerはOptionButtonで呼ばれている?ことがその原因だと考えています。
ただ、Unityを触るのは殆ど初めてなのでUnityにおける参照範囲や参照方法のセオリー等がはっきりと分かっておらず、浅はかな質問になってしまっているかも知れませんが、回答頂けると幸いです。

補足情報(FW/ツールのバージョンなど

Unity 2019.3.0f
MacOS Mojava 10.14.5

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんばんは。

私が試す限りでは動的生成でも特に問題無くCurrentSceneは参照出来ました。
質問への追記に書くべきだったのですがCurrentSceneへの代入はどこでおこなっているのでしょうか?

投稿2020/02/17 15:15

編集2020/02/17 17:05
Hawn

総合スコア1222

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

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

AyumuYoshikawa

2020/02/17 22:45

ご回答ありがとうございます! 代入処理はGameCotrollerクラス(一番上のコードです)のメンバ関数clickHandler内で呼ばれており、そのボタンへの割当は同じくメンバ関数ViewOption内のAddEventlitenerで、2番目のコードでclickHandlerに引数を渡したものをAction化?したものの割当を行っています
Hawn

2020/02/18 03:18

そこは理解しているので大丈夫です。 最近似たようなコードを見ていてそちらでは「Scene CurrentScene」がpublicでは無かったのにこちらではそうなっているのが気になりました。
Hawn

2020/02/18 03:37

そちらのコードでは「currentScenario = null;」箇所がある上に条件的にもあり得るのでこちらのコードでも残っていればそこをコメントアウトしてみて下さい。 どういう意図で略しているのか判らないのですが出来ればコード全て提示して頂きたいところでした。
AyumuYoshikawa

2020/02/18 04:03

ご丁寧にありがとうございます. currentScenario = null;にあたるコードをコメントアウトしたところ無事解決致しました. おそらくha_wn様がご覧になられたコードと同じものを参考に書いていると思います. 色々つけ足した結果,コード超が少し長くなっており回答に差し支えることと,原因にある程度辺りを付けそれ以外のコードを略していましたが,その結果として原因部分を載せていなかったことになっていたようです. 今回の解決はha_wn様あってのものでした.辺りをつけすぎない等の勉強になったことが沢山あります.ありがとうございました.
Hawn

2020/02/18 04:18

無事解決されたようで良かったです。 多少冗長でも難解なコードでなければ200~300行読むのに20秒掛からないので特に気を遣う必要は無いかと思います。 500行超とかになると要点だけ抜き出した方が良いかとは思いますが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問