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

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

ただいまの
回答率

90.32%

  • C#

    7714questions

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

  • Unity

    4430questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

シーン間でのスコア持ち越しとDontDestroyOnLoadについて

受付中

回答 3

投稿 編集

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

zarakima

score 7

Unityで、シーン間でのスコア持ち越しについて質問します。

SingletonMonoBehaviorを継承したScoreManagerで、シーンをまたいだScoreの管理をしたいと思っていますが、

1.ScoreManagerの中にスコアを保持する変数と、DontDestroyOnLoadを実装する
2.他のスクリプト(そのシーンでの得点を保持しているスクリプト)からそれを呼び出す

という実装は、具体的にどの様になるのでしょうか。
いろいろ調べてみたのですが、この例に当てはまるものがなくいま一つよくわかりません。
(SingletonMonoBehaviorはすでにあります)

また、現在シーン内でDoTweenを使用しているのですが、
DoTweenで物体に移動をかけるとDoTweenによってDontDestroyOnLoadが生成されてしまいます。

DontDestoyOnLoadは、シーンをまたぐと増えていってしまい、どこかで削除しなければならないのですが、スコア持ち越しに使用しているDontDestroyOnLoadと、DoTweenで生成されるDontDestroyOnLoadを判別できる方法があればご教示ください。
※DoTweenのDontDestroyOnLoadはシーンをまたいでも増えません。
スコアを保持するためのDontDestroyOnLoadは増えると思われるので、DoTweenのDontDestroyOnLoadを間違って削除しないようにしたいと考えています。

・実装しているコードを書きたいのですが、概要がよくわからずコードの記述ができません。
コードが必要な場合は、ヒントを頂ければ実装してみてお返事させて下さい。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+1

まず、SingletonMonoBehaviorは標準ライブラリに無いため、どのSingletonMonoBehavior実装であるかがわからないと正確なところがわかりません。後は推測で書きます。

  1. 普通ならAwakeをoverrideして、その中でDontDestoryOnLoad()を呼び出せばOKです。起きている現象は、変な場所でDontDestoryOnLoadを呼び出しているからかと思います。実装を見直してください。(DoTweenが勝手にDontDestoryOnLoadを呼び出してはいないです)
  2. 普通の実装なら、static ScoreManager Instanceなどが定義されているので、ScoreManager.InstanceでScoreManagerのインスタンスがどこでも取得出来ます。DontDestoryOnLoadが変なところで呼び出される実装を修正すれば普通にあとはScoreManagerのフィールドまたはプロパティとして保持すれば良いかと思います。
public class ScoreManager : SingletonMonoBehaviour<ScoreManager>
    public int Score{get;set;}
    //継承元のAwake実装がvirtualになっていない場合、virtualに変更する必要があります。
    protected override void Awake()
    {
        base.Awake();
        if(Instance == this) {
            DontDestoryOnLoad(this.gameObject);
        }
    }
}

//他からの呼び出し
Debug.Log(ScoreManager.Instance.Score);

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/06/27 15:12

    丁寧なご回答ありがとうございます。
    1. SingletonMonoBehaviorはUniRxのものではないです(UniRxを導入していないため)
    2. DontDestroyOnLoadは、実装の中で記述してある箇所がまだありません。(物体が動いた瞬間DontDestroyOnLoadが生成され、ヒエラルキー上のDontDestroyOnLoadをクリックすると、子オブジェクトにDoTweenがあります。)

    キャンセル

  • 2018/06/27 20:51 編集

    ありがとうございます。実装を進めています。

    //他からの呼び出し
    Debug.Log(ScoreManager.Instance.Score);

    ですが、実行すると呼び出し側で実装した行で「NullReferenceExeption」となってしまいます。
    「普通の実装なら、static ScoreManager Instanceなどが定義されている」がおそらく定義されていないと思われるのですが、
    呼び出し側で参照が必要になりますか。

    キャンセル

  • 2018/06/28 11:00

    NullReferenceExceptionが出ているということは、static ScoreManager Instance自体は定義されています。おそらく、他のクラスのAwake内で呼び出している、または使っているSingletonMonoBehaviourの実装がシーン内に一度配置しておかないと行けないなどの制限がある実装になっているのどちらかかと思います。

    キャンセル

