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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
まず、SingletonMonoBehaviorは標準ライブラリに無いため、どのSingletonMonoBehavior実装であるかがわからないと正確なところがわかりません。後は推測で書きます。
- 普通ならAwakeをoverrideして、その中でDontDestoryOnLoad()を呼び出せばOKです。起きている現象は、変な場所でDontDestoryOnLoadを呼び出しているからかと思います。実装を見直してください。(DoTweenが勝手にDontDestoryOnLoadを呼び出してはいないです)
- 普通の実装なら、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);
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
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
もしかして質問者さんは現在この画像のような状態になっていることを質問文でおっしゃっているのでしょうか?
もしそうであるならば前提の認識が間違っています。
この画像にある「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を書いたのかが提示されていないのでそこはすみませんが分からないです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
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