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

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

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

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

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

Unity

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

Q&A

1回答

1339閲覧

ハイスコアの保存 unity

hikaaaaaaaa

総合スコア19

C#

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

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

Unity

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

0グッド

0クリップ

投稿2020/05/10 07:06

編集2022/01/12 10:55

unity2Dでゲームを作成しています。

全2ステージのゲームです。
ステージごとのスコアを登録し、スコアシーンでスコアをハイスコア順で
上位の10個を表示させてスクロールできるようにし、
ステージ1とステージ2のスコアをわけたいと考えているのですが、
スコアシーンでの表示がうまく行きません。スコアシーンはスコアシーン1とスコアシーン2に分けております。

ステージ1だけの場合はうまく行ったのですが、ステージ1のデータを複製をしてステージ2のスコアデータを作成とした際にできませんでした。

Listで管理をしており
、スコアの登録まではうまく行っていると思うのですが、スコアシーンでの表示がされない状態になっております。
EnhancedScrollerを用いて実装をしております。
こちらのページを参考にしました。

また、Ranktext(ステージ1)とRanktext2(ステージ2)をpfefab化し、CellViewを双方にアタッチしております。一度ゲームを再生した際には、スクロール内にその子要素にあるテキスト自体は表示がされますが、更新がされておらず、同じ数値(前にプレイした際の数値)が表示されています。

どなたかアドバイスをいただけますと幸いです。

