前提・実現したいこと
こんにちは、Unity の PlayerPrefs 機能を用いて Player のハイスコアの管理をしたいです。
作っているのはレースゲームでハイスコアは「タイム」になるので、数が少ない方が上位スコアになります。
構想としてはInt型の PlayerPrefs とString型の PlayerPrefs にデータを保存しておいて、Int型のほうでスコアの優劣を判断して、その順番通りにString型の値を並び替える。という形になっています。
発生している問題・エラーメッセージ
Debug時にエラーは発生していませんが、実行してもPlayerPrefs に値が保存されていません。
Debug.Logでキーを出力してみましたが一致しているので、キーが違うわけではないと思います。
詳しい問題点はコードの横にコメントとして書いています。
該当のソースコード
C#ここに言語名を入力
1//かなり長いので一部抜粋させていただきます。それでも長く、序盤に問題点はないと思われるので途中まで読み飛ばしてもらっても問題はないと思います。 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6using TMPro; 7using System; 8 9public class CountScript : MonoBehaviour 10{ 11 float time; 12 int sec, min; 13 int playerRecord; 14 string texts[] = new string[3]; 15 16 string[] records; 17 public int stageNum; 18 public bool goaled; 19 public int recordNum; 20 public string viewable; 21 public string publishText; 22 public int[] playerRecords = new int[3]; 23 24 25 void Update() 26 { 27 if (goaled == true) 28 { 29 return; 30 } 31 time += Time.deltaTime; 32 if (time > 1.0f) 33 { 34 sec++; 35 time = 0; 36 if (sec > 60) 37 { 38 min++; 39 sec = 0; 40 } 41 } 42 texts[0] = min.ToString() + ":"; 43 texts[1] = sec.ToString() + ":"; 44 texts[2] = Mathf.FloorToInt(time * 100).ToString(); 45 for (int i = 0; i < 3; i++) 46 { 47 text[i].text = texts[i]; 48 tmp += texts[i]; 49 } 50 publishText = tmp; 51 tmp = null; 52 } 53//駄コードにはなりますが、ここまでで毎フレームタイムをカウントしています。ここで出力されている publishText は[1:23:14]といったように理想の値になっているのでここまでに原因はないと思います。 54 55//おそらく問題となっているのはここからです 56 57 public void PlayerGoaled() 58 { 59 string prefsKey = "PlayerRecord" + stageNum; //ステージが複数あるので、PlayerPrefsのKeyにステージ番号を足して区別させています。 60 playerRecord = Mathf.FloorToInt(time * 100) + (sec * 100) + (min * 10000); //今回のプレイヤーの記録を大きさを比べられる形にして playerRecord に代入しています。 61 for (int i = 0; i < 3; i++) 62 { 63 playerRecords[i] = PlayerPrefs.GetInt(prefsKey + i, 999999); //これまでのプレイヤーの記録を playerRecords[] に代入しています。 64 } //値が小さいほど良い結果なのでデフォルト値は999999にしています。 65 if (playerRecords[2] > playerRecord) //今回の記録とこれまでの記録のなかで最も低い記録の優劣を判定しています。 66 { 67 playerRecords[2] = playerRecord; 68 Array.Sort(playerRecords); //今回の記録のほうが優秀だった場合それを最も低い記録と入れ替えて、Sortで小さい順(スコアが優秀な順)に並べ替えます。 69 for (int i = 0; i < 3; i++) 70 { 71 Debug.Log(playerRecords[i]); 72//ここで出力されている値ですが、今回の記録以外はすべて999999になってしまっています。つまり、前回の SetInt が機能していないか、Setの際に用いたキーとGetの際に用いたキーが異なるということになります。 73 } 74 for (int i = 0; i < 3; i++) 75 { 76 if (playerRecords[i] == playerRecord) 77 { 78 recordNum = i; //並べ替えた後、今回の記録が上位何番目に入る記録なのかを判定しています。(本来管理したい値がStringのためです。) 79 } 80 PlayerPrefs.SetInt(prefsKey + i, playerRecords[i]); //並べ替えた後の値を PlayerPrefs に入れなおしています。ここが動いていないのかな.. 81 } 82 for (int i = 2; i > recordNum; i--) 83//次に今回の記録が今までで一番の記録だった場合、これまで一位だった記録を二位に、二位だった記録を三位スライドさせる必要があるため、その旨のコード書いています。 84 { 85 PlayerPrefs.SetString(prefsKey + i, PlayerPrefs.GetString(prefsKey + (i - 1), "00:00:00")); 86 } 87 PlayerPrefs.SetString(prefsKey + recordNum, publishText); //そのあと最後にString型の PlayerPrefs に今回の結果の String 値を代入しています。 88 } 89 goaled = true; //フラグ 90 } 91} 92
試したこと
Int型のPlayerPrefsとString型のとで同じキーを用いているのが問題なのかな?と思い各キーを区別させるために最後にSとIを付けてみましたがうまくいきませんでした。
もしこれが問題なのであればもう一度しっかり試してみます。
至る所でDebug.Logで出力を繰り返してみましたが、どのように行っても「先ほど値を入れたはずのPlayerPrefsと全く同じキーから値を取り出しているのに値が取れない。」という状態が続いてしまいます。
補足情報(FW/ツールのバージョンなど)
問題が起こっているのはInt型のPlayerPrefsだけだと思います。String型の方はInt型の方がうまく機能してくれないと問題が起こっているのかどうかわかりづらいところではありますが、他シーンで値を取ったところ入っていることを確認できています。また、現在 PlayerPrefs を用いてデータの管理を行っていますが、それしか方法を知らないだけで別にかたくなに PlayerPrefs にこだわっているわけではありません。ほかに方法がある場合は、「モバイル端末にて使用可能な方法のみ」でご教授いただけたらなと思います。
長くなってしまい申し訳ありません。よろしくお願いします。
すみません、タイトルでかなりわかりづらくなってしまってはいると思うのですが、PlayerPrefs.GetIntが使えないのはこのスクリプト部分だけで、他のスクリプト上では理想の挙動を返してくれているので、Unityそのものに問題があるわけではないと思います。Unityのバージョンは2019.1.6f1です。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。