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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

2405閲覧

PlayerPrefs.GetInt で常にデフォルトの値が返されてしまう状態に悩んでいます。

Cl2_CHINO

総合スコア12

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2019/07/20 17:26

編集2019/07/20 17:35

前提・実現したいこと

こんにちは、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です。

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

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

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

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

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

guest

回答1

0

自己解決

Int型とString型を併用するそもそもの仕組みを訂正して、データを保存するのはInt型のみにしデータを読み取る際にString型に変換、String型の状態で桁数をいじったりstring.Insertを用いることで理想の挙動を実現することができました。
おそらく型の異なる PlayerPrefs でキーを統一していたのがよくなかったみたいですね。「試したこと」の欄で失敗したと書いてしまっていたのはよくなかったですね。
駄質問失礼いたしました。閲覧していただいた方及び考えていただいた方々、申し訳ありませんでした

投稿2019/07/21 03:51

Cl2_CHINO

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問