Skip to content

Commit 0790a8b

Browse files
committed
Added automatic camera creation for AnimationToPNG.
1 parent 8ef75dc commit 0790a8b

File tree

4 files changed

+81
-47
lines changed

4 files changed

+81
-47
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ Library/
88
Assets/AssetStoreTools/
99
Gizmos/
1010
Assets/GitSharp/
11-
.gradle/
11+
.gradle/
12+
build/
Binary file not shown.

Assets/SpritesAndBones/Scripts/Utils/AnimationToPNG.cs

+79-46
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,41 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2828
THE SOFTWARE.
2929
*/
3030

31-
// AnimationToPNG is based on Twinfox and bitbutter's Render Particle to Animated Texture Scripts, this script will render out an animation that is played when "Play" is pressed in the editor.
32-
33-
/* Basically this is a script you can attach to any gameobject in the scene, but you have to reference a Black Camera and White Camera both of which should be set to orthographic, but this script should have it covered. There is a prefab called AnimationToPNG which should include everything needed to run the script.
34-
35-
If you have Unity Pro, you can use Render Texture, which can accurately render the transparent background for your animations easily in full resolution of the camera. Just check the box for the variable "useRenderTexture" to use RenderTextures instead. If you are using Unity Free, then leave this unchecked and you will have a split area using half of the screen width to render the animations.
36-
37-
You can change the "animationName" to a string of your choice for a prefix for the output file names, if it is left empty then no filename will be added.
38-
39-
The destination folder is relative to the Project Folder root, so you can change the string to a folder name of your choice and it will be created. If it already exists, it will simply create a new folder with a number incremented as to how many of those named folders exist.
40-
41-
Choose how many frames per second the animation will run by changing the "frameRate" variable, and how many frames of the animation you wish to capture by changing the "framesToCapture" variable.
42-
43-
Once "Play" is pressed in the Unity Editor, it should output all the animation frames to PNGs output in the folder you have chosen, and will stop capturing after the number of frames you wish to capture is completed. */
31+
// AnimationToPNG is based on Twinfox and bitbutter's Render Particle to Animated Texture Scripts,
32+
// this script will render out an animation that is played when "Play" is pressed in the editor.
33+
34+
/*
35+
Basically this is a script you can attach to any gameobject in the
36+
scene, but you have to reference a Black Camera and White Camera both of
37+
which should be set to orthographic, but this script should have it
38+
covered. There is a prefab called AnimationToPNG which should include
39+
everything needed to run the script.
40+
41+
If you have Unity Pro, you can use Render Texture, which can accurately
42+
render the transparent background for your animations easily in full
43+
resolution of the camera. Just check the box for the variable
44+
"useRenderTexture" to use RenderTextures instead. If you are using Unity
45+
Free, then leave this unchecked and you will have a split area using
46+
half of the screen width to render the animations.
47+
48+
You can change the "animationName" to a string of your choice for a
49+
prefix for the output file names, if it is left empty then no filename
50+
will be added.
51+
52+
The destination folder is relative to the Project Folder root, so you
53+
can change the string to a folder name of your choice and it will be
54+
created. If it already exists, it will simply create a new folder with a
55+
number incremented as to how many of those named folders exist.
56+
57+
Choose how many frames per second the animation will run by changing the
58+
"frameRate" variable, and how many frames of the animation you wish to
59+
capture by changing the "framesToCapture" variable.
60+
61+
Once "Play" is pressed in the Unity Editor, it should output all the
62+
animation frames to PNGs output in the folder you have chosen, and will
63+
stop capturing after the number of frames you wish to capture is
64+
completed.
65+
*/
4466

