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

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

詳細はこちら
Unity

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

Q&A

解決済

2回答

5249閲覧

Unityで別シーンから変数を呼び出す方法で困っています

TaroNoguchi

総合スコア18

Unity

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

0グッド

1クリップ

投稿2019/10/02 03:52

編集2019/10/02 04:33

Unityで落ち物カウントゲームを作っています。
シーンは3つあり、
StartScene, MainScene, GameOverSceneです。

今回の質問はMainSceneにてゲームをプレイして、その際のスコアを格納している変数(これはScoreController.csに記述)をGameOverSceneで呼び出して結果画面として表示する(これはResult.csに記述)と言った状況です。
以下のようなスクリプトを書いております。

Csharp

1// ScoreController.cs 2 3using UnityEngine; 4using UnityEngine.UI; 5using System.Collections; 6 7public class ScoreController : MonoBehaviour { 8 9 public int score = 0; 10 GameObject scoreText; 11 12 13 public void AddScore(){ 14 this.score += 1; 15 } 16 17 void Start () { 18 this.scoreText = GameObject.Find ("Score"); 19 DontDestroyOnLoad(this); 20 } 21 22 /* 23 public int getScore(){ 24 return score; 25 } 26 */ 27 28}

AddScoreメソッドのトリガーとなっているのは、落ち物をキャッチする(得点を認める動作)別ファイル(HatController.cs)の関数OnTriggerEnter2Dが動作した時です↓

C#

1// HatController.cs 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6 7public class HatController : MonoBehaviour 8{ 9 ... 10 11 12 void OnTriggerEnter2D(Collider2D coll) { 13 GameObject.Find("Canvas").GetComponent<ScoreController>().AddScore(); 14 Destroy(coll.gameObject); 15 } 16 17 18 19}

ここからが本題ですが、ScoreController.csで更新した変数scoreを以下のスクリプトResult.csで呼び出したいのです。

C#

1// Result.cs 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6using UnityEngine.UI; 7 8public class Result : MonoBehaviour 9{ 10 GameObject resultScore; 11 void Start() 12 { 13 int result = ScoreController.score; 14 this.resultScore = GameObject.Find ("Result"); 15 resultScore.GetComponent<Text>().text = "SCORE: " + result.ToString("D4"); 16 } 17 18} 19

しかし、Unity画面でエラーメッセージAssets/Scripts/Result.cs(11,22): error CS0120: An object reference is required for the non-static field, method, or property 'ScoreController.score'と表示されてしまいます。

static変数などを使えば良いなど調べてやってみることはやってみたのですが、staticを使うとHatController.csからScoreController.csAddScoreのトリガーを引けなかったりします。
こちらのサイトの内容などはすでにやってみましたができません。

対処法ご存知の方がいらっしゃいましたら教えてください!

追記(10/2 13:30)

以下のようにScoreController.csResult.csを書き換えたところ、エラーは無くなりましたがMainSceneにてスコアが反映されず、またGameOverSceneにてスコア文字列が出てこなくなってしまいました。

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

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

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

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

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

guest

回答2

0

自己解決

staticな変数のりよう

一夜明けて、やはりstaticな変数として導入することがシンプルにできそうだったのでやってみたらできました。

c#

1//ScoreController.cs 2 3... 4 // まず`ScoreController.cs`で変数をstaticで宣言する。 5 public static int score = 0; 6... 7 8 // AddScoreメソッドのscoreからthisを取る 9 public void AddScore(){ 10 score += 1; 11 } 12... 13 // GetScoreメソッドをstaticなメソッドにする 14 public static int GetScore(){ 15 return score; 16 } 17

c#

1// Result.cs 2 3... 4 // ScoreController.GetScoreで変数を呼び出す 5 int result = ScoreController.GetScore(); 6

これでできるようになりました。

投稿2019/10/03 02:31

TaroNoguchi

総合スコア18

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

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

0

