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

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

詳細はこちら
C#

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

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Unity3D

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

Unity

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

Q&A

解決済

1回答

15004閲覧

Unityでスタックオーバーフローしてしまった

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/01/01 09:59

前提・実現したいこと

UnityでUIが変わったり、発砲できたりするようなシステムを作っています。
UIの変更機能を実装しテストに以下のエラーメッセージが発生しました。

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

StackOverflowException: The requested operation caused a stack overflow. FirstPersonGunController.set_SupplyValue (System.Int32 value) <0x1e3a228f5d0 + 0x00016> in <141fe023199f493885009e10446256d3>:0

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class FirstPersonGunController : MonoBehaviour 7{ 8 public enum ShootMode { AUTO, SEMIAUTO } 9 10 public bool shootEnabled = true; 11 12 public ShootMode shootMode = ShootMode.AUTO; 13 public int maxAmmo = 30; 14 public int damage = 1; 15 public float shootInterval = 0.1f; 16 public float shootRange = 50; 17 [SerializeField] 18 int maxSupplyValue = 30; 19 [SerializeField] 20 float supplyInterval = 0.1f; 21 22 public Vector3 muzzleFlashScale; 23 public GameObject muzzleFlashPrefab; 24 public GameObject hitEffectPrefab; 25 [SerializeField] 26 Image ammoGauge; 27 [SerializeField] 28 Text ammoText; 29 [SerializeField] 30 Image supplyGuage; 31 32 bool shooting = false; 33 bool supplying = false; 34 int ammo = 0; 35 int supplyValue = 0; 36 37 GameObject muzzleFlash; 38 GameObject hitEffect; 39 40 void Start() 41 { 42 InitGun(); 43 } 44 45 void Update() 46 { 47 if (shootEnabled & ammo > 0 & GetInput()) 48 { 49 StartCoroutine(ShootTimer()); 50 } 51 if (shootEnabled) 52 { 53 StartCoroutine(SupplyTimer()); 54 } 55 } 56 57 public int Ammo 58 { 59 set 60 { 61 ammo = Mathf.Clamp(value, 0, maxAmmo); 62 63 ammoText.text = ammo.ToString(); 64 65 float scaleX = (float)ammo / maxAmmo; 66 ammoGauge.rectTransform.localScale = new Vector3(scaleX, 1, 1); 67 } 68 get 69 { 70 return ammo; 71 } 72 } 73 74 public int SupplyValue 75 { 76 set 77 { 78 SupplyValue = Mathf.Clamp(value, 0, maxSupplyValue); 79 80 if (SupplyValue >= maxSupplyValue) 81 { 82 Ammo = maxAmmo; 83 supplyValue = 0; 84 } 85 86 float scaleX = (float)supplyValue / maxSupplyValue; 87 supplyGuage.rectTransform.localScale = new Vector3(scaleX, 1, 1); 88 } 89 get 90 { 91 return supplyValue; 92 } 93 } 94 void InitGun() 95 { 96 Ammo = maxAmmo; 97 } 98 99 bool GetInput() 100 { 101 switch (shootMode) 102 { 103 case ShootMode.AUTO: 104 return Input.GetMouseButton(0); 105 106 case ShootMode.SEMIAUTO: 107 return Input.GetMouseButtonDown(0); 108 } 109 return false; 110 } 111 112 IEnumerator ShootTimer() 113 { 114 if (!shooting) 115 { 116 shooting = true; 117 //マズルフラッシュON 118 if (muzzleFlashPrefab != null) 119 { 120 if (muzzleFlash != null) 121 { 122 muzzleFlash.SetActive(true); 123 } 124 else 125 { 126 muzzleFlash = Instantiate(muzzleFlashPrefab, transform.position, transform.rotation); 127 muzzleFlash.transform.SetParent(gameObject.transform); 128 muzzleFlash.transform.localScale = muzzleFlashScale; 129 } 130 } 131 132 Shoot(); 133 134 yield return new WaitForSeconds(shootInterval / 2); 135 136 //マズルフラッシュOFF 137 if (muzzleFlash != null) 138 { 139 muzzleFlash.SetActive(false); 140 } 141 142 //ヒットエフェクトOFF 143 if (hitEffect != null) 144 { 145 if (hitEffect.activeSelf) 146 { 147 hitEffect.SetActive(false); 148 } 149 } 150 yield return new WaitForSeconds(shootInterval / 2); 151 152 shooting = false; 153 } 154 else 155 { 156 yield return null; 157 } 158 } 159 160 IEnumerator SupplyTimer() 161 { 162 if (!supplying) 163 { 164 supplying = true; 165 SupplyValue++; 166 yield return new WaitForSeconds(supplyInterval); 167 supplying = false; 168 } 169 } 170 171 void Shoot() 172 { 173 Ray ray = new Ray(transform.position, transform.forward); 174 RaycastHit hit; 175 176 //レイを飛ばして、ヒットしたオブジェクトの情報を得る 177 if (Physics.Raycast(ray, out hit, shootRange)) 178 { 179 //ヒットエフェクトON 180 if (hitEffectPrefab != null) 181 { 182 if (hitEffect != null) 183 { 184 hitEffect.transform.position = hit.point; 185 hitEffect.transform.rotation = Quaternion.FromToRotation(Vector3.forward, hit.normal); 186 hitEffect.SetActive(true); 187 } 188 else 189 { 190 hitEffect = Instantiate(hitEffectPrefab, hit.point, Quaternion.identity); 191 } 192 } 193 //★ここに敵へのダメージ処理などを追加 194 } 195 Ammo--; 196 } 197}

試したこと

無限ループに入ると起きるというサイトを見たので、そのような部分を探したりデバッグログ出力を付けたりしましたが、わかりませんでした。

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

Unity : 2019.2.11f1
VisualStudio : 2017 community

このサイトを参考にやっています。このページまでやりました。
https://unity.moon-bear.com/zombie-slayer/gauge-and-score/

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

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

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

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

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

guest

回答1

0

ベストアンサー

SupplyValueプロパティのセッター内部でSupplyValue = Mathf.Clamp(value, 0, maxSupplyValue);と値をセットしています。
これにより、SupplyValueプロパティのセッターが呼ばれることになり永久ループに陥ります。

他のプロパティでもそうですが、プロパティ名と値を保持する変数の名前は違うものにしましょう。
大文字と小文字の違いくらいだと今回のように間違う可能性が高いです。

投稿2020/01/01 10:56

YAmaGNZ

総合スコア10469

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

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

退会済みユーザー

退会済みユーザー

2020/01/01 11:09

すみません。具体的にどう対処すればいいのでしょうか
YAmaGNZ

2020/01/01 11:32

何故ここで永久ループになるか理解できましたか?
退会済みユーザー

退会済みユーザー

2020/01/03 06:36

はい、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問