How to render image or film sequences to hdd

Hi,

is unity capable to render predefined camera sequences as image- or film-sequences to hdd in realtime with 25 frames/sec?

If yes, how could it be done?

Alex

No but you can make a script that does it or use external capture software.

as in:

Thanks Robbie / Eric :slight_smile:

Hmm, only this little script is needed?
I think it’s only possible to realize this with the pro-version, isn’t it?

You can use that script to produce one png per frame with the Unity indie version, then you need a software to build a single animation file. Quicktime pro si suggested.

God, I just found this thread.

I can’t tell you how excited this makes me. I’ve always loved the appearance of the high quality visuals in Unity, and for me, this is good enough to render out movies.

Machinema here I come.

Time to upgrade to Unity 2.0 and buy the replacement Mac for the dead G5.

iShowU HD? Upgrade your iShowU | shinywhitebox - screen recording for your mac Only 30 bucks USD.

I second IShowU. I tried most of the top OSX screen capture tools and none performed as well as IShowU HD.

Capturing won’t replace saving out a sequence of pngs in terms of quality but IShowU performs a decent job for a simpler capture.

Could you theoretically use the same technique to limit the framerate for your game?

Nope…it makes the game run as fast as possible. For framerate limiting, there’s a C# script floating around, or you can use this (basically the same thing, translated to Javascript):

import System.Threading;

private var oldTime = 0.0;
private var theDeltaTime = 0.0;
private var curTime = 0.0;
var frameRate = 30;

function Start () {
	theDeltaTime = 1.0 / frameRate;
	oldTime = Time.realtimeSinceStartup;
}

function LateUpdate () {
	curTime = Time.realtimeSinceStartup;
	var timeTaken = curTime - oldTime;
	if (timeTaken < theDeltaTime) {
		Thread.Sleep( 1000*(theDeltaTime - timeTaken) );
	}
	oldTime = curTime; 
}

–Eric

Hi,

I’ve done such a project this summer, exporting HDTV 3d realtime stuff from Unity to broadcast machines. I tried everything and what I found out at last is that going step by step throught the frames works technically, but the assembled video looks not smooth afterwards. Not that I want to judge the scripts written here, definately not, just wanted to tell from my experience that for this job it’s best to take hardware that takes the video signal from the Mac and converts it to the desired format. Had great results with Matrox boxes (Genlock interfaces) and also there is a graphics card from NVidia for roughly 20.000 US$ that does the job too.

Regards
Martin

This is a very old thread but I wanted to chime in with a solution for anyone who might come across this while googling. I created a script, which is basically a bunch of pieces of other scripts, plus my own terrible coding which does exactly what you’re asking. I too want to use unity for rendering still frames like mental ray / vray in maya and max as an image sequence because I like the unity work flow for world building, but I like my 3d software for character animation. So what I do is import the finished characters and camera in to a scene and build the world there, then I use this script to knock out the frames to a png sequence I can import to vegas (or premier, whatever) to add sounds and editing.

Here goes. This is a BASIC script, it’s basically digital duct tape but it works, and so if you can improve upon it please do, if nothing else it’s a start. Here’s giving back to the community, hope this helps someone:

using UnityEngine;
using System.Collections;



public class StillFrameRenderer : MonoBehaviour {

    public int ScreenWidth = 1280;
    public int ScreenHeight = 720;
    public int StartFrame = 0;
    public int EndFrame = 30;
 
    public string FileName = "MyProject";
    public string NumberSequenceStart = "00";
    public string SaveDirectory = "C:\\UnityRenderer\\";

    float curFrame = 0;
    /// <summary>
    ///  You attach this script to your main camera.
    ///
    /// Still Frame Renderer is a basic script that will generate a series of screen shots at a fixed 30fps and save the screen shots in order
    /// using the start and end frames. The game will pause every 1/30th of a second, save a screen shot and then stop at the EndFrame #.
    ///
    /// HOW TO USE THIS:
    /// 1. Attach this script to the main camera!
    /// 2. Set your start and end frames
    /// 3. Set File Name (leave off the PNG)
    /// 4. Set # Number Sequence start (this adds trailing zeros to the end of the file name
    /// 5. Create and then set your save directory with trailing slash
    /// 6. Start Scene.
    /// MAKE SURE THE DIRECTORY HAS A TRAILING SLASH & THAT IT EXISTS ALREADY BEFORE USING THE SCRIPT OR WHO KNOWS WHAT THE HELL WILL HAPPEN.
    ///
    /// Who the hell would want this? The main intention here is to use the Unity engine as a still frame render engine like the mental ray or scan
    /// line renderers in 3ds max and maya, blender, etc. This script allows you to do just that!
    ///
    /// For best results pause the game before pressing play...
    ///
    /// </summary>