ScoreControllerへの参照がないからだと思います。
int result = ScoreController.score; と言われていますが、一体どのScoreControllerのことを言っているのかがスクリプト側からはわかりません。

なので参照先をFindなりアタッチなりで設定してあげればどうでしょうか。

#追記
状況再現するのがめんどくさかったのでかなり無理矢理作りましたが、表示を更新すれば問題なく動いているように思います。
デバッグ用に画面をクリックすればAddScoreを実行してテキストを更新することでテキストにスコアを反映させています。

cs

1// Result.cs 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6using UnityEngine.UI; 7 8public class Result : MonoBehaviour { 9 GameObject resultScore; 10 void Start() { 11 12 var reffernceObj = GameObject.Find("Score"); 13 ScoreController result = reffernceObj.GetComponent<ScoreController>(); 14 15 this.resultScore = GameObject.Find("Result"); 16 resultScore.GetComponent<Text>().text = "SCORE: " + result.GetScore(); 17 } 18 19 private void Update() { 20 21 // デバッグ用 … マウスクリックしたらスコアを加算して、表示を更新 22 if (Input.GetMouseButtonDown(0)) { 23 var reffernceObj = GameObject.Find("Score"); 24 ScoreController result = reffernceObj.GetComponent<ScoreController>(); 25 result.AddScore(); 26 resultScore.GetComponent<Text>().text = "SCORE: " + result.GetScore(); 27 28 } 29 } 30 31}

投稿2019/10/02 04:05

編集2019/10/02 04:51
hogefugapiyo

総合スコア3302

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

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

TaroNoguchi

2019/10/02 04:22

ありがとうございます。 それだとエラーは解消するのですがスコアが画面に表示されなくなってしまうのです。 ```C# // Result.cs public class Result : MonoBehaviour { GameObject resultScore; GameObject reffernceObj; void Start() { reffernceObj = GameObject.Find("Score"); ScoreController result = reffernceObj.GetComponent<ScoreController>(); this.resultScore = GameObject.Find ("Result"); resultScore.GetComponent<Text>().text = "SCORE: " + result.getScore(); } } ```
hogefugapiyo

2019/10/02 04:32

resultScore.GetComponent<Text>().text = "SCORE: " + result.getScore(); これをStartでやってるので1回しかテキストが更新されません。scoreは最初に0で初期化しているので、おそらく0が表示されておしまいだと思います。 ためしにupdateとかの中で、この記述を回したらどうなりますか? resultScore.GetComponent<Text>().text = "SCORE: " + result.getScore();
hogefugapiyo

2019/10/02 04:52

回答に追記しましたが、デバッグ用に画面クリックでスコア増加&スコア更新を書いてみましたが私の環境だと動いたので、単純にスコアの更新処理をどっかに入れてあげればいいかと思います
TaroNoguchi

2019/10/02 05:26

ScoreController.csのAddScoreメソッドでscore += 1と更新していて、さらにUpdateメソッドで変数scoreを呼び出した時にちゃんとMainSceneではスコアが表示されて更新できているので、更新処理は問題ないと考えております。 その更新されたscoreをGameOverSceneのオブジェクトResultへぶち込みたいのですがそこで詰まっています...
hogefugapiyo

2019/10/02 06:06

メインシーンとは別にゲームオーバーシーンがあり、そちらで参照が取れないってことですかね? それはシーンが変わった際に消されちゃいますので、参照が消えないようにアプローチする必要があります。 staticを使わないなら、たとえばScoreController.cs に対してDontDestroyOnLoad などでシーンまたいで存在できるようにしてあげるとかでしょうか。 https://docs.unity3d.com/ja/2018.2/ScriptReference/Object.DontDestroyOnLoad.html
TaroNoguchi

2019/10/03 02:25

DontDestroyOnLoadを使うとオブジェクトを自分で意識的に消さないといけなくなり、コリンジョンで消滅しなくなってしまったので、ダメだったんです... 懇切丁寧に回答していただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問