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

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

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

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

Unity

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

Q&A

1回答

2603閲覧

Unityでクリアシーンに最終スコアを表示する方法が知りたいです。

sancor

総合スコア5

C#

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

Unity

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

0グッド

0クリップ

投稿2019/11/08 23:30

編集2019/11/09 14:30

Unityでゲームシーンでの最終スコアをクリアシーンに反映したいのですが、うまくいきません。
ネットに書いてあることも試してみたのですが、やり方が悪いのか上手くいきませんでした。
教えてほしいです。

流れとしては、ゲームシーンで、CursorShotScriptでRayがmatoPrefabを破壊しそのたびにUIDirectorのscoreincrease関数を起動します。
UIDirectorでscoreにmatoPrefabが破壊された回数を表示し、TimerScriptで制限時間が来たらクリアシーンでClearDirector内で最終的なスコアの数値をコンソールに表示するようにしたいです。

まずCursorShotScriptです。

c#

1using UnityEngine; 2using System.Collections; 3using UnityEngine.SceneManagement; 4 5public class CursorShotScript : MonoBehaviour { 6 7 // カーソルに使用するテクスチャ 8 [SerializeField] 9 private Texture2D cursor; 10 [SerializeField] 11 private matoGenerator matoGenerator; 12 public GameObject matoPrefab; 13 GameObject gameobject; 14 15 void Start () { 16 // カーソルを自前のカーソルに変更 17 Cursor.SetCursor(cursor, new Vector2(cursor.width / 2, cursor.height / 2), CursorMode.ForceSoftware); 18 } 19 20 void Update () { 21 // マウスの左クリックで撃つ 22 if(Input.GetButtonDown("Fire1")) { 23 Shot(); 24 } 25 } 26 27 // 敵を撃つ 28 void Shot() { 29 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 30 31 float maxDistance=10; 32 33 RaycastHit2D hit = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction, maxDistance, LayerMask.GetMask("Enemy")); 34 35 if(hit.collider) { 36 matoGenerator.Create(); 37 Destroy(hit.collider.gameObject); 38 GameObject director = GameObject.Find("UIDirector"); 39 director.GetComponent<UIDirector>().scoreincrease(); 40 } 41 if(hit.collider.tag=="Enemy"){ 42 SceneManager.LoadScene("LoseScene"); 43 Debug.Log ("RayがPlayerに当たった"); 44 } 45 } 46} 47

次にUIDirectorです。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class UIDirector : MonoBehaviour { 7 8 public GameObject score; 9 public int score_current=0; 10 // Use this for initialization 11 void Start () { 12 this.score = GameObject.Find("score"); 13 } 14 public void scoreincrease(){ 15 this.score_current++; 16 this.score.GetComponent<Text>().text=score_current.ToString(); 17 } 18} 19

次にTimerScriptです。

c#

1using UnityEngine; 2using System.Collections; 3using UnityEngine.UI; 4using UnityEngine.SceneManagement; 5 6public class TimerScript : MonoBehaviour { 7 8 // トータル制限時間 9 private float totalTime; 10 // 制限時間(分) 11 [SerializeField] 12 private int minute; 13 // 制限時間(秒) 14 [SerializeField] 15 private float seconds; 16 // 前回Update時の秒数 17 private float oldSeconds; 18 private Text timerText; 19 20 void Start () { 21 totalTime = minute * 60 + seconds; 22 oldSeconds = 0f; 23 timerText = GetComponentInChildren<Text>(); 24 } 25 26 void Update () { 27 // 制限時間が0秒以下なら何もしない 28 if (totalTime <= 0f) { 29 return; 30 } 31 // 一旦トータルの制限時間を計測; 32 totalTime = minute * 60 + seconds; 33 totalTime -= Time.deltaTime; 34 35 // 再設定 36 minute = (int) totalTime / 60; 37 seconds = totalTime - minute * 60; 38 39 // タイマー表示用UIテキストに時間を表示する 40 if((int)seconds != (int)oldSeconds) { 41 timerText.text = minute.ToString("00") + ":" + ((int) seconds).ToString("00"); 42 } 43 oldSeconds = seconds; 44 45 if(totalTime <= 0f) { 46 SceneManager.LoadScene("ClearScene"); 47 } 48 } 49}

最後にClearDirectorです。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5using UnityEngine.UI; 6 7 8public class ClearDirector : MonoBehaviour { 9 public GameObject score; 10 11 void Start () 12 { 13 14 } 15 16 // Update is called once per frame 17 void Update () { 18 if(Input.GetMouseButtonDown(0)){ 19 SceneManager.LoadScene("Mainmenu"); 20 } 21 } 22} 23

変な文章で申し訳ありません。
###回答を受けての変更後
snowshinkさんの回答をいただいて変更したときのスクリプトとエラーです
変更したスクリプトはUIDirectorとClearDirectorです

UIDirector

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class UIDirector : MonoBehaviour { 7 8 public Text score; 9 public int score_current=0; 10 // Use this for initialization 11 void Start () { 12 score = GetComponent<Text>(); 13 DontDestroyOnLoad(this.gameObject); 14 } 15 public void scoreincrease(){ 16 this.score_current++; 17 this.score.text=score_current.ToString(); 18 } 19}

ClearDirector

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5using UnityEngine.UI; 6 7 8public class ClearDirector : MonoBehaviour { 9 public GameObject score; 10 void Start () 11 { 12 UIDirector loadScene = FindObjectOfType<UIDirector> (); 13 Debug.Log (loadScene.score); 14 } 15 16 // Update is called once per frame 17 void Update () { 18 if(Input.GetMouseButtonDown(0)){ 19 SceneManager.LoadScene("Mainmenu"); 20 } 21 } 22}

エラー画面はこんな感じです。
イメージ説明
エラー文章は、
NullReferenceException: Object reference not set to an instance of an object
UIDirector.scoreincrease () (at Assets/UIDirector.cs:17)
CursorShotScript.Shot () (at Assets/CursorShotScript.cs:40)
CursorShotScript.Update () (at Assets/CursorShotScript.cs:24)
です。初期配置しているmatoPrefabを破壊したときに発生しました。

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

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

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

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

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

guest

回答1

0

構造がよくわかんないのですが、
ゲームシーンがあって、ここにスコアオブジェクトがあって、
クリアしたらゲームクリアシーンを読み込んでというのであれば、
スコアオブジェクトをシーン読み込みで破棄させないようにしたらどうでしょうか。

Unity

1Start(){ 2 score = GameObject.Find("score"); 3 DontDestoyOnLoad(score); 4}

これで結果が保持され続けるのではないでしょうか。

気になったのですが、スコア表示するテキストオブジェクトとスコアを保持するオブジェクトを別々にする
必要はないのでは。

Unity

1Text score; 2public int score_current = 0; 3 4Start(){ 5 score = GetComponent<Text>(); 6 DontDestoyOnLoad(this.gameObject); 7}I 8 9public void IncreaseScore(){ 10 score_current++; 11 score.text = score_current; 12}

こう変更してscoreにはめて?ください。
これでSceneManager.LoadScene("GameClearScene");しても結果は表示され続けます。

投稿2019/11/09 02:06

編集2019/11/09 02:18
snowshink

総合スコア138

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

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

sancor

2019/11/09 06:45

説明が不足しすぎていたので内容を編集しました。 申し訳ありません。
snowshink

2019/11/09 07:37

追記ありがとうございます。 やはり、シーンを読み込んでいるので、DontDestroyOnLoad(GameObject)で、いい気がします。 ゲーム画面のスコアと別にしたいならscore_currentを取得すればいいですし。 もし、もう試されたのならほかに何を試されたかも教えて下さるとありがたいです。 多分、NullReferenceException(所謂ヌルポ)で悩んでるのではないでしょうか。 Unity開発経験が浅いので正確にこたえられるかは分かりませんが
sancor

2019/11/09 09:02 編集

試させた頂いたのですが、UIDirectorの方のscore.text=score_current;の部分でscore_currentに「intをstringに変換できない」と出たので.ToString()を入れたところ、matoPrefabの破壊時にスコアに加算されなくなってしまいました。コンソールにも同じ部分でその所謂「ヌルポ」が出ています。 そしてClearDirectorの方のStart関数に UIDirector loadScene = FindObjectOfType<UIDirector> (); Debug.Log (loadScene.score); を入れたのですが、LogがNullになってしまいました。
snowshink

2019/11/09 13:15

複雑そうなので、エラーが出たところのエディタ画面を見せて欲しいです。 そこまで詳しくないので直せる保証はないですが、やれるところまで… ログウィンドウのerror on pauseでヌルポが出ると止まります。
sancor

2019/11/09 13:47

追加させていただきました。 よろしくお願いいたします。
snowshink

2019/11/10 13:15

ごめんなさい、TextのscoreをGetComponentで取得するのはやめておいた方がいいですね。 インスペクターから選択するようにしてください。GetComponentとFindは重い処理なので。 Shot()のところもオブジェクトをインスペクターから取得するように。 クラスはGameObjectではなくて、UIDirectorやTextにすれば一々GetComponentする必要もないです。 シングルトンでもいいのですが…(というよりマネージャー系はシングルトンがいい) それで、クリアシーンのTextのStart()でUIDirectorから点数を取得してみてください。 このエラーはUIDirectorのオブジェクトにTextがない為ですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問