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

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

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

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

Unity

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

Q&A

解決済

1回答

4632閲覧

Unity(C#)newで作っていたscriptをGameObjectにアタッチしたい

Yamaimo_Misoni

総合スコア11

C#

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

Unity

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

0グッド

1クリップ

投稿2017/04/02 15:34

Unity5.5.1(C#)で、クイズを出題するゲームアプリを作っています。
クイズは3種類(○×、3択、並べ替え)あり、読み込んだクイズがそのどれかを判別して、各形式のscriptを読み込むという方式をとっています。

詳しく言うと、WholeQuizManagerというScript(これはObjectにアタッチされています)でquizを読み込み、それが○×ならTrueFalseQuizManagerを起動、3択ならThreeChoiceQuizManagerを起動……というようになっています。

コードでいうと、WholeQuizManagerでは

C#

1if(quiz is TrueFalseQuiz){ //TrueFalseQuizは自前のクラス 2 currentManager = new TrueFalseQuizManager(quiz as TrueFalseQuiz) 3} 4……

というようになっており、TrueFalseQuizManagerの中身は

C#

1public class TrueFalseManager : MonoBehaviour, QuizManager { //QuizManagerは自前のクラス 2//…中略… 3 public FourChoiceQuizManager(FourChoiceQuiz quiz) { 4 //起動時の動作が入る 5 } 6 7 public void Update() { 8 //中略 9 } 10}

というふうになっています。WholeQuizManagerのUpdateで、currentManagerのUpdateを呼び、クイズ形式に応じたUpdateが動くようになっています。

しかし、Monobehaviorを継承したクラスがGameObjectにアタッチしないままnewで呼び出されることは良くないようで、警告が出ます。
そこでTrueFalseManagerなどを一旦適当なGameObjectにアタッチしようと試みているのですが、TrueFalseQuizManagerには引数としてquizを渡さなければなりません。
例えば

C#

1 GameObject Object = new GameObject("Object"); 2 TrueFalseQuizManager trueFalseQuizManager = Object.AddComponent<TrueFalseQuizManager>(); 3 currentManager = trueFalseQuizManager;

とすると、一応文法エラーにはなりませんが、quizが渡せておらず、また最初に呼ばれるべきはずのクラス名と同名のメソッド(TrueFalseQuizManager(Quiz quiz))が呼ばれないため、実行エラーが起きます。

長くなってしまいましたが、どのように書けばObjectにアタッチしつつ各形式のManagerを起動できるでしょうか?
ご教授よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

他の方法があるとは思いますが、とりあえず思いついたのを

C#

1public class TrueFalseManager : MonoBehaviour, QuizManager { //QuizManagerは自前のクラス 2//…中略… 3 4 private FourChoiceQuiz quiz; 5 6 public FourChoiceQuizManager() { 7 } 8 9 public FourChoiceQuiz Quiz 10 { 11 get 12 { 13 return quiz; 14 } 15 set 16 { 17 quiz = value; 18 //起動時の動作が入る 19 } 20 public void Update() { 21 //中略 22 } 23}

とコンストラクタではなくプロパティでquizを渡すようにして

C#

1GameObject Object = new GameObject("Object"); 2TrueFalseQuizManager trueFalseQuizManager = Object.AddComponent<TrueFalseQuizManager>(); 3trueFalseQuizManager.Quiz = quiz; 4currentManager = trueFalseQuizManager;

と生成後にプロパティをセットしてはどうでしょう?

投稿2017/04/02 22:09

YAmaGNZ

総合スコア10222

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

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

Yamaimo_Misoni

2017/04/03 00:49 編集

ありがとうございます。TrueFalseやFourChoiceが混在してしまい、申し訳ありません。 この方法をとったのですが、プロパティでquizを渡し起動時の動作をするとき、TrueFalseQuizManagerのグローバル変数(?)としてとっていたGameObjectのobject2にObjectを渡すため、 object2 = GameObject.Find("オブジェクト名"); と書いたところ、 NullReferenceException: Object reference not set to an instance of an object (wrapper stelemref) object:stelemref (object,intptr,object) が出てしまいました。これはどうしてなのでしょうか?
YAmaGNZ

2017/04/03 01:09

object2 = GameObject.Find("オブジェクト名"); ではなく object2 = GameObject.Find("Object"); ではないでしょうか? 前者は「オブジェクト名」という名前のGameObjectを探して、存在しない為GameObject.Findはnullを返します。 この為、NullReferenceExceptionとなっているのではないでしょうか? プロパティのsetの部分の //起動時の動作が入る の部分での記述で、このスクリプトがアタッチされているGameObjectをobject2に格納するのであれば object2 = gameObject; でもいけそうな気がしますが
Yamaimo_Misoni

2017/04/03 01:26

書き方が悪くてすみません。書き直して再度説明を試みさせてください。 WholeQuizManagerはUnityでQuizというシーンの適当なObjectにアタッチされており、QuizシーンにはButtonというGameObjectをすでに配置しています。 そして、いまWholeQuizManagerから教えていただいたとおりにTrueFalseQuizManagerを生成します。 TrueFalseQuizManagerの中では public class TrueFalseQuizManager : MonoBehaviour, QuizManager { private GameObject button; private FourChoiceQuiz quiz; public FourChoiceQuizManager() { } public FourChoiceQuiz Quiz { get { return quiz; } set { quiz = value; button = GameObject.Find("Button"); } public void Update() { //中略 } } というように書いているのですが、button = GameObject.Find("Button");の部分でNullReferenceExceptionを返されるのです。
YAmaGNZ

2017/04/03 03:22

GameObject.Findがnullを返すとすれば 1.名称(今回は"Button")が間違っている 2.探す対象のGameObjectがアクティブになっていない が考えられます。 原因が2でアクティブにできないのであれば、親GameObjectから parent.transform.Find("Button").gameObject; という感じで取得する手もあります。
Yamaimo_Misoni

2017/04/03 05:01

間違えて private GameObject button = new GameObject; としていたのが問題でした。多くの質問に答えていただき、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問