はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】PlayerPrefsの一覧を表示、特定(全て)のPlayerPrefsを削除する【エディタ拡張】

unityのバージョン unity2018.4.0f1

はじめに

今回はPlayerPrefsの一覧を表示、特定(全て)のPlayerPrefsを削除するエディタ拡張についての記事になります!

以下の動画のようなエディタ拡張を作ってみました。

PlayerPrefsTools.cs

using System.Collections.Generic;

namespace PlayerPrefsEditor
{

    /// <summary>
    /// Windowのみ対応
    /// </summary>
    public class PlayerPrefsTools
    {
        private static readonly string[] NON_TARGET_KEY = { "unity.cloud_userid", "unity.player_sessionid", "unity.player_session_count","UnityGraphicsQuality" };

        public static void GetAllPlayerPrefKeys(ref List<string> keys)
        {
            if (keys != null)
            {
                keys.Clear();
            }
            else
            {
                keys = new List<string>();
            }

#if UNITY_STANDALONE_WIN
            // Unity stores prefs in the registry on Windows
            string regKeyPathPattern =
#if UNITY_EDITOR
        @"Software\Unity\UnityEditor\{0}\{1}";
#else
		@"Software\{0}\{1}";
#endif
            ;

            string regKeyPath = string.Format(regKeyPathPattern, UnityEditor.PlayerSettings.companyName, UnityEditor.PlayerSettings.productName);
            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regKeyPath);
            if (regKey == null)
            {
                return;
            }

            string[] playerPrefKeys = regKey.GetValueNames();
            for (int i = 0; i < playerPrefKeys.Length; i++)
            {
                string playerPrefKey = playerPrefKeys[i];

                // Remove the _hXXXXX suffix
                playerPrefKey = playerPrefKey.Substring(0, playerPrefKey.LastIndexOf("_h"));

                if(playerPrefKey != NON_TARGET_KEY[0] && playerPrefKey != NON_TARGET_KEY[1] && playerPrefKey != NON_TARGET_KEY[2] && playerPrefKey != NON_TARGET_KEY[3])
                    keys.Add(playerPrefKey);
            }
#endif
        }
    }
}

【Unity】PlayerPrefs のすべてのキーを取得できる「PlayerPrefsTools.cs」紹介(Windows のみ) - コガネブログ

こちらの記事を参考にしながらPlayerPrefsのキーを全て取得するスクリプトを作成しました。

ただ自分が作成していないPlayerPrefsが自動でいくつか作成されていたので、それを除くように変更させていただきました。

PlayerPrefsDeleter.cs

// PlayerPrefsDeleter.cs
// https://www.hanachiru-blog.com/entry/2019/05/25/170042
//
// Created by hanachiru on 2019.05.26

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;

namespace PlayerPrefsEditor
{

    public class PlayerPrefsDeleter : EditorWindow
    {
        private List<PlayerPrefsData> _playerPrefData = null;


        [MenuItem("Tools/PlayerPrefsDeleter")]
        private static void Open()
        {
            var window = GetWindow<PlayerPrefsDeleter>("PlayerPrefsDeleter");

            window.minSize = new Vector2(500, 180);

            window.LoadPlayerPrefs();
        }

        private void OnGUI()
        {
            DrawToolbar();

            if (_playerPrefData == null || _playerPrefData.Count() == 0)
            {
                EditorGUILayout.LabelField("PlayerPrefs do not exist");
                return;
            }

            DrawPlayerPrefsList();
        }

        /// <summary>
        /// PlayerPrefsを読み込む
        /// </summary>
        private void LoadPlayerPrefs()
        {

#if UNITY_EDITOR
            //リストの初期化
            if (_playerPrefData != null)
            {
                _playerPrefData.Clear();
            }
            else
            {
                _playerPrefData = new List<PlayerPrefsData>();
            }

            //PlayerPrefsのすべてのキーを検索する
            var keys = new List<string>();
            PlayerPrefsTools.GetAllPlayerPrefKeys(ref keys);

            //リストの作成
            foreach (var key in keys)
            {
                _playerPrefData.Add(new PlayerPrefsData(key));
            }
#else
            _playerPrefData = null;
#endif

        }

        /// <summary>
        /// PlayerPrefsを全て削除する
        /// </summary>
        private void ResetPlayerPrefs()
        {
            PlayerPrefs.DeleteAll();
            PlayerPrefs.Save();
            _playerPrefData = null;
        }

        private void DrawToolbar()
        {
            using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar, GUILayout.ExpandWidth(true)))
            {
                if (GUILayout.Button("DeleteAll...", EditorStyles.toolbarButton))
                {
                    Debug.Log("Delete All PlayerPrefs");
                    ResetPlayerPrefs();
                }
                if (GUILayout.Button("Reload...", EditorStyles.toolbarButton))
                {
                    Debug.Log("Reload PlayerPrefs");
                    LoadPlayerPrefs();
                }
            }
        }
        private void DrawPlayerPrefsList()
        {
            bool isDeleted = false;

            EditorGUILayout.BeginVertical();

            foreach (var item in _playerPrefData)
            {
                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.LabelField("Key: " + item.Key);
                EditorGUILayout.LabelField("Value: " + item.Value);

                if (GUILayout.Button("Delete", GUILayout.Width(64), GUILayout.Height(16)))
                {
                    item.Delete();
                    isDeleted = true;
                    Debug.Log(item.Key + " is deleted");
                }
                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.EndVertical();

            if(isDeleted) LoadPlayerPrefs();
        }
    }

    public class PlayerPrefsData
    {
        public string Key { get; }
        public string Value { get; }

        public PlayerPrefsData(string key)
        {
            Key = key;
            Value = GetValue(key);
        }

        public void Delete()
        {
            PlayerPrefs.DeleteKey(Key);
        }

        /// <summary>
        /// PlayerPrefsのstring,int,floatのどれかを返す
        /// </summary>
        private string GetValue(string key)
        {
            string value = PlayerPrefs.GetString(key, null);

            if (string.IsNullOrEmpty(value))
            {
                value = PlayerPrefs.GetInt(key, 0).ToString();

                if (value == "0")
                {
                    value = PlayerPrefs.GetFloat(key, 0).ToString();
                }
            }

            return value;
        }
    }
}

こちらがメインのスクリプトになります。

  • PlayerPrefsの一覧を表示
  • 特定のPlayerPrefsを削除する(それぞれの要素の右のボタン)
  • 全てのPlayerPrefsを削除する(Delete All...)
  • PlayerPrefsを再ロードする(Reload...)

という機能を付けてみました。

これらのスクリプトをEditorフォルダ内に入れれば動きます。

またWindowの開き方はTool -> PlayerPrefsDeleterをクリックすればOKです。

ただ復元機能はないので慎重に。(暇があれば追加したいです)

ダウンロードの仕方

上のコードをコピペしても動きますが、.unitypackageも用意してみました。

全然自由に使っていいので、よかったら下のGitHubからどうぞ。
GitHub - hanachiru/PlayerPrefsDeleter: PlayerPrefsの一覧を表示、一部(全部)を削除できるエディタ拡張

さいごに

あまりスクリプトの説明はしませんでしたが、そんなに大層なことはしてないです。

また久しぶりのエディタ拡張でしたので、ワクワクしながら作成することができました。

さらにマサカリも大大募集中ですので、よろしければコメント等で教えてください!

追記)これの進化Verを作ってみました。よろしければこちらもチェックしてみてください。
www.hanachiru-blog.com