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

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

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

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

Unity

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

Q&A

解決済

1回答

300閲覧

Unityで変数が意図せず0になる

jinzin

総合スコア2

C#

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

Unity

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

0グッド

0クリップ

投稿2025/04/21 11:40

実現したいこと

QTE(クイックタイムイベント)を実装しようと思っているのですが,別スクリプトからある関数(GradeCount)を呼び出すと,呼び出された関数があるのスクリプトの変数(c)が0になってしまうことを解決したい。
(同名の関数が別関数として処理されてしまうことの対処法)

発生している問題・分からないこと

2つ目のコードの38行目のDebug.Log(c);で何故か「0」が出力されてしまいます。上のUpdate関数で常時cの値を出力し続けていますが,3から変化はしません。
おそらく同じ名前でも別変数として扱っているのだと思いますが、直し方がわかりません。

エラーメッセージ

error

1エラーメッセージはない。 2強いて言えば、意図しない時点で数値(c)が0と出力される

該当のソースコード

Qte_System.cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using TMPro; 6 7public class Qte_System : MonoBehaviour 8{ 9 // Start is called before the first frame update 10 private string buttom;#指定されるボタンの種類 11 private float m_time;#受付時間 12 private float r_time;#受付残り時間 13 private int success = -2;#成功判定 14 private string grade;#成功ランク 15 [SerializeField]private Image progressRing;#残り時間を可視化するゲージ 16 [SerializeField]private TextMeshProUGUI ButtomText;#押すボタンの名前 17 public Generate_Qte gene_q; 18 19 void Start() 20 { 21 Generate_Qte gene_q = GetComponent<Generate_Qte>(); 22 } 23 24 void Update()#Qteの受付の関数(おそらくここにエラーはない) 25 { 26 //if(Input.GetButtonDown("Fire1")){begin(buttom,m_time);} 27 if(success == 0) 28 { 29    progressRing.fillAmount = r_time/m_time; 30 r_time -= Time.deltaTime; 31 if(r_time > 0) 32 { 33 if(!(buttom == "Up" || buttom == "Down" || buttom == "Right" || buttom == "Left") ){ 34 if(Input.GetButtonDown(buttom)){Success();} 35 }else{ 36 if(Input.GetAxis("Horizontal")>0 && buttom == "Right"){Success();} 37 if(Input.GetAxis("Horizontal")<0 && buttom == "Left"){Success();} 38 if(Input.GetAxis("Vertical")>0 && buttom == "Up"){Success();} 39 if(Input.GetAxis("Vertical")<0 && buttom == "Down"){Success();} 40 } 41 } 42 if(r_time <= 0){ 43 success = -1; 44 grade = "False"; 45 Debug.Log(grade); 46 gene_q.GradeCount(grade); 47 Destroy(this.gameObject); 48 } 49 } 50 } 51 52 public void Success()#成功ランクの決定 53 { 54 success ++; 55 if(r_time/m_time > 0.95){ 56 grade = "Perfect!"; 57 }else if(r_time/m_time > 0.8){ 58 grade = "Excellent!"; 59 }else if(r_time/m_time > 0.6){ 60 grade = "Great"; 61 }else{grade = "Nice";} 62 if(r_time/m_time < 0.05){grade = "Crazy";} 63 Debug.Log(grade); 64 r_time = m_time; 65 gene_q.GradeCount(grade); 66 Destroy(this.gameObject); 67 } 68 69 public void begin(string b, float m_t) 70 { 71 ButtomText.text = b; 72 buttom=b; 73 r_time = m_time = m_t; 74 success = 0;grade = ""; 75 transform.position = new Vector2(Random.Range(-5f,5f),Random.Range(-5f,5f)); 76 } 77}

Generate_Qte.cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Generate_Qte : MonoBehaviour 6{ 7 // Start is called before the first frame update 8 [SerializeField] GameObject obj; #Qteのプレハブ 9 public Transform parent; 10 private int c=0;#一度に何回QTEが発生したかをカウント 11 [SerializeField]public float q_combo=1;#ダメージ倍率 12 void Start()#3回Qteを発生させる 13 { 14 //c = 0;q_combo=1; 15 StartCoroutine(Qte(0,"Space",3f)); 16 StartCoroutine(Qte(2,"Up",2f)); 17 StartCoroutine(Qte(3,"Down",1f)); 18 } 19 20 // Update is called once per frame 21 void Update() 22 { 23 //Debug.Log("["+c+"]");#ここでは常時[3]と表示される 24 } 25 26 27 IEnumerator Qte(float ti,string bo,float m_ti)#ボタン、待ち時間、受付時間を受取、Qteを発生させる 28 { 29 c += 1;#発生した回数だけ増やす 30 yield return new WaitForSeconds(ti); 31 Debug.Log("!!!"+c);#ここでは !!!3 と出力される 32 Generate(bo,m_ti);#Qteを生成 33 //yield break; 34 } 35 36 public void GradeCount(string g)#問題の関数 37 { 38 Debug.Log(c);#何故かここで 0 が出力される 39 c --; 40 if(g == "Perfect!"){ 41 q_combo += 0.5f; 42 } 43 else if(g == "Excellent!"){ 44 q_combo += 0.25f; 45 }else if(g == "Great"){ 46 q_combo += 0.1f; 47 }else if(g == "Nice"){ 48 q_combo += 0.05f; 49 }else if(g == "Grazy"){ 50 q_combo += 1; 51 }else{q_combo += 0;} 52 53 if(c <= 0){# 54 Debug.Log("Damage:"+/*Random.Range(90,110)*/q_combo); 55 q_combo = 1; 56 c = 0; 57 } 58 } 59 60 public void Generate(string b,float m_t) 61 { 62 GameObject pre = Instantiate(obj,parent) as GameObject; 63 Qte_System s = pre.GetComponent<Qte_System>(); 64 s.begin(b,m_t); 65 } 66}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

・変数cの型をpublic intprivate floatにしてみたが変化なし。

補足

もしかしたら、ものすごく初歩的な問題かもしれませんが、解決策が思いつかなく質問させていただきました。こういったところに質問することにもあまり慣れていないので、至らないところがあると思いますが、回答をお願いいたします。

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

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

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

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

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

lehshell

2025/04/21 14:11

Qte_System クラスのフィールドの public Generate_Qte gene_q; にはインスペクター上で何かを設定しているのでしょうか? Qte_System クラスの void Start() {     Generate_Qte gene_q = GetComponent<Generate_Qte>(); } では Generate_Qte のインスタンスを取得してもローカル変数ですので Start メソッド終了後はどこからもアクセスできませんが意図したコードでしょうか? Generate_Qte のスクリプトが何らかのゲームオブジェクトにアタッチされている Generate メソッド内容から Qteのプレハブには Qte_System がアタッチされている ことがわかりますが、Qte_System の Startメソッドから Qteのプレハブには Generate_Qte のスクリプトもアタッチされているようです。 それぞれのスクリプトとゲームオブジェクトとプレハブとのアタッチ関係情報をご提示 願えないでしょうか?
jinzin

2025/04/22 00:13

public Generate_Qte gene_q;にはQTE(Generate_Qte.cs)を設定しています スクリプトは初期状態では Canvas ->QTE(Generate_Qte.cs) スタートするとQteの子オブジェクトとしてQte(Qte_System.cs)のプレハブを生成しています。(Qteはテキストとサークルの2つの子オブジェクトを持っています)
lehshell

2025/04/22 11:53

> QTE(Generate_Qte.cs)を設定しています とはどういう意味でしょうか? QTE というクラス定義が別に存在するのでしょうか? それとも Generate_Qte.cs をアタッチしている QTE という名前の GameObject が存在して これをインスペクター上で設定しているのでしょうか? また、これは #Qteのプレハブ との関係はどうなっているのでしょうか? > public Generate_Qte gene_q;にはQTE(Generate_Qte.cs)を設定しています からはコードの意図は public Generate_Qte gene_q; void Start() {     Generate_Qte gene_q = GetComponent<Generate_Qte>(); } ではなく private Generate_Qte gene_q; void Start() {     gene_q = GetComponent<Generate_Qte>(); } でもなく public Generate_Qte gene_q; void Start() { } ということでしょうか? ゲームオブジェクトとスクリプトの関係を提示されない状況では > 変数(c)が0になってしまう の調査のアプローチとして次の2つをお勧めします。 ■ 3 を出力しているところと 0 を出力しているところで InstanceID も一緒に出力して同じインスタンスの話かどうか確認する。 例 Update メソッド内 Debug.Log($"{GetInstanceID()} [{c}]"); Qte コルーチン内 Debug.Log($"{GetInstanceID()} !!! {c}"); GradeCount メソッド内 Debug.Log($"{GetInstanceID()} GradeCount {c}"); ■ c-- の影響の排除 GradeCount メソッド内の c--; をコメントにして再現するか確認する
lehshell

2025/04/22 12:25

すみません、例を訂正します。 Update メソッド内 Debug.Log($"{gameObject.GetInstanceID()} [{c}]"); Qte コルーチン内 Debug.Log($"{gameObject.GetInstanceID()} !!! {c}"); GradeCount メソッド内 Debug.Log($"{gameObject.GetInstanceID()} GradeCount {c}");
jinzin

2025/04/23 02:23

コメントありがとうございました。 一応解決?しました。 17行目のpublic Generate_Qte gene_q;でインスペクター上でQTEが入らなかったため、QTEをプレハブ化して入れているのがよくなかったようです。 インスペクターで参照ではなくスクリプト内でgene_q = GameObject.Find("QTE");を使って参照をこなうようにしたら思うように動作しました。 無意味にプレハブ化してしまったことで誤作動を起こしたようです。 ベストアンサーに選びたいので同じ内容を回答欄に投稿いただけますでしょうか?
lehshell

2025/04/23 13:49

私のコメントは関係していないと思います。 自己解決としてご自身で回答されるのが適切と思います。
guest

回答1

0

自己解決

スクリプトをインスペクターで参照させるために、プレハブ化してしまったことが原因でした。
GameObject.Find()で参照することで解決できました。
インスペクターの参照について指摘くださったことができました。
質問に答えてくださり、ありがとうございました。

投稿2025/04/24 04:15

jinzin

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問