前回の記事でEditorPrefs
の値をレジストリエディタでいじるのが面倒だったので書いた、誰得なPowerShellスクリプトを公開。
正直このスクリプト書くのが一番面倒だった。
ちなみに取得・削除はできますが、作成・変更はできません(必要だという稀有な方は自分で改造してください)。
EditorPrefs の仕様 (Windows)
スクリプトリファレンスに記述されているように、
EditorPrefs
に保存した値はWindowsではレジストリに記録されます。
正確にはHKCU\Software\Unity Technologies\UnityEditor #.x
(#はUnityのメジャーバージョン)のエントリとして記録されます。
この際、エントリ名にはEditorPrefs
で指定した文字列(キー)にハッシュを連結したものが使われます。
フォーマットは{key}_h{hash}
です(ハッシュはパディングなしの十進数)。
ハッシュで何か特殊な検査でもしているのかと思ったのですが、
少し調べてみたところキー自体のハッシュのようです(何に使用しているのか不明)。
ハッシュの計算方法は多分こんな感じ。
static uint GetHash(string key) { uint hash = 5381; foreach(char c in key) { hash = (hash * 33) ^ c; } return hash; }
EditorPrefs
はBool/Int/Float/Stringの四種類の値が扱えますが、
Bool/IntではREG_DWORDで32bit値、
FloatではREG_DWORDで64bit値(!?)、
StringではREG_BINARYでヌル文字を含む任意長の値(詳しく調べてないけどUTF-8かな?)を保存しています。
Floatはもともと32bit値のはずなので、doubleに変換したうえでBitConverter.DoubleToInt64Bits
をかけているようです。
地味にこの仕様がやっかいで、
Floatに対して普通にGet-ItemProperty
やGet-ItemPropertyValue
を呼び出すと、
不正なDWORD値ということで内部でInvalidCastException
が発生して死にます。
Stringも普通に変換するとヌル文字を含むstring型に変換されて、そのまま別のコマンドに渡すとやっぱり死にます。
使い方
普通にスクリプトを読み込むといくつかのコマンドレットが読み込まれます。
.\UnityEditorPrefs.ps1
値の取得
Get-UnityEditorPref
コマンドレットにEditorPrefs
のキーの値を指定する(複数可)とPSCustomObject
が返ってきます。
Get-UnityEditorPref MyKey
このPSCustomObject
には次の三つのプロパティが設定されています。
プロパティ | 説明 |
---|---|
Key | EditorPrefs のキー |
Value | EditorPrefs に保存された値 |
Name | 対応するレジストリエントリ名 |
キーの指定にはワイルドカードが使用できます。
Get-UnityEditorPref MyKey_*
-Json
スイッチを使用すると、EditorPrefs
に保存された値がJSONとして解釈できる場合にConvertFrom-Json
された状態で返ってきます。
JSONの値を確認したい場合にはConvertTo-Json
で再度フォーマットしてやると見やすくなります。
Get-UnityEditorPref -Key My*Settings -Json | % { ConvertTo-Json $_.Value }
値の削除
Remove-UnityEditorPref
コマンドレットにEditorPrefs
のキーの値を指定する(複数可)と指定したキーが削除できます。
Remove-UnityEditorPref MyKey
キーの指定にはワイルドカードが使用できます。
Remove-UnityEditorPref MyKey_*
Get-UnityEditorPref
とパイプで繋いでも削除できます。
Get-UnityEditorPref MyKey_* | Remove-UnityEditorPref
その他の操作
Get-UnityEditorPrefPath
コマンドレットでEditorPrefs
が書き込むレジストリキーのパスが取得できます。
Get-UnityEditorPrefPath -Version 5
ConvertTo-UnityEditorPrefEntryName
コマンドレットでEditorPrefs
のキーをレジストリエントリ名に変換できます。
ConvertTo-UnityEditorPrefEntryName MyKey
Get-UnityEditorPrefEntry
コマンドレットで存在するEditorPrefs
のエントリを列挙できます(ワイルドカードによるフィルタリングも可)。
Get-UnityEditorPrefEntry MyKey_*
これらのコマンドはPowerShellでのプライベートな関数の書き方がよくわからなかったので、体裁を整えて公開してあるだけです。 多分、拡張しようとでも思わない限りは使い道はないはず。
メジャーバージョンの指定
各コマンドレットの-Version
オプションにUnityのメジャーバージョンを指定すると、そのバージョンの値を操作できます。
メジャーバージョンの初期値は5です。 これを変更するにはスクリプト最上部の定数の値をテキストエディタで直接書き換えてください。
ソースコード
Gist: UnityEditorPrefs.ps1
おわりに
PowerShellの練習がてら書いたのですが、結構難しいですね。 スクリプト言語である以上、ある程度柔軟に変換するのは必要だと思うのですが、 勝手に変換しすぎてくれるおかげで型がよくわからなくなることがしばしば。 一方で、スコープとか固定長整数とか細かいところで融通が利かなかったり。 あとVSCodeが何故かタブ保持の設定を無視してくれたり(PowerShellのせいじゃないけど)。
ところで、PowerShellオープンソース化するそうですね。 LinuxやMacでも使えるようになるんだとか。 .NET Coreとかbashの輸入とか最近Microsoftの動きが激しくて混乱中。
執筆時のUnityのバージョン:5.4.0f3