スクリーンキャプチャで「Failed to store screen shot」が出た時の原因と対処法

Unityで画面キャプチャ(スクリーンショット)を撮る方法

Unityでは、スクリーンショットを撮って保存する機能が実装されています。

ScreenCapture.CaptureScreenshot("filePath");

を使うだけでスクリーンショットが撮れます。簡単!

スクリプトの例は以下のとおり。


using System;  //DateTimeを使う場合
using System.IO;

void Capture(int deadCount){
  #if UNITY_EDITOR  //エディタの場合
    Directory.CreateDirectory(Path.Combine(Application.dataPath, "Captures"));
    ScreenCapture.CaptureScreenshot(Application.dataPath + "/Captures/capture" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".png");
  #elif UNITY_IOS  //iOSの場合(Androidでも同様)
    Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, "Captures"));
    ScreenCapture.CaptureScreenshot(Application.persistentDataPath + "/Captures/deadCapture" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".png");
  #endif
}

これで指定パスにキャプチャが保存されます。

注意すべきこと

スクリーンショットを撮る時に、

Failed to store screen shot

というエラーが出たことがありました。

僕の場合の原因としては、ScreenCapture.CaptureScreenshot(“filePath”)で指定したfilePathのディレクトリが存在しなかったことが原因でした。
ScreenCapture.CaptureScreenshotでは新たにディレクトリを作成してくれないので、もし存在しない場合は事前に作成しておく必要があります。

ディレクトリ(フォルダ)を作成する方法は以下。

using System.IO; 

#if UNITY_EDITOR  //エディタの場合
  Directory.CreateDirectory(Path.Combine(Application.dataPath, "dirName"));
#elif UNITY_IOS  //iOSの場合
  Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, "dirName"));
#endif

もしすでに同名のディレクトリが存在した場合は何もされないので、上書きされるような心配は無用です。

これで「Failed to store screen shot」というエラー文は消えて、きちんとスクリーンショットが保存されるようになりました。

あと注意すべき点としては、保存するスクリーンショット(画面キャプチャ)の名前を一意の名前にすること

同名のスクリーンショットがすでに保存されていると、そのスクリーンショットを上書き保存してしまいます。
なので、上書き保存せずに個別に保存したい場合は、ひとつひとつ異なるファイル名にしましょう。

今回の例ではキャプチャした日時を取得してそのままファイル名にしました。
もし1秒間に複数枚キャプチャする可能性があるのであれば、もう少し工夫する必要がありそうです。

ScreenCapture.CaptureScreenshotとTexture2D.ReadPixelsの違い

ついでに。
ScreenCapture.CaptureScreenshotとは別に、もうひとつスクリーンショットを撮る方法としてTexture2D.ReadPixelsを使う方法があります。

こちらについては詳しくは書きませんが、ScreenCapture.CaptureScreenshotとTexture2D.ReadPixelsの違いというか使い分け方についてざっくりと。

ScreenCapture.CaptureScreenshotは「撮影」→「保存」→「取得」
Texture2D.ReadPixelsは「撮影」→「取得」(→「保存」)

という流れになっています。

また、ScreenCapture.CaptureScreenshotにはコールバック関数がないというデメリットもあります。

そのため、
スクリーンショットを単純に撮って保存しておきたい場合は実装が簡単なScreenCapture.CaptureScreenshot、
撮ったスクリーンショットをその場で使いたい場合はコールバック関数が使えるTexture2D.ReadPixels
を使うのが良いと思います。

Texture2D.ReadPixelsは撮ったスクリーンショットの保存ももちろんできますが、自動では保存されません。
なのでもし保存する必要がなく、その場で使いたいだけの場合は、いちいち保存していると容量がもったいないのでTexture2D.ReadPixelsを使うべきかなと思います。¥

コメント