ゲーム終了時のスコアの保存(ステージ1とステージ2)
(ゲームの終了の際にスコア保存をして更新をしております。)

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using UnityEngine.SceneManagement; 6using System; 7 8public class EndSceneManager : MonoBehaviour 9{ 10List<int> highScores = new List<int>(); 11 //第二ステージの場合 12 List<int> highScores2 = new List<int>(); 13 14 15 [SerializeField] 16 Text scoreText, clearText; 17 string[] keyList = new string[10]; 18 19 string[] keyList2 = new string[10]; 20 21 int scoreNumber; 22 int scoreNumber2; 23 24 25//スコアの保存 26public void Return() 27 { 28//ステージ1の場合 29 if (PlayerPrefs.GetInt("secondLap", 0) == 0) 30 { 31 // playerprefsからscoreNumberの分(1~10)だけハイスコアを取ってくる 32 for (int i = 0; i < PlayerPrefs.GetInt("scoreNumber"); i++) 33 { 34 highScores.Add(PlayerPrefs.GetInt(keyList[i])); 35 // Debug.Log("high score add from pref cycle"); 36 } 37 // 今回のスコアをハイスコアに追加する 38 // if finishFlag == true 39 highScores.Add(GameManager.score); 40 // ハイスコアをソート 41 // highScores.Sort((int x, int y) => { return y - x; }); 42 highScores.Sort((x, y) => y - x); 43 44 if (highScores.Count > 10) 45 { 46 highScores.RemoveAt(10); 47 // Debug.Log("memorized score is more than 10"); 48 } 49 // スコアの数を0にリセット 50 scoreNumber = 0; 51 // ハイスコアをplayerprefsに記録 52 // ハイスコアの個数分scoreNumberをインクリメント 53 for (int i = 0; i < highScores.Count; i++) 54 { 55 // Debug.Log(highScores[i]); 56 PlayerPrefs.SetInt(keyList[i], highScores[i]); 57 scoreNumber++; 58 // Debug.Log("set prefs high score cycle"); 59 } 60 // ハイスコアの個数をplayerprefsに記録 61 PlayerPrefs.SetInt("scoreNumber", scoreNumber); 62 SceneManager.LoadScene("MainScene"); 63 64 } 65 66 67//ステージ2の場合 68 else if (PlayerPrefs.GetInt("secondLap", 0) == 1) { 69 70 // playerprefsからscoreNumberの分(1~10)だけハイスコアを取ってくる 71 for (int i = 0; i < PlayerPrefs.GetInt("scoreNumber2"); i++) 72 { 73 highScores2.Add(PlayerPrefs.GetInt(keyList2[i])); 74 // Debug.Log("high score add from pref cycle"); 75 } 76 // 今回のスコアをハイスコアに追加する 77 // if finishFlag == true 78 highScores2.Add(GameManager.score); 79 // ハイスコアをソート 80 // highScores.Sort((int x, int y) => { return y - x; }); 81 highScores2.Sort((x, y) => y - x); 82 83 if (highScores2.Count > 10) 84 { 85 highScores2.RemoveAt(10); 86 // Debug.Log("memorized score is more than 10"); 87 } 88 // スコアの数を0にリセット 89 scoreNumber2 = 0; 90 // ハイスコアをplayerprefsに記録 91 // ハイスコアの個数分scoreNumberをインクリメント 92 for (int i = 0; i < highScores2.Count; i++) 93 { 94 // Debug.Log(highScores[i]); 95 PlayerPrefs.SetInt(keyList2[i], highScores2[i]); 96 scoreNumber2++; 97 // Debug.Log("set prefs high score cycle"); 98 } 99 // ハイスコアの個数をplayerprefsに記録 100 PlayerPrefs.SetInt("scoreNumber2", scoreNumber2); 101 SceneManager.LoadScene("MainScene"); 102 103 104 105 } 106 } 107 108 109 110

スコアの表示(スコアシーンのステージ1のスクリプト)

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class HighScoreManager : MonoBehaviour 7{ 8 List<GameObject> highScoreTexts = new List<GameObject>(); 9 10 void Start() 11 { 12 // Debug.Log(PlayerPrefs.GetInt("scoreNumber")); 13 14 for (int i = 0; i < PlayerPrefs.GetInt("scoreNumber"); i++) 15 { 16 // Debug.Log(PlayerPrefs.GetInt((i + 1).ToString())); 17 highScoreTexts.Add(Instantiate( 18 Resources.Load<GameObject>("Prefabs/RankText"), 19 transform.position, 20 Quaternion.identity 21 )); 22 highScoreTexts[i].transform.SetParent(transform); 23 highScoreTexts[i].transform.localScale = new Vector3(1, 1, 1); 24 highScoreTexts[i].GetComponent<RectTransform>().anchoredPosition = new Vector3(65, 400 - (145 * (i + 1))); 25 highScoreTexts[i].transform.Find("Text").GetComponent<Text>().text 26 = (i + 1).ToString() + ". " + PlayerPrefs.GetInt((i + 1).ToString()).ToString(); 27 // highScoreTexts[i].transform.Find("Text").GetComponent<Text>().text = "aiueo"; 28 } 29 30 31 32 33 34 } 35 36 void Update() 37 { 38 39 } 40} 41

スコアの表示(スコアシーンのステージ2のスクリプト)

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6public class HighScoreManager2 : MonoBehaviour 7{ 8 9 List<GameObject> highScoreTexts2 = new List<GameObject>(); 10 11 void Start() 12 { 13 // Debug.Log(PlayerPrefs.GetInt("scoreNumber")); 14 15 for (int i = 0; i < PlayerPrefs.GetInt("scoreNumber2"); i++) 16 { 17 // Debug.Log(PlayerPrefs.GetInt((i + 1).ToString())); 18 highScoreTexts2.Add(Instantiate( 19 Resources.Load<GameObject>("Prefabs/RankText2"), 20 transform.position, 21 Quaternion.identity 22 )); 23 highScoreTexts2[i].transform.SetParent(transform); 24 highScoreTexts2[i].transform.localScale = new Vector3(1, 1, 1); 25 highScoreTexts2[i].GetComponent<RectTransform>().anchoredPosition = new Vector3(65, 400 - (145 * (i + 1))); 26 highScoreTexts2[i].transform.Find("Text2").GetComponent<Text>().text 27 = (i + 1).ToString() + ". " + PlayerPrefs.GetInt((i + 1).ToString()).ToString(); 28 // highScoreTexts[i].transform.Find("Text").GetComponent<Text>().text = "aiueo"; 29 } 30 31 32 33 34 35 } 36 37 void Update() 38 { 39 40 } 41} 42

pfefabのRankTextとRankText2にアタッチ

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using EnhancedUI.EnhancedScroller; 5using UnityEngine.UI; 6 7public class CellView : EnhancedScrollerCellView 8{ 9 public Text m_nameTextUI; 10 11 public void SetData(ScrollerData data) 12 { 13 m_nameTextUI.text = data.m_name; 14 } 15} 16

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using EnhancedUI.EnhancedScroller; 5 6public class ScrollerController : MonoBehaviour, IEnhancedScrollerDelegate 7{ 8 9 public CellView m_cellPrefab; 10 11 12 private ScrollerData[] m_list; 13 14 15 private void Start() 16 { 17 18 19 20 } 21 22 public int GetNumberOfCells(EnhancedScroller scroller) 23 { 24 return m_list.Length; 25 26 } 27 28 29 30 public float GetCellViewSize(EnhancedScroller scroller, int dataIndex) 31 { 32 return 60f; 33 } 34 35 36 public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex) 37 { 38 var cellView = scroller.GetCellView(m_cellPrefab) as CellView; 39 40 cellView.SetData(m_list[dataIndex]); 41 42 return cellView; 43 44 45 } 46 47 48 49} 50

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class ScrollerData 6{ 7 public string m_name; 8} 9

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

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

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

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

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

YASU_jrt

2020/05/11 03:21

EndSceneManagerクラスの keyList,keyList2 の変数には具体的にはどのような値が入っているのでしょうか? keyList,keyList2 は PlayerPrefs に保存する各スコアのキーとして使用しているようですが HighScoreManager, HighScoreManager2 クラスの PlayerPrefsからスコアを取得しているであろう処理は両方とも PlayerPrefs.GetInt((i + 1).ToString()) とステージ1とステージ2を区別できていない気がします。
hikaaaaaaaa

2020/05/11 03:27

ご回答ありがとうございます。 こちら、GameManager.score(ゲームシーンでの得点が入っています) Game内では、 int avoidCount = 0; public int AvoidCount { get { return avoidCount; } set { avoidCount = value; } } とし、score = avoidCount;として値を代入しております。
YASU_jrt

2020/05/11 03:41

得点の値そのものではなく、その得点を PlayerPrefs.SetInt() を使って保存している際のキーについてお聞きしたいです。 // ハイスコアをplayerprefsに記録 と書かれている個所には PlayerPrefs.SetInt(keyList[i], highScores[i]); PlayerPrefs.SetInt(keyList2[i], highScores2[i]); を使って PlayerPrefs にスコアを保存していますが、 keyList, keyList2 の中身にはどんな文字列を設定していますか? スクリプトを見る限り keyList, keyList2 に値を設定している個所が見当たりません。 PlayerPrefs.SetInt() スクリプトリファレンス https://docs.unity3d.com/ja/current/ScriptReference/PlayerPrefs.SetInt.html
hikaaaaaaaa

2020/05/11 03:59

セーブについての理解が乏しく、答えになっていなかったらすみません。 、private string highScoresKey = "highScoresKey"と private string highScore2sKey = "highScoresKey2";いう形で設定をしております。
YASU_jrt

2020/05/11 05:17

質問が複雑になってしまい申し訳ないです。 質問で記述された EndSceneManager のスクリプトには string[] keyList = new string[10]; string[] keyList2 = new string[10]; とあります。 この string の配列には何か文字列を設定していますか? スクリプト内で設定している箇所が無いように思えます。
hikaaaaaaaa

2020/05/11 05:20

こちらの理解不足で申し訳ございまん。。 こちら設定はしていないと思います。。
YASU_jrt

2020/05/11 06:50

ちなみに同じような内容の質問をあげられているようですが、 スコアの保存だけに関しての回答はそちらにしたほうがいいですか? https://teratail.com/questions/260537
hikaaaaaaaa

2020/05/11 06:51

こちらで大丈夫です。 ありがとうございます。。
guest

回答1

0

こんにちは。
私はEnhancedScrollerに関しては詳しくないので、全ての問題が解決されるかはわかりませんが、
スコアの保存と取得に関しての修正案を提示致します。

今回スコアの保存に使用している
PlayerPrefs.SetInt()
は第一引数に保存するデータのキーとなる文字列を指定する必要があります。
指定する文字列そのものは何でもいいのですが、別のデータとして保存する場合は違う文字列を指定する必要があります。
PlayerPrefs.SetInt()

例えば、
ステージ1の1番目の得点のキーは、"Stage1_1"
ステージ1の2番目の得点のキーは、"Stage1_2"
ステージ2の1番目の得点のキーは、"Stage2_1"
といった感じにです。

cs

1PlayerPrefs.SetInt("Stage1_1", 10); 2PlayerPrefs.SetInt("Stage1_2", 8); 3PlayerPrefs.SetInt("Stage2_1", 15);

同じキーを使ってPlayerPrefs.SetInt()を使うと上書きされます。

EndSceneManagerクラスのReturn()関数内で
PlayerPrefs.SetInt()を使って得点を保存しているようですが、
キーとして使用しているkeyListお呼びkeyList2は配列の初期化はされていますが、別々の文字列を指定していないため各ステージの得点がすべて同じ保存先に上書きされ正しく保存されていないように見受けられます。

以下のスクリプトのように各ステージの得点毎に別のキーを指定してあげれば正しく保存されると思います。

cs

1// ステージ1の場合 2for (int i = 0; i < PlayerPrefs.GetInt("scoreNumber"); i++) 3{ 4 // stage1_インデックス番号の形で文字列を生成する 5 string key = string.Format("stage1_{0}", i); 6 PlayerPrefs.SetInt(key, highScores[i]); 7} 8// ステージ2の場合 9for (int i = 0; i < PlayerPrefs.GetInt("scoreNumber2"); i++) 10{ 11 // stage2_インデックス番号の形で文字列を生成する 12 string key = string.Format("stage2_{0}", i); 13 PlayerPrefs.SetInt(key, highScores2[i]); 14}

得点を取得する場合もHighScoreManager,HighScoreManager2を見る限り
両方ともPlayerPrefs.GetInt((i + 1).ToString())という形で取得していますが、
上記のPlayerPrefs.SetInt()と同じキーを使うことで正しく得点を取得できると思います。

投稿2020/05/11 07:23

編集2020/05/12 08:13
YASU_jrt

総合スコア33

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

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

hikaaaaaaaa

2020/05/12 02:41

ご回答ありがとうございます。 上記のコードを実装した際に、 string key = string.Format("stage1_{1}", i);のiの部分で書式設定文字列で引数が設定されていません。 と表示がされてしまいます。。
hikaaaaaaaa

2020/05/13 05:59

ご回答ありがとうございます。 上記の通りに実装した際に ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. と出てきてしまいます。 リストの個数以上の範囲を指定しているとの事ですがコード上そのような設定はしていないように思います。。 もしお分かりになるのならばアドバイスいただけますと幸いです。
YASU_jrt

2020/05/13 10:19

ありえるとしたら、highScores が scoreNumber 分用意されていない時などでしょうかね。 エラーが起きる箇所の前にログを仕込んで、実際の数値を確認してみてはいかがでしょうか。 Debug.LogFormat("scoreNumber = {0}", PlayerPrefs.GetInt("scoreNumber")); Debug.LogFormat("highScores count = {0}", highScores.Count); 上記のようなログを仕込むことで、Unityのコンソールウィンドウに実際のスクリプトが動いているときの数値が表示できます。 今回の書き方では {0} の部分に各変数の値が表示される書き方になっています。 これで実際に数値がどのように変動しているかを調べることができます。 それでも原因がわからない場合は、 この質問内容に追記で、修正したスクリプトを記述してもらえれば確認してみますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問