Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [5.0.0] - 2023-09-19
### Added
- Tutorial in documentation to set up a Unity project with API scripting for starting recordings via a command line.

### Changed
- Removed resolution automatic rounding to the nearest even number when Movie Recorder uses MP4 codec and "Match Window Size" output resolution.

### Fixed
- Prevent video output from being corrupted when generated via a Recorder Clip run through a Scene loaded in Play mode.
- Ensure the project uses the right RenderPipeline settings at all time: quality RenderPipeline settings or default RenderPipeline settings.
- Ensure that the status messages at the bottom of the Recorder window are always readable even if the window is small.
  • Loading branch information
Unity Technologies committed Sep 19, 2023
1 parent 618752c commit 4ae66f5
Show file tree
Hide file tree
Showing 23 changed files with 451 additions and 126 deletions.
74 changes: 0 additions & 74 deletions .editorconfig

This file was deleted.

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.0.0] - 2023-09-19
### Added
- Tutorial in documentation to set up a Unity project with API scripting for starting recordings via a command line.

### Changed
- Removed resolution automatic rounding to the nearest even number when Movie Recorder uses MP4 codec and "Match Window Size" output resolution.

### Fixed
- Prevent video output from being corrupted when generated via a Recorder Clip run through a Scene loaded in Play mode.
- Ensure the project uses the right RenderPipeline settings at all time: quality RenderPipeline settings or default RenderPipeline settings.
- Ensure that the status messages at the bottom of the Recorder window are always readable even if the window is small.

## [5.0.0-pre.1] - 2023-05-11
### Changed
- Updated minimum required Unity Editor version to 2023.1.
Expand Down
147 changes: 147 additions & 0 deletions Documentation~/CommandLineRecorder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Presets;
using UnityEditor.Recorder;
using UnityEngine;

public class CommandLineRecorder : MonoBehaviour
{
// The RecorderController starts and stops the recording.
private RecorderController m_Controller;

// The first frame to record.
[SerializeField] private int m_startFrame;

// The last frame to record.
[SerializeField] private int m_endFrame;

// The path to the Recorder Settings preset file to use for the recording.
[SerializeField] private string m_presetPath;

static RecorderSettings LoadRecorderSettingsFromPreset(string presetPath)
{
// Load the Preset from the provided path.
var preset = AssetDatabase.LoadAssetAtPath<Preset>(presetPath);

// Use reflection to determine the type of the RecorderSettings to use
// (for example a MovieRecorderSettings).
var recorderSettingsTypes =
TypeCache.GetTypesDerivedFrom<RecorderSettings>().ToList();

var recorderSettingsType = recorderSettingsTypes.SingleOrDefault(
t => t.Name == preset.GetTargetTypeName());

if (recorderSettingsType == null)
{
Debug.Log("Preset must be a subclass of RecorderSettings");
return null;
}

// Create a new RecorderSettings instance and apply the Preset to it.
RecorderSettings outSettings =
(RecorderSettings)ScriptableObject.CreateInstance(recorderSettingsType);

preset.ApplyTo(outSettings);
outSettings.name = preset.name;

return outSettings;
}

void StartRecording(string presetPath, int startFrame, int endFrame)
{
// Create RecorderSettings from the provided Preset path.
RecorderSettings recorderSettings = LoadRecorderSettingsFromPreset(presetPath);
recorderSettings.FrameRate = 60;

// Create a new RecorderControllerSettings to set the start and end frame for
// the recording session and add the RecorderSettings to it.
var controllerSettings = ScriptableObject.CreateInstance<RecorderControllerSettings>();
controllerSettings.AddRecorderSettings(recorderSettings);
controllerSettings.SetRecordModeToFrameInterval(startFrame, endFrame);

// Create and setup a new RecorderController and start the recording.
m_Controller = new RecorderController(controllerSettings);
m_Controller.PrepareRecording();
m_Controller.StartRecording();
}

void OnEnable()
{
// This is called once when Unity enters PlayMode.
StartRecording(m_presetPath, m_startFrame, m_endFrame);
}

void Update()
{
// This is called on every frame when Unity is in PlayMode.
if (m_Controller != null && !m_Controller.IsRecording())
{
// When the RecorderController has no more frame to record, stop
// the recording and exit the PlayMode.
m_Controller.StopRecording();
EditorApplication.ExitPlaymode();
}
}

static Dictionary<string, string> GetCommandLineArgs()
{
string[] cmdLineParts = Environment.GetCommandLineArgs();
Dictionary<String, String> arguments = new Dictionary<string, string>();

// These are the 3 arguments this MonoBehaviour expects to start a recording.
string[] args = { "-startFrame", "-endFrame", "-presetPath" };

var idx = 1;
while (idx < cmdLineParts.Length)
{
var part = cmdLineParts[idx];
if (args.Contains(part))
{
var argName = part.TrimStart('-');
arguments[argName] = cmdLineParts[idx + 1];
}

idx++;
}

return arguments;
}

private void SetRecordingInfo(int startFrame, int endFrame, string presetPath)
{
m_startFrame = startFrame;
m_endFrame = endFrame;
m_presetPath = presetPath;
AssetDatabase.SaveAssets();
}

public static void ExecuteCommandLine()
{
// Parse the command line arguments to find the start and end frame and
// the path to the Recorder Settings Preset file to use.
var args = GetCommandLineArgs();
if (!args.TryGetValue("startFrame", out var startFrame))
throw new ArgumentException("[ERROR] Expected argument -startFrame");

if (!args.TryGetValue("endFrame", out var endFrame))
throw new ArgumentException("[ERROR] Expected argument -endFrame");

if (!args.TryGetValue("presetPath", out var presetPath))
throw new ArgumentException("[ERROR] Expected argument -presetPath");

// Find the GameObject that has the CommandLineRecorder MonoBehaviour attached
// to it and set the recording information provided by the command line arguments.
var sceneCommandLineRecorder =
FindObjectsByType<CommandLineRecorder>(FindObjectsSortMode.None).First();

sceneCommandLineRecorder.SetRecordingInfo(
Convert.ToInt32(startFrame),
Convert.ToInt32(endFrame),
presetPath);

// Enter PlayMode: which starts the Recording (OnEnable)
EditorApplication.EnterPlaymode();
}
}
Loading

0 comments on commit 4ae66f5

Please sign in to comment.