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

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

ただいまの
回答率

88.04%

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,716

score 15

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

using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;

namespace CompletedAssets
{
    public class Player : MonoBehaviour
    {
        // Spaceshipコンポーネント
        Spaceship spaceship;

        // 弾の連射用
        private float timeCount1;
//-----------------------------------------------------
// 見てほしいところ1 ここから
//-----------------------------------------------------
        // 発射ボタン判定
        bool shootbutton;

        public void ShootButton()
        {
            Debug.Log("ShootButton");
            shootbutton = true;
        }

        public void noShootButton()
        {
            Debug.Log("noShootButton");
            shootbutton = false;
        }
//-----------------------------------------------------
// 読んでほしいところ1 ここまで
//-----------------------------------------------------
        IEnumerator Start ()
    {
        // Spaceshipコンポーネントを取得
        spaceship = GetComponent<Spaceship> ();
                yield return new WaitForSeconds(spaceship.shotDelay);
        }

        IEnumerator GUN()
        {
            // 弾をプレイヤーと同じ位置/角度で作成
            spaceship.Shot(transform);

            // ショット音を鳴らす
            GetComponent<AudioSource>().Play();

            // shotDelay秒待つ
            yield return new WaitForSeconds(spaceship.shotDelay);
        }
//-----------------------------------------------------
// 見てほしいところ2 ここから
//-----------------------------------------------------
    void Update ()
    {
            if (shootbutton)
            {
                Debug.Log("Shoot!");
            }
//-----------------------------------------------------
// 見てほしいところ2 ここまで
//-----------------------------------------------------
            // 右・左
            float x = CrossPlatformInputManager.GetAxisRaw("Horizontal");

            // 上・下
            float y = CrossPlatformInputManager.GetAxisRaw("Vertical");

            // 移動する向きを求める
            Vector2 direction = new Vector2(x, y).normalized;

            // 移動の制限
            Move (direction);

            if (Input.GetKey(KeyCode.Z) || shootbutton)
            {
                timeCount1++;
                if (timeCount1 > spaceship.shotDelay * 10)
                {
                    timeCount1 = 0;
                    StartCoroutine("GUN");
                }
            }
            else
            {
                timeCount1 = spaceship.shotDelay * 10;
            }

        }

        // 機体の移動
        void Move (Vector2 direction)
        {

            // 背景左下の座標を取得
            Vector3 min = bg.GetComponent<Renderer>().bounds.min;

            // 背景右上の座標を取得
            Vector3 max = bg.GetComponent<Renderer>().bounds.max;

            // プレイヤーの座標を取得
            Vector2 pos = transform.position;

            // 移動量を加える
            pos += direction * spaceship.speed * Time.deltaTime;

            // プレイヤーの位置が画面内に収まるように制限をかける
            pos.x = Mathf.Clamp (pos.x, min.x + 0.28f, max.x - 0.32f);
            pos.y = Mathf.Clamp (pos.y, min.y, max.y);

            // 制限をかけた値をプレイヤーの位置とする
            transform.position = pos;
        }

        // ぶつかった瞬間に呼び出される
        void OnTriggerEnter2D (Collider2D c)
        {
            // レイヤー名を取得
            string layerName = LayerMask.LayerToName (c.gameObject.layer);

            // レイヤー名がBullet (Enemy)の時は弾を削除
            if (layerName == "Bullet (Enemy)") {
                // 弾の削除
                Destroy (c.gameObject);
            }

            // レイヤー名がBullet (Enemy)またはEnemyの場合は爆発
            if (layerName == "Bullet (Enemy)" || layerName == "Enemy") {

                // Managerスクリプトからコンティニューコルーチンを呼び出す
                FindObjectOfType<Manager>().Continue();

                // 爆発する
                spaceship.Explosion ();

                // プレイヤーを削除
                Destroy (gameObject);
            }
        }
    }
}


デバッグしてみたときは表示されてましたが、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);
としました。

void Update ()
        {
            Debug.Log(("shootbuttonは")+shootbutton);
            if (shootbutton)
            {
                Debug.Log("Shoot!");
            }
            // 右・左
            float x = CrossPlatformInputManager.GetAxisRaw("Horizontal");

            // 上・下
            float y = CrossPlatformInputManager.GetAxisRaw("Vertical");

            // 移動する向きを求める
            Vector2 direction = new Vector2(x, y).normalized;

            // 移動の制限
            Move (direction);

            if (Input.GetKey(KeyCode.Z) || shootbutton)
            {
                timeCount1++;
                if (timeCount1 > spaceship.shotDelay * 10)
                {
                    timeCount1 = 0;
                    StartCoroutine("GUN");
                }
            }
            else
            {
                timeCount1 = spaceship.shotDelay * 10;
            }

        }


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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+2

掲載されているスクリプトの「見てほしいところ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 22:26

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

    キャンセル

check解決した方法

+1

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

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


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

public class Player : MonoBehaviour
{
  bool shootbutton;
  bool tmp_shootbutton;

  public void ShootButton()
  {
    shootbutton = true;
  }

  public void noShootButton()
  {
    shootbutton = false;
  }

  void start()
  {
    tmp_shootbutton= true;
  }

  void update()
  {
    if(shootbutton != tmp_shootbutton)
    {
      tmp_shootbutton = shootbutton;
      Debug.Log("shootbuttonが" + shootbutton + "に切り替わりました");
    }
  }
}


それを踏まえたうえでこのような結果がでました。
・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を再現します。
イメージ説明

// testの中身です。Playerスクリプトの再現をします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
    public bool shootbutton;
    bool tmp_shootbutton;

    public void ShootButton()
    {
        shootbutton = true;
    }

    public void noShootButton()
    {
        shootbutton = false;
    }

    void Start()
    {
        tmp_shootbutton = true;
    }

    void Update()
    {
        if (shootbutton != tmp_shootbutton)
        {
            tmp_shootbutton = shootbutton;
            Debug.Log("shootbuttonが" + shootbutton + "に切り替わりました");
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Test2の中身です。Managerの再現をします。
public class Test2 : MonoBehaviour {

    public GameObject player2;
    // Use this for initialization
    void Start () {
        Instantiate(player2, player2.transform.position, player2.transform.rotation);
    }

    // Update is called once per frame
    void Update () {

    }
}


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さん。プログラミング初心者の私に真摯に受け答えして下さり、本当にありがとうございました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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

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

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

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

public class Player : MonoBehaviour
{
  bool shootbutton;
  bool tmp_shootbutton;

  public void ShootButton()
  {
    shootbutton = true;
  }

  public void noShootButton()
  {
    shootbutton = false;
  }

  void start()
  {
    tmp_shootbutton= true;
  }

  void update()
  {
    if(shootbutton != tmp_shootbutton)
    {
      tmp_shootbutton = shootbutton;
      Debug.Log("shootbuttonが" + shootbutton + "に切り替わりました");
    }
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/18 18:17

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

    キャンセル

  • 2018/09/18 22:56

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

    キャンセル

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

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る