4567
public class AnimationToPNG : MonoBehaviour {
4668

@@ -57,16 +79,16 @@ public class AnimationToPNG : MonoBehaviour {
5779
public int framesToCapture = 25;
5880

5981
// White Camera
60-
public Camera whiteCam;
82+
private Camera whiteCam;
6183

6284
// Black Camera
63-
public Camera blackCam;
85+
private Camera blackCam;
6486

6587
// Pixels to World Unit size
6688
public float pixelsToWorldUnit = 74.48275862068966f;
6789

6890
// If you have Unity Pro you can use a RenderTexture which will render the full camera width, otherwise it will only render half
69-
public bool useRenderTexture = false;
91+
private bool useRenderTexture = false;
7092

7193
private int videoframe = 0; // how many frames we've rendered
7294

@@ -90,45 +112,41 @@ public class AnimationToPNG : MonoBehaviour {
90112

91113
private RenderTexture whiteCamRenderTexture; // white camera render texure
92114

93-
// Get the texture from the screen, render all or only half of the camera
94-
public Texture2D GetTex2D( bool renderAll ) {
95-
// Create a texture the size of the screen, RGB24 format
96-
int width = Screen.width;
97-
int height = Screen.height;
98-
if (!renderAll){
99-
width = width / 2;
100-
}
101-
102-
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
103-
// Read screen contents into the texture
104-
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
105-
tex.Apply();
106-
return tex;
107-
}
108-
109115
public void Start () {
116+
useRenderTexture = Application.HasProLicense();
117+
110118
// Set the playback framerate!
111119
// (real time doesn't influence time anymore)
112120
Time.captureFramerate = frameRate;
113121

114122
// Create a folder that doesn't exist yet. Append number if necessary.
115123
realFolder = folder;
116124
int count = 1;
117-
while (System.IO.Directory.Exists(realFolder)) {
125+
while (Directory.Exists(realFolder)) {
118126
realFolder = folder + count;
119127
count++;
120128
}
121129
// Create the folder
122-
System.IO.Directory.CreateDirectory(realFolder);
130+
Directory.CreateDirectory(realFolder);
123131

124132
originaltimescaleTime = Time.timeScale;
125133

126134
// Force orthographic camera to render out sprites per pixel size designated by pixels to world unit
127135
cameraSize = Screen.width / ((( Screen.width / Screen.height ) * 2 ) * pixelsToWorldUnit );
136+
137+
GameObject bc = new GameObject("Black Camera");
138+
bc.transform.localPosition = new Vector3(0, 0, -1);
139+
blackCam = bc.AddComponent<Camera>();
140+
blackCam.backgroundColor = Color.black;
128141
blackCam.orthographic = true;
129142
blackCam.orthographicSize = cameraSize;
143+
blackCam.tag = "MainCamera";
130144

131-
whiteCam.orthographic = true;
145+
GameObject wc = new GameObject("White Camera");
146+
wc.transform.localPosition = new Vector3(0, 0, -1);
147+
whiteCam = wc.AddComponent<Camera>();
148+
whiteCam.backgroundColor = Color.white;
149+
whiteCam.orthographic = true;
132150
whiteCam.orthographicSize = cameraSize;
133151

134152
// If not using a Render Texture then set the cameras to split the screen to ensure we have an accurate image with alpha
@@ -149,15 +167,14 @@ void Update() {
149167
}
150168
}
151169

152-
void LateUpdate(){
170+
void LateUpdate() {
153171
// When we are all done capturing, clean up all the textures and RenderTextures from the scene
154-
if (done){
155-
172+
if (done) {
156173
DestroyImmediate(texb);
157174
DestroyImmediate(texw);
158175
DestroyImmediate(outputtex);
159176

160-
if (useRenderTexture){
177+
if (useRenderTexture) {
161178
//Clean Up
162179
whiteCam.targetTexture = null;
163180
RenderTexture.active = null;
@@ -174,7 +191,7 @@ IEnumerator Capture () {
174191
if(videoframe < framesToCapture) {
175192
// name is "realFolder/animationName0000.png"
176193
// string name = realFolder + "/" + animationName + Time.frameCount.ToString("0000") + ".png";
177-
string name = String.Format("{0}/" + animationName + "{1:D04}.png", realFolder, Time.frameCount);
194+
string filename = String.Format("{0}/" + animationName + "{1:D04}.png", realFolder, Time.frameCount);
178195

179196
// Stop time
180197
Time.timeScale = 0;
@@ -199,7 +216,7 @@ IEnumerator Capture () {
199216
texw = GetTex2D(true);
200217
}
201218
// If not using render textures then simply get the images from both cameras
202-
else{
219+
else {
203220
// store 'black background' image
204221
texb = GetTex2D(true);
205222

@@ -208,7 +225,7 @@ IEnumerator Capture () {
208225
}
209226

210227
// If we have both textures then create final output texture
211-
if (texw && texb){
228+
if (texw && texb) {
212229

213230
int width = Screen.width;
214231
int height = Screen.height;
@@ -224,10 +241,10 @@ IEnumerator Capture () {
224241
for (int x = 0; x < outputtex.width; ++x) { // each column
225242
float alpha;
226243
if (useRenderTexture){
227-
alpha = (float)(texw.GetPixel(x, y).r - texb.GetPixel(x, y).r);
244+
alpha = texw.GetPixel(x, y).r - texb.GetPixel(x, y).r;
228245
}
229246
else {
230-
alpha = (float)(texb.GetPixel(x + width, y).r - texb.GetPixel(x, y).r);
247+
alpha = texb.GetPixel(x + width, y).r - texb.GetPixel(x, y).r;
231248
}
232249
alpha = 1.0f - alpha;
233250
Color color;
@@ -244,7 +261,7 @@ IEnumerator Capture () {
244261

245262
// Encode the resulting output texture to a byte array then write to the file
246263
byte[] pngShot = outputtex.EncodeToPNG();
247-
File.WriteAllBytes(name, pngShot);
264+
File.WriteAllBytes(filename, pngShot);
248265

249266
// Reset the time scale, then move on to the next frame.
250267
Time.timeScale = originaltimescaleTime;
@@ -254,9 +271,25 @@ IEnumerator Capture () {
254271
// Debug.Log("Frame " + name + " " + videoframe);
255272
}
256273
else {
257-
Debug.Log("Complete! "+videoframe+" videoframes rendered (0 indexed)");
274+
Debug.Log("Complete! " + videoframe + " videoframes rendered (0 indexed)");
258275
done = true;
259276
}
260277
}
278+
279+
// Get the texture from the screen, render all or only half of the camera
280+
private Texture2D GetTex2D(bool renderAll) {
281+
// Create a texture the size of the screen, RGB24 format
282+
int width = Screen.width;
283+
int height = Screen.height;
284+
if (!renderAll) {
285+
width = width / 2;
286+
}
287+
288+
Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
289+
// Read screen contents into the texture
290+
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
291+
tex.Apply();
292+
return tex;
293+
}
261294
}
262295

30.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)