0

追加です。
DoTweenが、DoTweenComponentクラスをDontDestroyOnLoadの状態で生成していました。失礼しました。

ただ、DoTween 無償版 1.1.640で以下のようなコードを適当なオブジェクトにアタッチし実行しましたが、DoTweenComponentが複数作られる現象は確認出来ませんでした。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

// 適当なアニメーション中にシーンをロードし直すスクリプト
public class DoMove : MonoBehaviour {

    void Start () {
        DOTween.Init();      
        // 10秒間のアニメーション
        transform.DOMove(new Vector3(2, 0, 0), 10f).Play();      
        StartCoroutine(ReloadScene());
    }

    IEnumerator ReloadScene()
    {
        // 3秒後にシーンをLoadし直す = Animation終了前にシーン遷移
        yield return new WaitForSeconds(3);
        UnityEngine.SceneManagement.SceneManager.LoadScene("Main");
    }

}

DoTween自体を普通に使う分には起きない現象だと思いますので、DoTweenの使い方を見直して見たほうが良いかと思います。

DoTweenで生成されるDontDestroyOnLoadを判別できる方法があればご教示ください。

こちらも一応、判別方法というか取得方法を書いておきますが、根本原因を治すほうが良いので推奨はしません。

var doTweenComponents = GameObject.FindObjectsOfTypeAll(typeof(DG.Tweening.Core.DOTweenComponent));

で全てのDOTweenComponentが取得できるので、後は一つを残してDestroyすれば良いです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

もしかして質問者さんは現在この画像のような状態になっていることを質問文でおっしゃっているのでしょうか?
DontDestroyOnLoad
もしそうであるならば前提の認識が間違っています。
この画像にある「DontDestoryOnLoad」はGameObjectではなく、
"[DOTween]ゲームオブジェクトがDontDestroyOnLoad状態になっている"ことを示す目印に過ぎません。
なのでDOTweenを使用していればこの状態になるのはおかしいことではありません。

その上で質問の回答なのですが、

1.についてはそのままです。ScoreManagerにDontDestroyOnLoadを記述して下さい。
(書き方は探せばたくさん出るので参照して下さい。と言っても一行書くだけですが)

2.はDontDestroyOnLoad状態にしたScoreManagerを他のスクリプト内で探して呼び出してください。
私は

GameObject ScoreManagerObject;
ScoreManager scoreManager;
ScoreManagerObject= GameObject.FindGameObjectWithTag("scoreManager");
scoreManager= ScoreManagerObject.GetComponent<Data_cabinet>();


のようにGameObject.FindGameObjectWithTagを使って、
他のスクリプト内でscoreManagerを呼び出せるようにしています。
「Unity 別のスクリプト」で調べればもっと詳細な情報が出ると思います。

DontDestroyOnLoad状態だと増える一方のスクリプトの消し方は
SingletonMonoBehaviorが使えそうな気がしますが、何を参考にしてSingletonMonoBehaviorを書いたのかが提示されていないのでそこはすみませんが分からないです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/06/27 23:58 編集

    ご回答有り難うございます。やはり参照が必要なのですね。
    参照を付けた状態で実行したところ、エラーは出ませんが、シーンをまたいでデータの持ち越しができません。
    DoTweenで生成された以外の(データ持ち越し用の)「DontDestroyOnLoad」が生成されていないようです。
    考えられる原因がありましたらご教示下さい。

    ScoreManagerに記述されているDontDestroyOnLoadは、takezoux2様の実装例にある
    protected override void Awake()
    {
    base.Awake();
    if(Instance == this) {
    DontDestoryOnLoad(this.gameObject);
    }
    }

    になります。

    キャンセル

  • 2018/06/29 10:02

    文法的にはこれであっているはずなのですが…
    DontDestroyOnLoadが発生せず悩んでおります。

    キャンセル

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

  • C#

    7714questions

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

  • Unity

    4430questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。