    float deltaTime = 0.0f;

    void Awake()
    {
        QualitySettings.vSyncCount = 2; //set game to 30fps
        curFrame = 0; //set current frame counter to zero.
        //If we set time scale to .1f then in theory the game runs at 1/30th of a second if we set the vsyncCount to 2;
        Time.timeScale = .1f; //Set time scales to 1f or 1/30th of a second.
        Time.fixedDeltaTime = .1f;
    }
    // Use this for initialization
    void Start () {
  
    }
    bool wait = false;
    bool tick = false;
    float temptime = 0.0f;
  
  
    // Update is called once per frame
    void Update() {

        if (curFrame <= EndFrame)
        {
            deltaTime += (Time.deltaTime - deltaTime) * 0.1f;
          
            if (curFrame < StartFrame)
            {
                if (deltaTime >= 0.001) {
                    curFrame += 1;
                }
            } else {
                if (deltaTime >= 0.001)
                {
                    temptime = deltaTime;
                    Time.timeScale = 0;
                    Time.fixedDeltaTime = 0;
                    tick = true;
                }

                if (tick) {
                    RenderToPng();
                }

                if(!tick && wait)
                {
                    WaitForFrame();
                }
            }
        }
    }

    //copypasta from a screen shot script...
    public bool hasSaved()
    {
        //it's not enough to just check that the file exists, since it doesn't mean it's finished saving
        //we have to check if it can actually be opened
        Texture2D image;
        image = new Texture2D(Screen.width, Screen.height);
        bool imageLoadSuccess = image.LoadImage(System.IO.File.ReadAllBytes(getImage()));
        Destroy(image);
        return imageLoadSuccess;
    }

    public void WaitForFrame()
    {
        if (hasSaved()) //The file is saved, set time back to 1f and repeat!
        {
            curFrame += 1; //increment frame by 1.
            Debug.Log("Found Screenshot saved:" + filename + " now moving to next frame:  " + curFrame);
            deltaTime = 0.0f; // reset this
            Time.fixedDeltaTime = 0.1f; //
            Time.timeScale = .1f;
            tick = false; //reset conditionals...
            wait = false;
        }
    }

    public string getImage()
    {
        return filename;
    }
  
   string filename ="";

//copypasta from another script..
    public bool RenderToPng()
    {
        bool finished = false;
        RenderTexture rt = new RenderTexture(ScreenWidth, ScreenHeight, 24);
        GetComponent<Camera>().targetTexture = rt;
        Texture2D screenShot = new Texture2D(ScreenWidth, ScreenHeight, TextureFormat.RGB24, false);
        GetComponent<Camera>().Render();
        RenderTexture.active = rt;
        screenShot.ReadPixels(new Rect(0, 0, ScreenWidth, ScreenHeight), 0, 0);
        GetComponent<Camera>().targetTexture = null;
        RenderTexture.active = null; // JC: added to avoid errors
        Destroy(rt);
        byte[] bytes = screenShot.EncodeToPNG();
        filename = SaveDirectory + FileName + NumberSequenceStart + curFrame+".png";
        System.IO.File.WriteAllBytes(filename, bytes);
        Debug.Log(string.Format("Took screenshot to: {0}", filename));
        wait = true;
        tick = false;
        return finished;
    }

//This will not render in screenshots...
    void OnGUI()
    {
        int w = Screen.width, h = Screen.height;
        GUIStyle style = new GUIStyle();
        Rect rect = new Rect(0, 25, w, h * 2 / 100);
        style.alignment = TextAnchor.UpperLeft;
        style.fontSize = h * 2 / 100;
        style.normal.textColor = new Color(0.0f, 0.0f, 0.5f, 1.0f);
       string text = "SCENE IS RENDERING! Current Frame is: "+curFrame +" of "+EndFrame;
        GUI.Label(rect, text, style);
    }
}
1 Like

Program disables antialiasing settings.

With the latest version none of the examples using ScreenCapture or readPixels was working but i did eventually find this which worked a treat. GitHub - Unity-Technologies/GenericFrameRecorder: This GitHub package is DEPRECATED. Please get the new Unity Recorder from the Asset Store (https://assetstore.unity.com/packages/essentials/unity-recorder-94079) Use the editor builtin Bug Reporter to report issues. You can track and vote for issues on the Issue Tracker (https://issuetracker.unity3d.com)

1 Like

Binxalot thank you for sharing this script, after 7 years I’m making use of it! All the best

You could use ScreenCapture.CaptureScreenshot(“Namepic.jpg”,intimgquality);
For video you have Unity Recorder | Essentials | Unity Asset Store , which is included in the package manager in the latest unity versions
You can use Obi too as external application