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

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

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

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Q&A

解決済

2回答

1894閲覧

プログラムからinteractableを切り替えたい

退会済みユーザー

退会済みユーザー

総合スコア0

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

0グッド

0クリップ

投稿2019/04/12 03:21

編集2019/04/12 03:26

前提・実現したいこと

Unityで特定の条件を満たしていたらinteractableをTrueにしボタンを押せるようにしたいです。
interactable(false)⇒指定アイテム入手⇒interactable(True)

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

最初はオブジェクト参照がオブジェクト インスタンスに設定されていません。というNullがでており、他の方の質問を参考に書き直し下のコードになったのですが新しくエラーが発生してしまいました。

また、このエラーはAを押すと出現します。
インスタンスの設定をよく理解できていない為単純なミスなのかもしれませんがご教授お願いします。

You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all UnityEngine.MonoBehaviour:.ctor() Button:.ctor() MakimonoscriptGr:Update() (at Assets/Gallry/MakimonoscriptGr.cs:29)

該当のソースコード

public class MakimonoscriptGr : MonoBehaviour { Button btn;   void Start() { //btn = GetComponent<Button>(); btn = GameObject.Find("Canvas/ボタンオブジェクトの名前").GetComponent<Button>(); //btn.interactable = false; } void Update() { if (Input.GetKeyDown(KeyCode.A))//Aを押したら切り替え { // btn.interactable = true; // btn.GetComponent<Button>().interactable = true; btn = new Button(); btn.interactable = true; } } }

試したこと

http://portaltan.hatenablog.com/entry/2016/05/24/144108
こちらのサイトを参考にさせていただきコードを作成しました。
ほかにも Button btn; ⇒ public Button btn;にしてみたりしましたがエラーは起きないのですがオブジェクトを入れることができませんでした。

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

Unity3.4f1

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

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

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

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

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

guest

回答2

0

btn = new Button();がまずいらないのでそれを消します。
あとはインスペクターからアタッチするか、Findで探すかはお好みなのでお好きなほうで。

とりあえず色々減らしてみて、下記の感じでAを押したらボタンが押せなくなるか確認してみてください。
アタッチしたオブジェクトのインスペクターから、btnに切り替えたい対象のボタンをアタッチしてください。

C#

1public class MakimonoscriptGr : MonoBehaviour 2{ 3 4 [SerializeField] GameObject btn; 5 6 void Update() 7 { 8 if (Input.GetKeyDown(KeyCode.A))//Aを押したら切り替え 9 { 10 btn.GetComponent<Button>().interactable = false; 11 12 } 13 } 14} 15

投稿2019/04/12 04:16

hogefugapiyo

総合スコア3302

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

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

退会済みユーザー

退会済みユーザー

2019/04/13 06:45

返答が遅くなり申し訳ございません。 さっそく試してみたところボタンは押せるままでした。 btn.GetComponent<Button>().interactable = false; この部分のインスタンスが設定されてないと出てしまいます。 また、別の疑問だったのですが、今までいろいろ試していた時にpublicでオブジェクトを作っておりアタッチできないのが何故なのかわからなかったのですがhogefugapiyo様のコードのSerializeFieldではアタッチできたため、publicとSerializeFieldの違いを調べることで理解できました。初歩的なところですが一つ疑問が解けました、ありがとうございます。
fiveHundred

2019/04/13 07:28

> btn.GetComponent<Button>().interactable = false; > この部分のインスタンスが設定されてないと出てしまいます。 以下を確認してみてください。 - インスペクター上からbtnを設定しているかどうか - btnにスクリプトから何か代入していないかどうか(「btn = GameObject.Find("Canvas/ボタンオブジェクトの名前").GetComponent<Button>();」は残っていませんよね?) > publicとSerializeFieldの違いを調べることで理解できました。 正直、正しく理解されていないような気がします。 publicでもSerializeFieldと同様にインスペクター上から設定できるようになることは変わりないため、「アタッチできるようになった」というのは、別の原因だと思われます。 (そもそも、アタッチという言葉の使い方自体、間違っているような気もします) この2つの違いを挙げるとすれば、「publicは、別のスクリプトから参照できるようになる(本来、publicとは別のクラスからアクセスできるように設定するためのもの)」「SerializeFieldは、アクセス権(private・protectedなど)は変更されない」という感じですが、認識は合っておりますでしょうか。
退会済みユーザー

退会済みユーザー

2019/04/14 03:23 編集

- インスペクター上からbtnを設定しているかどうか    設定していました。 - btnにスクリプトから何か代入していないかどうか   下の回答の方へコードを載せました、代入はしてないです。 >正直、正しく理解されていないような気がします。  知ったきになっていたみたいです、もう1度しっかりと調べなおすことにします・・・。  SerializeFieldで設定をすると他からアクセス権などのを変更ができなくなる、publicは他から色々変更ができてしまうということでしょうか? すみません、少し困惑しています。 こちらのサイトも併せて読みました。 https://qiita.com/makopo/items/8ef280b00f1cc18aec91 また、初歩的だとは思うのですがインスペクターにスクリプトなどを入れることはアタッチでないのでしょうか?
fiveHundred

2019/04/14 06:27

> SerializeFieldで設定をすると他からアクセス権などのを変更ができなくなる、 逆です。SerializeFieldを使わないとアクセス権を変更できません。 > publicは他から色々変更ができてしまうということでしょうか? 他のクラスから変更することが出来てしまう、という意味で合っておりますが、ちょっと認識がずれているような気もします。 「SerializeField」と「public」は本来であれば、同格のものではありません。 「public」はデフォルトで(「SerializeField」のように)インスペクターの表示がされる、という仕様になっているだけです。 (私の回答で混乱させてしまっているのであれば、すいません) 「public」は「アクセス修飾子」といい、他のクラスから設定できるかどうかを指定するもので、他には「private」「protected」などがあります。 (ちなみに、C#ではデフォルトではprivateです) 詳細は「C# アクセス修飾子」で検索してみてください。 対して「SerializeField」はアクセス修飾子ではないので、「privateだけどインスペクターに表示する」ということができます。 よく分からないのであれば、とりあえず「SerializeField」を使うことをおすすめします。 もし「public」にする必要がでてきたら、その時に「public」にすればいいだけなので。 > また、初歩的だとは思うのですがインスペクターにスクリプトなどを入れることはアタッチでないのでしょうか? アタッチは、ゲームオブジェクトにコンポーネント(スクリプトも含む)をくっつけることを指します。
退会済みユーザー

退会済みユーザー

2019/04/14 12:37

解説ありがとうございます。 アクセス修飾子について調べます。 アタッチの方、理解できました。
guest

0

ベストアンサー

C#

1 btn = new Button(); 2 btn.interactable = true;

上記だと、Buttonを新しく生成してそのinteractableを変更する、となります。
当然ながら、すでに設置してあるButtonは何も変化はありません。

また、コンポーネントのクラス(厳密にはMonoBehaviourを継承しているクラス)をnewしようとすると、質問にあるようなメッセージが出ます。

見た感じだと、Start()内でボタンのクラスを取得しているようなので、btn = new Button();を削除すれば動作するようになると思います。

投稿2019/04/12 04:06

fiveHundred

総合スコア9797

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

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

退会済みユーザー

退会済みユーザー

2019/04/13 06:22

返答が遅くなり申し訳ございません。 btn=new Button();を消したところこちらのnullが発生しました。(質問を始める前にも何度か出ていました。) NullReferenceException: Object reference not set to an instance of an object MakimonoscriptGr.Update () (at Assets/Gallry/MakimonoscriptGr.cs:30) こちらの質問が出た際にインスタンスを作成すると他の質問者様のところで見てbtn = new Button();を追加したのですが、入れる場所または書き方が悪かったのでしょうか・・・?
fiveHundred

2019/04/13 07:13

「btn = GameObject.Find("Canvas/ボタンオブジェクトの名前").GetComponent<Button>();」が上手くいっていないからでしょう。 もっとも、hogefugapiyoさんの回答のように、[SerializeField]を使って、「btn = GameObject.Find("Canvas/ボタンオブジェクトの名前").GetComponent<Button>();」は削除したほうが、分かりやすいと思います。 また、Buttonはnewするものではありません。 ゲームオブジェクトにアタッチして使うものは全てコンポーネントなので、newは一切使ってはいけないと思ってください。
退会済みユーザー

退会済みユーザー

2019/04/14 02:53

「//」で現在スクリプトはこのようになっています。 public class MakimonoscriptGr : MonoBehaviour { [SerializeField]   GameObject btn; void Update() { if (Input.GetKeyDown(KeyCode.A)) { btn.GetComponent<Button>().interactable = false; } } エラーは出ないのですがAを押しても変更しません。また、オブジェクトをクリックするとButton横のチェックが外れるようになっていました。 もしかしてなのですが、Aを押したらButtonのアニメーション(Disabled)と(Normal)を切り替える処理は最初にした質問とは違うコードなのでしょうか。 >また、Buttonはnewするものではありません。   承知しました。
fiveHundred

2019/04/14 06:27

> Buttonのアニメーション これ初耳なんですけど…。 現状のソースはアニメーションを使わずに変更する方法なので、アニメーションを使っているのであれば、そちらを制御する必要があります。
退会済みユーザー

退会済みユーザー

2019/04/14 12:43 編集

そうですよね…質問の内容が悪くうまく伝えられていなかったようです、申し訳ないです。 変更したいボタンはクリック時の色が変わる処理等をアニメーションにしています。(trantionをanimationにしている) Aを押したらDisabledアニメーション⇒normalアニメーションへ変更、ボタンの選択が可能 という風にしたかったのです。      *訂正*enableアニメーション⇒Disabledアニメーション
fiveHundred

2019/04/14 12:31

試してみたところ、interactableもアニメーションで変更できるようですが、どうでしょうか。
退会済みユーザー

退会済みユーザー

2019/04/14 12:42

アニメーションがはDisabledのままで変わる様子はありませんでした。animatorをいじる必要がありますか? またはスクリプトにアニメーションへの処理のコードを入れるべきでしょうか。
fiveHundred

2019/04/14 12:46

そもそも、アニメーションの切り替え処理はどのようになっていますか?
退会済みユーザー

退会済みユーザー

2019/04/15 05:04 編集

UIボタンを追加した際にButton(script)にはいっているtrantionをanimationにすると生成されるものを使用しています。切り替えの処理はよくわかりませんでした・・・。AnyStateから待機やクリック時などのアニメーションに矢印が伸びています。
fiveHundred

2019/04/15 06:05

trantionというがよく分かりませんが、とりあえずAnimatorの使い方について、調べたほうがよろしいかと思います。
退会済みユーザー

退会済みユーザー

2019/04/15 07:20

そうですね、animationについて調べることにします。 様々なことに細かくお答えいただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問