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

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

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

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

Unity

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

Q&A

解決済

3回答

2224閲覧

【Unity】ボタンを押してもtrueになりません

syah

総合スコア16

C#

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

Unity

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

1グッド

1クリップ

投稿2018/09/17 10:46

編集2018/09/17 13:24

ボタンを押したときにbool型の変数shootbuttonをtrueにしたいです。

c#

1using UnityEngine; 2using System.Collections; 3using UnityStandardAssets.CrossPlatformInput; 4 5namespace CompletedAssets 6{ 7 public class Player : MonoBehaviour 8 { 9 // Spaceshipコンポーネント 10 Spaceship spaceship; 11 12 // 弾の連射用 13 private float timeCount1; 14//----------------------------------------------------- 15// 見てほしいところ1 ここから 16//----------------------------------------------------- 17 // 発射ボタン判定 18 bool shootbutton; 19 20 public void ShootButton() 21 { 22 Debug.Log("ShootButton"); 23 shootbutton = true; 24 } 25 26 public void noShootButton() 27 { 28 Debug.Log("noShootButton"); 29 shootbutton = false; 30 } 31//----------------------------------------------------- 32// 読んでほしいところ1 ここまで 33//----------------------------------------------------- 34 IEnumerator Start () 35 { 36 // Spaceshipコンポーネントを取得 37 spaceship = GetComponent<Spaceship> (); 38 yield return new WaitForSeconds(spaceship.shotDelay); 39 } 40 41 IEnumerator GUN() 42 { 43 // 弾をプレイヤーと同じ位置/角度で作成 44 spaceship.Shot(transform); 45 46 // ショット音を鳴らす 47 GetComponent<AudioSource>().Play(); 48 49 // shotDelay秒待つ 50 yield return new WaitForSeconds(spaceship.shotDelay); 51 } 52//----------------------------------------------------- 53// 見てほしいところ2 ここから 54//----------------------------------------------------- 55 void Update () 56 { 57 if (shootbutton) 58 { 59 Debug.Log("Shoot!"); 60 } 61//----------------------------------------------------- 62// 見てほしいところ2 ここまで 63//----------------------------------------------------- 64 // 右・左 65 float x = CrossPlatformInputManager.GetAxisRaw("Horizontal"); 66 67 // 上・下 68 float y = CrossPlatformInputManager.GetAxisRaw("Vertical"); 69 70 // 移動する向きを求める 71 Vector2 direction = new Vector2(x, y).normalized; 72 73 // 移動の制限 74 Move (direction); 75 76 if (Input.GetKey(KeyCode.Z) || shootbutton) 77 { 78 timeCount1++; 79 if (timeCount1 > spaceship.shotDelay * 10) 80 { 81 timeCount1 = 0; 82 StartCoroutine("GUN"); 83 } 84 } 85 else 86 { 87 timeCount1 = spaceship.shotDelay * 10; 88 } 89 90 } 91 92 // 機体の移動 93 void Move (Vector2 direction) 94 { 95 96 // 背景左下の座標を取得 97 Vector3 min = bg.GetComponent<Renderer>().bounds.min; 98 99 // 背景右上の座標を取得 100 Vector3 max = bg.GetComponent<Renderer>().bounds.max; 101 102 // プレイヤーの座標を取得 103 Vector2 pos = transform.position; 104 105 // 移動量を加える 106 pos += direction * spaceship.speed * Time.deltaTime; 107 108 // プレイヤーの位置が画面内に収まるように制限をかける 109 pos.x = Mathf.Clamp (pos.x, min.x + 0.28f, max.x - 0.32f); 110 pos.y = Mathf.Clamp (pos.y, min.y, max.y); 111 112 // 制限をかけた値をプレイヤーの位置とする 113 transform.position = pos; 114 } 115 116 // ぶつかった瞬間に呼び出される 117 void OnTriggerEnter2D (Collider2D c) 118 { 119 // レイヤー名を取得 120 string layerName = LayerMask.LayerToName (c.gameObject.layer); 121 122 // レイヤー名がBullet (Enemy)の時は弾を削除 123 if (layerName == "Bullet (Enemy)") { 124 // 弾の削除 125 Destroy (c.gameObject); 126 } 127 128 // レイヤー名がBullet (Enemy)またはEnemyの場合は爆発 129 if (layerName == "Bullet (Enemy)" || layerName == "Enemy") { 130 131 // Managerスクリプトからコンティニューコルーチンを呼び出す 132 FindObjectOfType<Manager>().Continue(); 133 134 // 爆発する 135 spaceship.Explosion (); 136 137 // プレイヤーを削除 138 Destroy (gameObject); 139 } 140 } 141 } 142}

デバッグしてみたときは表示されてましたが、trueに代入しようとしてもshootbuttonはtrueになりませんでした。
Inspectorの設定
![デバッグ
なおUpdateメソッド内ではshootbuttonをtrueに代入できました。ボタンは反応しているはずだと思いましたが、なぜshootbuttonに代入されないのかわかりません。
Unityのバージョンは2017.4.10f1 Personal(64bit)です。


追記

言葉足らずで申し訳ないです。
早速public bool shootbuttonと宣言し、Inspectorで見たところ、shootbuttonの値がボタンを押してる間はtrueになり、離したときにfalseになっていたことを確認できました。

「shootbuttonがtrueにならないことをどうやって確認したのか?」についてですが、
私は最初にUpdateメソッド内で
Debug.Log(shootbutton);
とした時にコンソールではTrueは表示されず、Falseしか表示されないことを確認しました。
※画像ではわかりやすくするために
Debug.Log(("shootbuttonは")+shootbutton);
としました。

c#

1void Update () 2 { 3 Debug.Log(("shootbuttonは")+shootbutton); 4 if (shootbutton) 5 { 6 Debug.Log("Shoot!"); 7 } 8 // 右・左 9 float x = CrossPlatformInputManager.GetAxisRaw("Horizontal"); 10 11 // 上・下 12 float y = CrossPlatformInputManager.GetAxisRaw("Vertical"); 13 14 // 移動する向きを求める 15 Vector2 direction = new Vector2(x, y).normalized; 16 17 // 移動の制限 18 Move (direction); 19 20 if (Input.GetKey(KeyCode.Z) || shootbutton) 21 { 22 timeCount1++; 23 if (timeCount1 > spaceship.shotDelay * 10) 24 { 25 timeCount1 = 0; 26 StartCoroutine("GUN"); 27 } 28 } 29 else 30 { 31 timeCount1 = spaceship.shotDelay * 10; 32 } 33 34 }

falseしか
Updateメソッド内ではshootbuttonの値の変化は反映されないのでしょうか。

I_love_yadoran👍を押しています

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

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

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

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

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

guest

回答3

0

掲載されているスクリプトの「見てほしいところ1」「見てほしいところ2」と書かれてある部分のみ抜粋して実行してみました。

ボタンを押している間は shootbutton = true
ボタンを押していない間は shootbutton = false
という動作を確認しました。
(ボタンを離した瞬間にtrueからfalseに変わることに注意してください)

Debug.Logでのコンソールへの出力以外に、

bool shootbutton;

の箇所を

public bool shootbutton;

と宣言して、UnityのPlay中にPlayerオブジェクトのshootbuttonのチェックボックスを見ることでリアルタイムにbool値の変化を確認することもできますので試してみてください。

イメージ説明

もしまだ問題が解決しないようでしたら、「shootbuttonがtrueにならないことをどうやって確認したのか?」およびその根拠となる画像を添付していただけたら回答がしやすいです。

投稿2018/09/17 11:53

I_love_yadoran

総合スコア20

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

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

syah

2018/09/17 13:26

回答ありがとうございます。 追記したので、確認をよろしくお願いします。
guest

0

自己解決

また前提として言葉が足りなかった部分があったので、本当に申し訳ないです。
Playerオブジェクトは、PlayerプレハブからHierarchyにあるManagerオブジェクトのManagerスクリプトから生成してましたので、正確に言うとPlayer(Clone)でした。
イメージ説明

c#

1// Managerの中で、これを使ってPlayer(Clone)を生成しています 2Instantiate(player, player.transform.position, player.transform.rotation);

そして、教えてもらった↓のコードで試しに色々やってみました。

c#

1public class Player : MonoBehaviour 2{ 3 bool shootbutton; 4 bool tmp_shootbutton; 5 6 public void ShootButton() 7 { 8 shootbutton = true; 9 } 10 11 public void noShootButton() 12 { 13 shootbutton = false; 14 } 15 16 void start() 17 { 18 tmp_shootbutton= true; 19 } 20 21 void update() 22 { 23 if(shootbutton != tmp_shootbutton) 24 { 25 tmp_shootbutton = shootbutton; 26 Debug.Log("shootbuttonが" + shootbutton + "に切り替わりました"); 27 } 28 } 29}

それを踏まえたうえでこのような結果がでました。
・Managerから生成しないで、Hierarchy上にPlayerオブジェクト置いた状態にする。
ボタンのEvent Triggerに、Hierarchy上のPlayerオブジェクトを参照させると、shootbuttonの値の変化を見ることができた。

・ManagerからPlayer(Clone)を生成する。
ボタンのEvent Triggerに、Player(Clone)の元であるPlayerプレハブを参照させると、shootbuttonの値の変化を見れなかった。

-しかし、シーンの再生中にボタンのEvent Triggerに、Player(Clone)自体を参照させると、shootbuttonの値の変化を見ることができた。(シーンの再生を停め、もう一回再生してみるとshootbuttonの値の変化は見れなかった。)
また、Playerプレハブ以外でもTestオブジェクトを作ってみて上の動作を再現したりしました。
赤で囲った部分が今回再現するために作ったファイルです。
わかりにくいですが、TestスクリプトがPlayer、Test2スクリプトがManagerを再現します。
イメージ説明

c#

1// testの中身です。Playerスクリプトの再現をします。 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5public class Test : MonoBehaviour 6{ 7 public bool shootbutton; 8 bool tmp_shootbutton; 9 10 public void ShootButton() 11 { 12 shootbutton = true; 13 } 14 15 public void noShootButton() 16 { 17 shootbutton = false; 18 } 19 20 void Start() 21 { 22 tmp_shootbutton = true; 23 } 24 25 void Update() 26 { 27 if (shootbutton != tmp_shootbutton) 28 { 29 tmp_shootbutton = shootbutton; 30 Debug.Log("shootbuttonが" + shootbutton + "に切り替わりました"); 31 } 32 } 33}

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4// Test2の中身です。Managerの再現をします。 5public class Test2 : MonoBehaviour { 6 7 public GameObject player2; 8 // Use this for initialization 9 void Start () { 10 Instantiate(player2, player2.transform.position, player2.transform.rotation); 11 } 12 13 // Update is called once per frame 14 void Update () { 15 16 } 17} 18

Player2オブジェクトにTest.csをアタッチ。Manager2オブジェクトにTest2.csをアタッチします。
次にPlayer2をプレハブ化します。
そして、↓のようにしてください。
D&D
まずはプレハブのほうからやってみます。
Hierarchyにあるプレハブを削除します。
Event Triggerがプレハブに参照されてることを確認します。
イメージ説明
ボタンを押しても値が変わりませんでした。
次に、Hierarchyからやってみます。Player2プレハブをHierarchyに持ってきます。
Player2プレハブは削除します。
Event Triggerの設定も同様にやります。
イメージ説明
ボタンを押すと値が変わりました。

自分の中の結論?としては
Hierarchy上にあるオブジェクトはEvent Triggerで参照できる
プレハブの場合はEvent Triggerで参照できない
になりました。

根本的な解決にはなってないかもしれませんが、自分が行った解決策をあげます。オブジェクトがHierarchy上に存在し参照すればよいのですから、まずManagerオブジェクトにあるManagerスクリプトでボタンの判定を行います。PlayerスクリプトではManagerスクリプトでボタンの判定を行った値を取得します。そうすることで、HierarchyにPlayerオブジェクトがなくとも、変数の共有をすることでCloneのPlayerオブジェクトでもボタンの判定を取得することができました。

今回、ヒントをくださったI_love_yadoranさん。プログラミング初心者の私に真摯に受け答えして下さり、本当にありがとうございました。

投稿2018/09/18 09:08

編集2018/09/18 09:11
syah

総合スコア16

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

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

0

Debug.Log(("shootbuttonは")+shootbutton);

という一文をupdate内に追記したところ、Inspectorでのチェックボックスと同様に
ボタンを押しているときは「shootbuttonはtrue」
ボタンを押していないときは「shootbuttonはfalse」
と出力されることを確認しました。

updateは1フレームごとに呼び出されるので、毎フレームログを出力しているとすぐに流れてしまいます。
もしかしたらかなり上の方に「shootbuttonはtrue」のログがあるかもしれません。
探してみてください。

また、毎フレームログを出力すると埋もれてやはり見づらいので、以下のように記述するとshootbuttonが切り替わった次のフレームのみにログが出力されるため、見やすくなると思います。
一度お試しください。

C#

1public class Player : MonoBehaviour 2{ 3 bool shootbutton; 4 bool tmp_shootbutton; 5 6 public void ShootButton() 7 { 8 shootbutton = true; 9 } 10 11 public void noShootButton() 12 { 13 shootbutton = false; 14 } 15 16 void start() 17 { 18 tmp_shootbutton= true; 19 } 20 21 void update() 22 { 23 if(shootbutton != tmp_shootbutton) 24 { 25 tmp_shootbutton = shootbutton; 26 Debug.Log("shootbuttonが" + shootbutton + "に切り替わりました"); 27 } 28 } 29}

投稿2018/09/17 14:02

I_love_yadoran

総合スコア20

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

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

syah

2018/09/18 09:17

回答ありがとうございます。 色々試してみたところ、自己解決することができました。
I_love_yadoran

2018/09/18 13:56

試行錯誤の上に自己解決に至ったということで、一番良い結果になったかと思います。 今回、ボタンのon/offはヒエラルキーに設置したManagerオブジェクトで制御し、そのときのbool値をPlayerオブジェクトに渡すという処理でやりたかったことを実現したということですね。 syahさんが実装したようなスクリプト制御・変数の受け渡し等をまとめて担当するオブジェクトをヒエラルキーに置いて、Clone(=インスタンス)とやりとりするという方法はよく使われるテクニックだと思います。 また、今回の件だと、PlayerをInstanciateしたときにボタンオブジェクトにスクリプト側でEventTriggerを設定する方法もあります。 参考:https://qiita.com/_tid_/items/4d418e10bf74f7a5da94 どちらでも同じ結果は得られますが、syahさんが実装されたManagerオブジェクトを経由して変数の受け渡しをする方法が、個人的にはスマートに感じるので良いと思います。 場合によってはスクリプト側からEventTriggerを追加する方がスマートに記述できるときもあると思いますので、「そういう方法もあるんだなー」と頭の片隅に置いておいても良いかと思います。 長くなってしまいましたが、頑張ってください。それでは。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問