先来效果
直接上代码
#if UNITY_EDITOR
using UnityEngine;
using System.Collections;
using System.IO;
using System;
public class AnimationToPNG : MonoBehaviour
{
public string animationName = "";
public string folder = "PNG_Animations";
public string folderPath = "";
public int frameRate = 30;
public int framesToCapture = 90;
private Camera whiteCam;
private Camera blackCam;
public float fieldOfView = 20;
private bool useRenderTexture = false;
public int videoframe = 0;
private float originaltimescaleTime;
private string realFolder = "";
private bool done = false;
private bool readyToCapture = false;
private Texture2D texb;
private Texture2D texw;
private Texture2D outputtex;
private RenderTexture blackCamRenderTexture; // black camera render texure
private RenderTexture whiteCamRenderTexture; // white camera render texure
public void OnStart()
{
useRenderTexture = Application.HasProLicense();
Time.captureFramerate = frameRate;
realFolder = folder + "/" + folderPath;
int count = 1;
while (Directory.Exists(realFolder))
{
realFolder = realFolder + count;
count++;
}
Directory.CreateDirectory(realFolder);
originaltimescaleTime = Time.timeScale;
if (blackCam == null)
{
GameObject bc = new GameObject("Black Camera");
bc.transform.parent = gameObject.transform;
bc.transform.localPosition = Vector3.zero;
bc.transform.localScale = Vector3.one;
bc.transform.localRotation = new Quaternion(0, 0, 0, 0);
blackCam = bc.AddComponent();
blackCam.backgroundColor = Color.black;
blackCam.fieldOfView = fieldOfView;
blackCam.tag = "MainCamera";
blackCam.cullingMask = ~(1 << LayerMask.NameToLayer("Default"));
}
if (whiteCam == null)
{
GameObject wc = new GameObject("White Camera");
wc.transform.parent = gameObject.transform;
wc.transform.localPosition = Vector3.zero;
wc.transform.localScale = Vector3.one;
wc.transform.localRotation = new Quaternion(0, 0, 0, 0);
whiteCam = wc.AddComponent();
whiteCam.backgroundColor = Color.white;
whiteCam.fieldOfView = fieldOfView;
whiteCam.cullingMask = ~(1 << LayerMask.NameToLayer("Default"));
if (!useRenderTexture)
{
blackCam.rect = new Rect(0.0f, 0.0f, 0.5f, 1.0f);
whiteCam.rect = new Rect(0.5f, 0.0f, 0.5f, 1.0f);
}
readyToCapture = true;
}
}
void Update()
{
if (!done && readyToCapture)
{
StartCoroutine(Capture());
}
}
void LateUpdate()
{
if (done)
{
DestroyImmediate(texb);
DestroyImmediate(texw);
DestroyImmediate(outputtex);
if (useRenderTexture)
{
//Clean Up
whiteCam.targetTexture = null;
RenderTexture.active = null;
DestroyImmediate(whiteCamRenderTexture);
blackCam.targetTexture = null;
RenderTexture.active = null;
DestroyImmediate(blackCamRenderTexture);
}
}
}
IEnumerator Capture()
{
if (videoframe < framesToCapture)
{
animationName = videoframe + "_";
string filename = String.Format("{0}/" + animationName + "{1:D04}.png", realFolder, Time.frameCount);
Time.timeScale = 0;
yield return new WaitForEndOfFrame();
if (useRenderTexture)
{
//Initialize and render textures
blackCamRenderTexture = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
whiteCamRenderTexture = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
blackCam.targetTexture = blackCamRenderTexture;
blackCam.Render();
RenderTexture.active = blackCamRenderTexture;
texb = GetTex2D(true);
//Now do it for Alpha Camera
whiteCam.targetTexture = whiteCamRenderTexture;
whiteCam.Render();
RenderTexture.active = whiteCamRenderTexture;
texw = GetTex2D(true);
}
else
{
texb = GetTex2D(true);
texw = GetTex2D(false);
}
if (texw && texb)
{
int width = Screen.width;
int height = Screen.height;
if (!useRenderTexture)
{
width = width / 2;
}
outputtex = new Texture2D(width, height, TextureFormat.ARGB32, false);
for (int y = 0; y < outputtex.height; ++y)
{ // each row
for (int x = 0; x < outputtex.width; ++x)
{ // each column
float alpha;
if (useRenderTexture)
{
alpha = texw.GetPixel(x, y).r - texb.GetPixel(x, y).r;
}
else
{
alpha = texb.GetPixel(x + width, y).r - texb.GetPixel(x, y).r;
}
alpha = 1.0f - alpha;
Color color;
if (alpha == 0)
{
color = Color.clear;
}
else
{
color = texb.GetPixel(x, y) / alpha;
}
color.a = alpha;
outputtex.SetPixel(x, y, color);
}
}
// Encode the resulting output texture to a byte array then write to the file
byte[] pngShot = outputtex.EncodeToPNG();
File.WriteAllBytes(filename, pngShot);
// Reset the time scale, then move on to the next frame.
Time.timeScale = originaltimescaleTime;
videoframe++;
}
// Debug.Log("Frame " + name + " " + videoframe);
}
else
{
Debug.Log("完成");
done = true;
GameObject.DestroyImmediate(whiteCam.gameObject);
GameObject.DestroyImmediate(blackCam.gameObject);
GameObject.DestroyImmediate(this);
}
}
private Texture2D GetTex2D(bool renderAll)
{
int width = Screen.width;
int height = Screen.height;
if (!renderAll)
{
width = width / 2;
}
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
return tex;
}
}
#endif