私はそれぞれの変形を試みました:http://wiki.unity3d.com/index.php/ScreenCapture Afterall、単純なApplication.Capturescreenshot(...)は、最も遅いです。遅れのないUnity3Dのスクリーンショットを撮る
、教えてください、私は遅れずにスクリーンショットを取ることができますどのように? Androidのゲームにはたくさんの機能があるため、不可能ではありません。
私はそれぞれの変形を試みました:http://wiki.unity3d.com/index.php/ScreenCapture Afterall、単純なApplication.Capturescreenshot(...)は、最も遅いです。遅れのないUnity3Dのスクリーンショットを撮る
、教えてください、私は遅れずにスクリーンショットを取ることができますどのように? Androidのゲームにはたくさんの機能があるため、不可能ではありません。
Application.CaptureScreenshot()
は一般的に遅い、より高速な方法は、あなたがハードドライブにテクスチャをエンコードして保存することができますよりもTexture2D
を使用してReadPixels()
機能を使用して、その上に画面上のすべてのピクセルを読むことです。
これは、この方法の例です:
Texture2D screenShot = new Texture2D(Screen.width, Screen.height);
screenShot.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0);
screenShot.Apply();
byte[] bytes = tex.EncodeToPNG();
Object.Destroy(tex);
File.WriteAllBytes(Application.dataPath + "/../myScreenShot.png", bytes);
あなたはユニティスクリプティングリファレンスページhereを使用することができます完全な参考のために。あなたは、各ステップの後を待っずに同時にですべてのステップを実行しようとすると、
'ReadPixels()'は、現在のコマンドバッファ内の残りのすべてのコマンドを待つことを意味するGPUフラッシュをトリガするため、非常に遅いです – Aray
原因の遅れ写真を撮影中です。これを修正するには、を1回実行し、が多く、フレームを待ってから、次の操作を実行してからをもう一度待ちます。あなたがゲームプレイ中に絵保存することを決定した場合や、画像を保存してスレッドを使用しています。 EncodeToPNG()
は問題別ですが、私はそれでは約別ソリューション後でお話します。あなたが、その後すぐにゲームが起動している間、それを表示するスクリーンショットを取りたい場合は、以下の
コードが良いです。 これは正しい方法で撮影し、約1.5秒でファイルを保存します。
IEnumerator screenShotCoroutine()
{
yield return new WaitForEndOfFrame();
string path = Application.persistentDataPath + "/DrukaloScreenshot.png";
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
//Get Image from screen
screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
screenImage.Apply();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
//Convert to png(Expensive)
byte[] imageBytes = screenImage.EncodeToPNG();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
//Create new thread then save image to file
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
File.WriteAllBytes(path, imageBytes);
}).Start();
}
あなたは写真を撮りたいとあなたはすぐに画像を表示するために必要なないある場合は、あなたが/ロードにアクセスしたいときに/表示、生Texture2D
として画像を保存することができます後でをからに変換してからPNGに変換してください。これは、EncodeToPNG()
が非常にであるため、すぐに画像が必要ない場合は、pngに変換する必要はありません。あなたが実際にPNGとしてにそれを必要とするのみ時にそれを行うことができます。だから今、私たちはただ、その後の後にそれをロードし、「はを.pngを」するロードされたイメージを変換する「.t2D」として保存することができます。
にTexture2Dとして保存 ".t2D"
IEnumerator screenShotCoroutine()
{
yield return new WaitForEndOfFrame();
string path = Application.persistentDataPath + "/DrukaloScreenshot.t2D";
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
//Get Picture
screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
screenImage.Apply();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
byte[] rawData = screenImage.GetRawTextureData();
//Wait for a long time
for (int i = 0; i < 15; i++)
{
yield return null;
}
//Create new thread then save image
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
File.WriteAllBytes(path, rawData);
}).Start();
}
次に、あなたが実際に画像、負荷にTexture2D "を必要とするとき。T2D「と、その後にそれをひそか」は.t2D」「古いものを削除して、その後」を.pngを。
IEnumerator screenShotCoroutine()
{
string path = Application.persistentDataPath + "/DrukaloScreenshot.t2D";
string newPath = Application.persistentDataPath + "/DrukaloScreenshot.png";
Texture2D screenImage = new Texture2D(Screen.width, Screen.height);
byte[] rawData = null;
//Create new thread then Load image
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
rawData = File.ReadAllBytes(path);
}).Start();
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
//Put loaded bytes to Texture2D
screenImage.LoadRawTextureData(rawData);
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
screenImage.Apply();
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
//convert to png
byte[] pngByte = screenImage.EncodeToPNG();
//Wait for a long time
for (int i = 0; i < 9; i++)
{
yield return null;
}
//Do whatever you want with the png file(display to screen or save as png)
//Create new thread and Save the new png file, then Delete Old image(DrukaloScreenshot.t2D)
new System.Threading.Thread(() =>
{
System.Threading.Thread.Sleep(100);
File.WriteAllBytes(newPath, pngByte); //Save the new png file(DrukaloScreenshot.png)
File.Delete(path); //Delete old file (DrukaloScreenshot.t2D)
}).Start();
}
あなたのコードを使用しましたが、ゲームプレイ中にスクリーンイメージを作成すると同じラグが表示されます。遅れはApplication.Capturescreenshot(...)のように少し気づかないです。とにかく、ありがとう。 – Drukalo
20%betterr – Drukalo
私のソリューションはApplication.Capturescreenshot(...)またはApplication.Capturescreenshot(...)よりも20%優れています。 – Programmer
あなたが代わりに実行されたコルーチンでそれを保存する別のスレッドでスクリーンショットを救うことができます – RCYR
@RCYR Capturescreenshotはメインスレッドからのみ呼び出すことができます – Programmer
スクリーンショットビデオの作成中にフレームレートを変更するためのコマンドは何ですか?ここにはここで質問がありました.. – Fattie