🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1466閲覧

アイテムを持っている時にアイテムを取れないようにしているのにもう一回アイテムをとると二回使えてしまう

Um_kok

総合スコア39

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/12/24 02:31

編集2020/12/24 02:38

こんにちは、レースゲームを作っております。
コードです

アイテムフラグを上げるオブジェクト

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Questionblock : MonoBehaviour 6{ 7 private void OnTriggerEnter(Collider other) 8 { 9 if (other.gameObject.CompareTag("Cart")) 10 { 11 other.GetComponentInParent<ItemCatch>().getItem = true; 12 } 13 } 14}

カートについているコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class ItemCatch : MonoBehaviour 6{ 7 public bool getItem; // アイテムをゲットしたかのフラグ 8 private bool haveItem; // アイテムを持っているかのフラグ 9 private bool useItem; // アイテムを使ったかのフラグ 10 private int selectItem; // アイテムを選んだものを入れる 11 private GameObject item; 12 private new Rigidbody rigidbody; 13 14 [SerializeField] private int itemCount; // アイテム数 15 [SerializeField] private float power; // キノコパワー 16 17 void Start() 18 { 19 rigidbody = GetComponent<Rigidbody>(); 20 } 21 void Update() 22 { 23 ChooseItem(); 24 UseItems(); 25 } 26 /// <summary> 27 /// アイテムを選ぶ 28 /// </summary> 29 private void ChooseItem() 30 { 31 if (!getItem) return; 32 if (haveItem) return; 33 34 print(getItem); 35 print("アイテムセレクト"); 36 var itemNumber = (int)Random.Range(0, itemCount); 37 selectItem = itemNumber; 38 getItem = false; 39 useItem = false; 40 haveItem = true; 41 42 } 43 /// <summary> 44 /// アイテムを使う 45 /// </summary> 46 private void UseItems() 47 { 48 if (!haveItem) return; 49 print("アイテム持っている"); 50 switch (selectItem) 51 { 52 case 0: SuperMushroom(); break; 53 } 54 } 55 /// <summary> 56 /// スーパーキノコ 57 /// </summary> 58 private void SuperMushroom() 59 { 60 if (useItem) return; 61 if (Input.GetKeyDown(KeyCode.J) && haveItem){ 62 rigidbody.AddForce(transform.forward * power); 63 haveItem = false; 64 useItem = true; ; 65 print("使った"); 66 } 67 } 68} 69

やった事
上にも書いたのですが、アイテムを持っているときに アイテムをとると 二回使えてしまうというバグがあります。
getItem でアイテムを選び
haveItem でアイテムを持っているときにはreturn で入らないようにし
それでも足りなかったので 新しいbool を作って、useItem を入れて return で返すようにしているのですが、何故か二回アイテムを使えてしまいます。
アイテム数はもう少し増やす予定なのですが、こういう時は配列やListに入れたほうが楽なのでしょうか?
どうかよろしくお願いします。解説やコメントなどくださるとうれしいです。
フラグなどが苦手なのでの考え方などもご教示お願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

回答依頼、ありがとうございます。

見たところ、**「アイテムを持っていたら…」「アイテム用のトリガーに触れたら…」**などの処理をboolでのフラグで頑張って管理しているように見えます。
もっとシンプルに考えるべきかと。

(コード、確認はしましたが手打ちなので誤字脱字あったらすみません)

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Questionblock : MonoBehaviour 6{ 7 private void OnTriggerEnter(Collider other) 8 { 9 if (other.gameObject.CompareTag("Cart")) 10 { 11 // other.GetComponentInParent<ItemCatch>().getItem = true; 12 // ItemCatchのgetItemフラグ操作ではなく、専用の関数を実行する 13 other.GetComponentInParent<ItemCatch>().GetItem(); 14 } 15 } 16}

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class ItemCatch : MonoBehaviour 6{ 7 // public bool getItem; // アイテムをゲットしたかのフラグ 8 private bool haveItem; // アイテムを持っているかのフラグ 9 // private bool useItem; // アイテムを使ったかのフラグ 10 private int selectItem; // アイテムを選んだものを入れる 11 private GameObject item; 12 private new Rigidbody rigidbody; 13 14 [SerializeField] private int itemCount; // アイテム数 15 [SerializeField] private float power; // キノコパワー 16 17 void Start() 18 { 19 rigidbody = GetComponent<Rigidbody>(); 20 } 21 void Update() 22 { 23 // Update()で呼び続ける必要はない 24 /* ChooseItem(); 25 UseItems(); */ 26 27 // キーの入力とアイテム所持のフラグを常に監視 28 if (Input.GetKeyDown(KeyCode.J) && haveItem) { 29 UseItem(); 30 } 31 } 32 33 /// <summary> 34 /// アイテムをゲットしたとき 35 /// 外部から呼ばれるため、アクセス修飾子はpublic 36 /// </summary> 37 public void GetItem() 38 { 39 print("アイテムゲット"); 40 41 print("アイテムセレクト"); 42 // めちゃくちゃシンプルな書き方ですが、関数の実行結果を変数に格納しています。 43 // 詳しくは「unity 関数 返り値」などで調べて見てください。 44 selectItem = ChooseItem(); 45 46 // アイテム所持フラグをtrueに 47 haveItem = true; 48 print("アイテム所持: " + haveItem.ToString()); 49 } 50 51 /// <summary> 52 /// アイテムを選ぶ 53 /// </summary> 54 private int ChooseItem() 55 { 56 /* if (!getItem) return; 57 if (haveItem) return; 58 59 print(getItem); 60 print("アイテムセレクト"); 61 var itemNumber = (int)Random.Range(0, itemCount); 62 selectItem = itemNumber; 63 getItem = false; 64 useItem = false; 65 haveItem = true; */ 66 67 // ChooseItem()が呼ばれるのはGetItem()からだけなので、フラグなどで管理しておく必要はない。 68 // Update()で管理しようとしていた(常にChooseItem()が呼ばれている)ため挙動も不安定だったのかも? 69 70 var itemNumber = (int)Random.Range(0, itemCount); 71 return itemNumber; 72 /* 本来は、return (int)Random.Range(0, itemCount); と 73 記述できますが分かりやすいようにいったん変数に入れています。 */ 74 } 75 76 /// <summary> 77 /// アイテムを使う 78 /// 関数名から s を抜きました 79 /// </summary> 80 private void UseItem() 81 { 82 /* if (!haveItem) return; 83 print("アイテム持っている"); 84 switch (selectItem) 85 { 86 case 0: SuperMushroom(); break; 87 }*/ 88 89 /* UseItem()も、ifを使っての分岐方法の位置を考えれば 90 呼ばれるのはキーを押した瞬間の一度だけなのでフラグ管理は要らない。 */ 91 92 print("アイテムを使う"); 93 switch (selectItem) { 94 case 0: SuperMushroom(); break; 95 } 96 97 // アイテムを使用したので、所持フラグをfalseに 98 haveItem = false; 99 } 100 101 /// <summary> 102 /// スーパーキノコ 103 /// </summary> 104 private void SuperMushroom() 105 { 106 /*if (useItem) return; 107 if (Input.GetKeyDown(KeyCode.J) && haveItem){ 108 rigidbody.AddForce(transform.forward * power); 109 haveItem = false; 110 useItem = true; ; 111 print("使った"); 112 }*/ 113 114 print("スーパーキノコ"); 115 rigidbody.AddForce(transform.forward * power); 116 } 117}

投稿2020/12/24 04:07

PinoMatcha

総合スコア368

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

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

Um_kok

2020/12/24 05:58

お返事遅れてすみません。回答ありがとうございます。 確かにUpdateで回すのは効率が良くないでした。なのでバグが起きていたんでしょうね。 なるほどです。すごくわかりにくいコードを書いていました。原因がわかってすっきりしました。 関数の返り値などあまり使ったことがないので、すごく勉強になりました。 凄くコードが短くなってわかりやすくなりました。ありがとうございます。 困った事があったらまたお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問