徳島ゲーム開発ごっこ 技術ブログ

ゲームを作るために役に立ったり立たなかったりする技術を学んでいきます!

【Unity】 セーブファイルのパスを開くメニューを作る

指定したパスをエクスプローラーで開くメニューを作るお話。
Unityの機能と言うより.Netの機能なのですが、妙なハマりかたをしたのでメモ書き。
f:id:urahimono:20211103163455p:plain


この記事にはUnity2020.3.21f1を使用しています。
.Netのバージョン設定には.Net4.x を使用しています。

Process.Start()を使ってエクスプローラーを呼ぶ

Unity ではいろいろとファイルパスを用意してくれてますよね。
こんな感じになっています。

  • Application.dataPath
    /Assets
  • Application.streamingAssetsPath
    /Assets/StreamingAssets
  • Application.persistentDataPath
    C:/Users/xxxx/AppData/LocalLow/CompanyName/ProductName
  • Application.temporaryCachePath
    C:/Users/xxxx/AppData/Local/Temp/CompanyName/ProductName

ファイルの保存や読み込みをこれらのパスを使ってテストする場合、
dataPathstreamingAssetsPath は Asset以下に配置されるので、ProjectView からすぐに見ることが出来るのですが、
persistentDataPathtemporaryCachePath は複雑な場所にあるので見に行くのが大変!

それならいっそ、このパスをエクスプローラーで開くメニューを作ってしまったほうが後々楽になる気がします。
簡単に作れそうなので、パパっと作っちゃいましょう。

メニュー作成用のクラスを作りましょう。

// OpenExplorerMenu.cs
using UnityEngine;
using UnityEditor;
public class OpenExplorerMenu
{
    [MenuItem("MyGame/Open Persistent Data")]
    private static void Open()
    {

    }
} // class OpenExplorerMenu

エクスプローラーを開くには、.Net の System.Diagnostics.Process.Start() を使いましょうか。
これならコマンドライン感覚で exe が呼べます。
docs.microsoft.com

エクスプローラーを開く exe は、explorer.exe です。

// OpenExplorerMenu.cs
using UnityEngine;
using UnityEditor;
public class OpenExplorerMenu
{
    [MenuItem("MyGame/Open Persistent Data")]
    private static void Open()
    {
        System.Diagnostics.Process.Start("explorer.exe", Application.persistentDataPath);
    }
} // class OpenExplorerMenu

すごい簡単に出来た。
早速使ってみましょう。

f:id:urahimono:20211103163508j:plain
f:id:urahimono:20211103163510j:plain

なぜマイドキュメントが開く!?
ちゃんとパスを指定したはずだけど。

Application.persistentDataPath の中身を確認しておきましょう。
f:id:urahimono:20211103163525j:plain

うーん、ちゃんとしたパスを指定しているように見えるんだけど……。
しかし、気になる点がありますね。
パスの区切りにスラッシュを使っているなぁ。
これ大丈夫なのかな?
後述の理由から、バックスラッシュの方が正しい気がする。
差し替えてみますか。

// OpenExplorerMenu.cs
using UnityEngine;
using UnityEditor;
public class OpenExplorerMenu
{
    [MenuItem("MyGame/Open Persistent Data")]
    private static void Open()
    {
        string path = Application.persistentDataPath.Replace('/', '\\');
        System.Diagnostics.Process.Start("explorer.exe", path);
    }
} // class OpenExplorerMenu

f:id:urahimono:20211103163535j:plain

おおー、上手くいきましたね。
なるほど、explorer.exe に渡す引数のパスはバックスラッシュでないと駄目なんですね。

ちなみに explorer.exe には他にもパラメータが渡せます。
smdn.jp

例えば /select,
指定したパスを選択した状態でエクスプローラーが開きます。

// OpenExplorerMenu.cs
using UnityEngine;
using UnityEditor;
public class OpenExplorerMenu
{
    [MenuItem("MyGame/Open Persistent Data")]
    private static void Open()
    {
        string path = Application.persistentDataPath.Replace('/', '\\');
        System.Diagnostics.Process.Start("explorer.exe", $"/select,{path}");
    }
} // class OpenExplorerMenu

f:id:urahimono:20211103163551j:plain

こんな風に。
ちなみにこれがパスの区切りがスラッシュじゃ上手くいかない理由なのかな?
他のパラメータをハイフンではなくスラッシュで指定しているから、パスをスラッシュで指定されると混乱するからかなぁ。

ちなみにこのパスのバックスラッシュ問題、
サラッと閃いたように書いているけど、実際には理由がわからなくて結構な時間が持っていかれました……。