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

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

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

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

Unity

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

Q&A

3回答

4497閲覧

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

zarakima

総合スコア15

C#

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

Unity

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

0グッド

0クリップ

投稿2018/06/27 05:44

編集2018/06/27 15:08

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

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

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

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

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

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

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

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

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

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

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

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

guest

回答3

0

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

  1. 普通ならAwakeをoverrideして、その中でDontDestoryOnLoad()を呼び出せばOKです。起きている現象は、変な場所でDontDestoryOnLoadを呼び出しているからかと思います。実装を見直してください。(DoTweenが勝手にDontDestoryOnLoadを呼び出してはいないです)
  2. 普通の実装なら、static ScoreManager Instanceなどが定義されているので、ScoreManager.InstanceでScoreManagerのインスタンスがどこでも取得出来ます。DontDestoryOnLoadが変なところで呼び出される実装を修正すれば普通にあとはScoreManagerのフィールドまたはプロパティとして保持すれば良いかと思います。

csharp

1public class ScoreManager : SingletonMonoBehaviour<ScoreManager> 2 public int Score{get;set;} 3 //継承元のAwake実装がvirtualになっていない場合、virtualに変更する必要があります。 4 protected override void Awake() 5 { 6 base.Awake(); 7 if(Instance == this) { 8 DontDestoryOnLoad(this.gameObject); 9 } 10 } 11} 12 13//他からの呼び出し 14Debug.Log(ScoreManager.Instance.Score); 15

投稿2018/06/27 05:59

編集2018/06/27 06:08
takezoux2

総合スコア3

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

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

zarakima

2018/06/27 06:12

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

2018/06/27 11:54 編集

ありがとうございます。実装を進めています。 //他からの呼び出し Debug.Log(ScoreManager.Instance.Score); ですが、実行すると呼び出し側で実装した行で「NullReferenceExeption」となってしまいます。 「普通の実装なら、static ScoreManager Instanceなどが定義されている」がおそらく定義されていないと思われるのですが、 呼び出し側で参照が必要になりますか。
takezoux2

2018/06/28 02:00

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

0

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

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

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

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

C#

1GameObject ScoreManagerObject; 2ScoreManager scoreManager; 3ScoreManagerObject= GameObject.FindGameObjectWithTag("scoreManager"); 4scoreManager= ScoreManagerObject.GetComponent<Data_cabinet>();

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

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

投稿2018/06/27 12:20

akki

総合スコア91

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

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

zarakima

2018/06/27 15:01 編集

ご回答有り難うございます。やはり参照が必要なのですね。 参照を付けた状態で実行したところ、エラーは出ませんが、シーンをまたいでデータの持ち越しができません。 DoTweenで生成された以外の(データ持ち越し用の)「DontDestroyOnLoad」が生成されていないようです。 考えられる原因がありましたらご教示下さい。 ScoreManagerに記述されているDontDestroyOnLoadは、takezoux2様の実装例にある protected override void Awake() { base.Awake(); if(Instance == this) { DontDestoryOnLoad(this.gameObject); } } になります。
zarakima

2018/06/29 01:02

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

0

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

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

csharp

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using DG.Tweening; 5 6// 適当なアニメーション中にシーンをロードし直すスクリプト 7public class DoMove : MonoBehaviour { 8 9 void Start () { 10 DOTween.Init(); 11 // 10秒間のアニメーション 12 transform.DOMove(new Vector3(2, 0, 0), 10f).Play(); 13 StartCoroutine(ReloadScene()); 14 } 15 16 IEnumerator ReloadScene() 17 { 18 // 3秒後にシーンをLoadし直す = Animation終了前にシーン遷移 19 yield return new WaitForSeconds(3); 20 UnityEngine.SceneManagement.SceneManager.LoadScene("Main"); 21 } 22 23}

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

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

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

csharp

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

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

投稿2018/06/27 07:48

takezoux2

総合スコア3

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問