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

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

ただいまの
回答率

90.00%

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 162

TaroNoguchi

score 4

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

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

// ScoreController.cs

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class ScoreController : MonoBehaviour {

    public int score = 0;
    GameObject scoreText;


    public void AddScore(){
        this.score += 1;
    }

    void Start () {
        this.scoreText = GameObject.Find ("Score");
        DontDestroyOnLoad(this);
    }

    /* 
    public int getScore(){
        return score;
    }
    */

}

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

// HatController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HatController : MonoBehaviour
{
    ...


    void OnTriggerEnter2D(Collider2D coll) {
        GameObject.Find("Canvas").GetComponent<ScoreController>().AddScore();
        Destroy(coll.gameObject);
    }



}

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

// Result.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Result : MonoBehaviour
{
    GameObject resultScore;
    void Start()
    {
        int result = ScoreController.score;
        this.resultScore = GameObject.Find ("Result");
        resultScore.GetComponent<Text>().text = "SCORE: " + result.ToString("D4");
    }

}

しかし、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にてスコア文字列が出てこなくなってしまいました。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

check解決した方法

0

staticな変数のりよう

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

//ScoreController.cs

...
    // まず`ScoreController.cs`で変数をstaticで宣言する。
    public static int score = 0;
...

    // AddScoreメソッドのscoreからthisを取る
    public void AddScore(){
        score += 1;
    }
...
    // GetScoreメソッドをstaticなメソッドにする
    public static int GetScore(){
        return score;
    }
// Result.cs

...
    // ScoreController.GetScoreで変数を呼び出す
    int result = ScoreController.GetScore();

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

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

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

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

追記

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

// Result.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Result : MonoBehaviour {
    GameObject resultScore;
    void Start() {

        var reffernceObj = GameObject.Find("Score");
        ScoreController result = reffernceObj.GetComponent<ScoreController>();

        this.resultScore = GameObject.Find("Result");
        resultScore.GetComponent<Text>().text = "SCORE: " + result.GetScore();
    }

    private void Update() {

        // デバッグ用 … マウスクリックしたらスコアを加算して、表示を更新
        if (Input.GetMouseButtonDown(0)) {
            var reffernceObj = GameObject.Find("Score");
            ScoreController result = reffernceObj.GetComponent<ScoreController>();
            result.AddScore();
            resultScore.GetComponent<Text>().text = "SCORE: " + result.GetScore();

        }
    }

}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/10/02 14:26

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

    キャンセル

  • 2019/10/02 15:06

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

    https://docs.unity3d.com/ja/2018.2/ScriptReference/Object.DontDestroyOnLoad.html

    キャンセル

  • 2019/10/03 11:25

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

    キャンセル

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

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

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