diff --git a/CHANGELOG.md b/CHANGELOG.md index c76967e..99d349f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,44 @@ # Changelog All notable changes to this package will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +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). + +## [3.0.0-pre.1] - 2021-04-07 +### Added +- Added public API for AOVRecorderSettings. + +### Changed +- Enabled alpha channel capture in projects that use HDRP. +- Changed the package display name from "Unity Recorder" to "Recorder" in the package manager. + +### Fixed +- Fixed clipped text in the file path drop down. +- Fixed an error that occurred when setting the build target to macOS standalone from the Editor in Windows. +- Fixed an exception that occurred when the user performed the undo action after deleting a Recorder. +- Fixed a wrong label for the WebM codec. +- Fixed invalid values in the alpha channel when performing texture sampling for different rendering and output resolutions. +- Ensure that the Image Recorder encodes in sRGB when requested, even if the scripted render pipeline provides linear data. +- Fixed a memory leak in the AOV Recorder. +- Fixed the Tagged Camera capture process to follow any camera changes that might occur. +- Improve the console messages for errors and warnings when Recorders are not properly configured. + +### Removed +- Removed legacy Recorders: MP4, EXR, PNG, WEBM and GIF Animation. ## [2.6.0-exp.4] - 2021-02-22 ### Fixed - - Fixed an invalid AOV error when selecting the Albedo AOV. +- Fixed an "invalid AOV" error that occurred when selecting the Albedo AOV. ## [2.6.0-exp.3] - 2021-02-19 ### Added - Added support for recording accumulation in HDRP, for motion blur and path tracer. -- Integrated AOV Recorder into this package. +- Integrated the AOV Recorder into this package. +
**Note:** If you previously installed the formerly separate AOV Recorder package, you should uninstall it to avoid any unexpected recording issues. + +### Fixed +- Fixed an issue where the Recorder Window's display name would be incorrect when using the Recorder Editor Sample. +- Fixed a UI issue where foldouts in the RecorderSettingPreset asset would not open when clicking their header name. ## [2.5.4] - 2021-01-25 ### Fixed @@ -49,7 +76,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed a bug where switching from an absolute path to any other path type would create an invalid output path. - Log a warning when multiple concurrent Movie Recorder instances are concurrent, because this is not supported. - Fixed a visual glitch with the "Cap FPS" checkbox extending outside its GUI element. -- Forced the "Render Frame Step" values in Recorders to be larger than zero. +- Forced the "Render Frame Step" values in Recorders to be larger than zero. - Fixed a bug causing excessive Timeline updates while changing the output file. - Removed superfluous "CaptureAudio" option from the AudioRecorder. - Fixed a bug that caused Copy/Pasted RecorderClips to lose the settings when entering in playmode. @@ -67,7 +94,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - UX improvements ### Bugfixes -- Fixed a bug that in the texture sampler recorder for animated camera fov and animated physical properties +- Fixed a bug that in the texture sampler recorder for animated camera fov and animated physical properties - Fixed a bug that caused the recorder to hang when docked next to the GameView. - Fixed a bug that caused the recorder to hang if starting recording while already in playmode - Fixed a bug where the AudioRecorder would not close the handle to the recorded file. @@ -85,8 +112,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [2.2.0-preview.4] - 2020-04-08 ### Public API and bugfixes - Added public api's to allow loading previously saved recorder lists. -- Fixed bug where the first few frames after going in play-mode were not recorded. -- Fixed a bug where the texture sampling recorder that did not correctly support the physical cameras. +- Fixed bug where the first few frames after going in play-mode were not recorded. +- Fixed a bug where the texture sampling recorder that did not correctly support the physical cameras. - Fixed an issue when starting a record session from scripts. - Fixed movie recoder's default framerate value being not set in the API. Default value is now set at 30 FPS. diff --git a/Documentation~/Images/AOVRecorderWindow.png b/Documentation~/Images/AOVRecorderWindow.png index 3ff72b6..7966f52 100644 Binary files a/Documentation~/Images/AOVRecorderWindow.png and b/Documentation~/Images/AOVRecorderWindow.png differ diff --git a/Documentation~/Images/RecorderAnimation.png b/Documentation~/Images/RecorderAnimation.png index 1762c6b..d287f30 100644 Binary files a/Documentation~/Images/RecorderAnimation.png and b/Documentation~/Images/RecorderAnimation.png differ diff --git a/Documentation~/Images/RecorderAudio.png b/Documentation~/Images/RecorderAudio.png index bc56c83..5cce0ba 100644 Binary files a/Documentation~/Images/RecorderAudio.png and b/Documentation~/Images/RecorderAudio.png differ diff --git a/Documentation~/Images/RecorderGIF.png b/Documentation~/Images/RecorderGIF.png deleted file mode 100644 index 9d7a075..0000000 Binary files a/Documentation~/Images/RecorderGIF.png and /dev/null differ diff --git a/Documentation~/Images/RecorderImage.png b/Documentation~/Images/RecorderImage.png index 8f10d9b..acbb174 100644 Binary files a/Documentation~/Images/RecorderImage.png and b/Documentation~/Images/RecorderImage.png differ diff --git a/Documentation~/Images/RecorderList.png b/Documentation~/Images/RecorderList.png index 7881f67..d7abfb1 100644 Binary files a/Documentation~/Images/RecorderList.png and b/Documentation~/Images/RecorderList.png differ diff --git a/Documentation~/Images/RecorderMovie.png b/Documentation~/Images/RecorderMovie.png index b8ec8d0..d26ce8d 100644 Binary files a/Documentation~/Images/RecorderMovie.png and b/Documentation~/Images/RecorderMovie.png differ diff --git a/Documentation~/Images/RecorderReveal.png.meta b/Documentation~/Images/RecorderReveal.png.meta deleted file mode 100644 index b831455..0000000 --- a/Documentation~/Images/RecorderReveal.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 4ef8b1e7678f57247bb8c385832e7af1 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 7 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Documentation~/Images/RecorderSplash.png.meta b/Documentation~/Images/RecorderSplash.png.meta deleted file mode 100644 index d2f77e1..0000000 --- a/Documentation~/Images/RecorderSplash.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 146dea9a138a4fa4499009102dd33887 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 7 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Documentation~/Images/RecorderWindow.png b/Documentation~/Images/RecorderWindow.png index af80eff..b5c761e 100644 Binary files a/Documentation~/Images/RecorderWindow.png and b/Documentation~/Images/RecorderWindow.png differ diff --git a/Documentation~/Images/RecorderWindow.png.meta b/Documentation~/Images/RecorderWindow.png.meta deleted file mode 100644 index ff60978..0000000 --- a/Documentation~/Images/RecorderWindow.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 9c22db835b48e7440862a0deea28c6d6 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 7 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Documentation~/Images/TimelineRecorderTrack.png.meta b/Documentation~/Images/TimelineRecorderTrack.png.meta deleted file mode 100644 index 01fbe72..0000000 --- a/Documentation~/Images/TimelineRecorderTrack.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 4b73d55201adb1a44b8348220d7fb597 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 7 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Documentation~/KnownIssues.md b/Documentation~/KnownIssues.md index 05b0540..d8380eb 100644 --- a/Documentation~/KnownIssues.md +++ b/Documentation~/KnownIssues.md @@ -1,6 +1,6 @@ # Known issues and limitations -This page lists some known issues and limitations that you might experience with the Unity Recorder. It also gives basic instructions to help you work around them. +This page lists some known issues and limitations that you might experience with the Recorder. It also gives basic instructions to help you work around them. #### Recording slowdown with concurrent Movie Recorders @@ -12,9 +12,20 @@ This page lists some known issues and limitations that you might experience with **Limitation:** The Recorder currently supports only the recording of samples from the Unity built-in audio engine. As such, it cannot record audio from third-party audio engines such as FMOD Studio or Wwise. -**Workaround:** For a movie, you can record the third-party audio output in WAV format through another application, reimport this recorded file into the Unity Timeline, and then use the Unity Recorder to create the final movie with audio. Alternatively, you can use any video editing software to recompose audio and video. +**Workaround:** For a movie, you can record the third-party audio output in WAV format through another application, reimport this recorded file into the Unity Timeline, and then use the Recorder to create the final movie with audio. Alternatively, you can use any video editing software to recompose audio and video. -### AOV Recorder limitations +#### GIF Animation Recorder no longer available -* You can't select the Active Camera as the source of the recording. -* The AOV Recorder uses a linear gamma (instead of sRGB gamma curve) when recording in PNG and JPEG. +**Limitation:** This version of the Recorder no longer includes the GIF Animation Recorder, although it is still available in Recorder versions 2.5 and lower. + +**Workaround:** To produce a GIF animation, record your content with the [Image Sequence Recorder](RecorderImage.md) and then process the result through any external GIF animation software. + +#### Limited support of AA/TAA in AOVs + +**Limitation:** The Beauty AOV is the only AOV that you can currently record with Anti-Aliasing (AA) / Temporal Anti-Aliasing (TAA) enabled on your recording camera. + +#### Color artifacts in AOV recordings when TAA is enabled + +**Known issue:** If you record multiple AOVs while the recording camera has Temporal Anti-Aliasing (TAA) enabled, the recorded outputs might contain unexpected color artifacts. For example, some areas of a Beauty pass might include artificial colors coming from the data recorded for a Normal pass. + +**Workaround:** If you need to record a Beauty pass with TAA enabled on your recording camera, you should record it through its own recording session, separately from any other AOVs. diff --git a/Documentation~/RecorderAOV.md b/Documentation~/RecorderAOV.md index b9df0bb..017dabe 100644 --- a/Documentation~/RecorderAOV.md +++ b/Documentation~/RecorderAOV.md @@ -2,7 +2,9 @@ AOV recording is a process that extracts specific render pass data from the Scene that a specific Camera views. This mainly includes render passes related to the material, geometry, depth, motion, and lighting response of the GameObjects in the Scene. -The Unity AOV Recorder generates a sequence of image files in various formats including compressed HDR EXR and supports the recording of [multiple AOVs](#aov-to-export) for various [use cases](#use-case-examples). +The AOV Recorder only works with projects that use Unity's [HDRP (High Definition Render Pipeline)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest). It generates a sequence of image files in various formats including compressed EXR and supports the recording of [several different AOVs](#aov-to-export) for various [use cases](#use-case-examples). + +>**Note:** This AOV Recorder replaces the one that was formerly available through a separate package. If you previously installed the separate AOV Recorder package, you should uninstall it to avoid any unexpected recording issues. This page covers all properties specific to the AOV Image Sequence Recorder type. @@ -31,17 +33,25 @@ The following table describes for each one the type of data recorded in each fra | AOV | Recorded data | Pixel value | |:---|:---|:---| | Beauty | The final rendered view (after post-process) without the alpha. | RGB color. | -| Albedo | The overall perceived colors of the objects in view, with no lighting calculation and no shadows. This includes data from albedo values or albedo maps of the object materials. | RGB color. | +| Albedo | The overall perceived colors of the surfaces in view, with no lighting calculation and no shadows. This includes data from albedo values or albedo maps of the surface materials. | RGB color. | | Normals | The normals of the surfaces in view, resulting from geometric normals and materials normal maps. | R, G and B channels:
The values of the R,G,B channels respectively represent the X,Y,Z vector coordinates of the normals in World Space. | -| Smoothness | The glossiness or roughness of the surfaces in view. This includes data from smoothness values or smoothness maps of the object materials. | Grayscale:
• Black (value of 0) = rough
• White (value of 1) = glossy | -| Ambient Occlusion | The ambient occlusion data from the material maps of the objects in view. This does not include data resulting from any ambient occlusion effects. | Grayscale:
• Black (value of 0) = fully occluded
• White (value of 1) = not occluded | -| Metal | The metallic or non-metallic surfaces in view. This includes data from metal values or metal maps of the object materials. | Grayscale:
• Black (value of 0) = non-metal
• White (value of 1) = metal | -| Specular | The specular colors of the objects in view. This includes data from specular color values or specular color maps of the object materials. | RGB color. | -| Alpha | The transparency or opacity of the objects in view. This includes data from alpha values or alpha maps of the object materials. | Grayscale:
• Black (value of 0) = transparent
• White (value of 1) = opaque | -| Diffuse Lighting | The diffuse light response of the objects in view according to the current lighting of the Scene. It depends on the object materials and includes shadows. | RGB color. | -| Specular Lighting | The specular light response of the objects in view according to the current lighting of the Scene. It depends on the object materials and includes shadows. | RGB color. | -| Motion Vectors | The 2D vectors representing the relative movements of the objects, perceived from the recording Camera. | R and G channels only:
• The values of the R and G channels respectively represent the horizontal and vertical coordinates of the vectors in the image plane.
• The range of values is between -1 and 1, normalized to the **Output Resolution** you selected for the recording. | -| Depth | The relative distances of the objects in view between the Far Plane (farthest point from the camera) and the Near Plane (closest point to the camera). | Grayscale:
• Black (value of 0) = at Far Plane
• White (value of 1) = at Near Plane | +| Smoothness | The glossiness or roughness of the surfaces in view. This includes data from smoothness values or smoothness maps of the surface materials. | Grayscale:
• Black (value of 0) = rough
• White (value of 1) = glossy | +| Ambient Occlusion | The ambient occlusion data from the material maps of the surfaces in view. This does not include data resulting from any ambient occlusion effects. | Grayscale:
• Black (value of 0) = fully occluded
• White (value of 1) = not occluded | +| Metal | The metallic or non-metallic surfaces in view. This includes data from metal values or metal maps of the surface materials. | Grayscale:
• Black (value of 0) = non-metal
• White (value of 1) = metal | +| Specular | The specular colors of the surfaces in view. This includes data from specular color values or specular color maps of the surface materials. | RGB color. | +| Alpha | The transparency or opacity of the surfaces in view. This includes data from alpha values or alpha maps of the surface materials. | Grayscale:
• Black (value of 0) = transparent
• White (value of 1) = opaque | +| Diffuse Lighting* | The direct _and_ indirect diffuse light response of the surfaces in view. | RGB color. | +| Specular Lighting* | The direct _and_ indirect specular light response of the surfaces in view. | RGB color. | +| Direct Diffuse* | Only the direct diffuse light response of the surfaces in view. | RGB color. | +| Direct Specular* | Only the direct specular light response of the surfaces in view. | RGB color. | +| Indirect Diffuse* | Only the indirect diffuse light response of the surfaces in view. | RGB color. | +| Reflection* | The light reflected by the surfaces in view. | RGB color. | +| Refraction* | The light refracted through the surfaces in view. | RGB color. | +| Emissive* | The light emitted by the surfaces in view. | RGB color. | +| Motion Vectors | The 2D vectors representing the movements in the Scene, relative to the recording Camera. | R and G channels only:
• The values of the R and G channels respectively represent the horizontal and vertical coordinates of the vectors in the image plane.
• The range of values is between -1 and 1, normalized to the **Output Resolution** you selected for the recording. | +| Depth | The relative distances of the Scene elements in view between the Far Plane (farthest point from the camera) and the Near Plane (closest point to the camera). | Grayscale:
• Black (value of 0) = at Far Plane
• White (value of 1) = at Near Plane | + +_\* These specific AOVs are for light decomposition purposes. The recorded data depends on the current lighting of the Scene and on the surface materials, and includes shadows._ ### Source camera diff --git a/Documentation~/RecorderDebugging.md b/Documentation~/RecorderDebugging.md index bf92f3b..eb54cb8 100644 --- a/Documentation~/RecorderDebugging.md +++ b/Documentation~/RecorderDebugging.md @@ -1,10 +1,10 @@ # Debugging Recorders -The Unity Recorder includes tools that can help you diagnose problems you may encounter during captures. +The Recorder includes tools that can help you diagnose problems you may encounter during captures. -## Unity Recorder GameObjects +## Recorder GameObjects -The Unity Recorder adds a **Unity-RecorderSessions** GameObject to Scenes to help manage capture sessions. The **Unity-RecorderSessions** GameObject has components that bind Recorders to GameObjects in your scene, and store the progress of the current recording session. +The Recorder adds a **Unity-RecorderSessions** GameObject to Scenes to help manage capture sessions. The **Unity-RecorderSessions** GameObject has components that bind Recorders to GameObjects in your scene, and store the progress of the current recording session. By default, Unity hides the **Unity-RecorderSessions** GameObject, but you can make it visible in the [Hierarchy window](https://docs.unity3d.com/Manual/Hierarchy.html). This is useful for debugging. For example, if a Recorder is not working properly, you can toggle the **Unity-RecorderSessions** GameObject on to make sure that Unity creates it properly when you launch the recording session. diff --git a/Documentation~/RecorderGif.md b/Documentation~/RecorderGif.md deleted file mode 100644 index 7929da7..0000000 --- a/Documentation~/RecorderGif.md +++ /dev/null @@ -1,51 +0,0 @@ -# GIF Animation Recorder properties - -The **GIF Animation Recorder** generates an animated GIF file. - -This page covers all properties specific to the GIF Animation Recorder type. - -> **Note:** To fully configure any Recorder, you must also set the general recording properties according to the recording interface you are using: the [Recorder window](RecorderWindowRecordingProperties.md) or a [Recorder Clip](RecordingTimelineTrack.md#recorder-clip-properties). - -![](Images/RecorderGIF.png) - -The GIF Animation Recorder properties fall into three main categories: -* [Capture](#capture) -* [Format](#format) -* [Output File](#output-file) - -## Capture - -Use this section to define the source and the content of your recording. - -|Property||Function| -|:---|:---|:---| -| **Source** || Specifies the input for the recording. | -|| Targeted Camera |Records frames captured by a specific camera, even if the Game View does not use that camera.

Selecting this option displays the [Targeted Camera capture properties](#targeted-camera).| -|| Render Texture Asset |Records frames rendered in a Render Texture.

Selecting this option displays the [Render Texture Asset capture properties](#render-texture-asset).| -|| Texture Sampling |Supersamples the source camera during the capture to generate anti-aliased images in the recording.

Selecting this option displays the [Texture Sampling capture properties](#texture-sampling).| -| **Flip Vertical** ||When you enable this option, the Recorder flips the output image vertically.
This is useful to correct for systems that output video upside down.| - -### Targeted Camera -[!include[](InclCaptureOptionsTargetedCamera.md)] - -### Render Texture Asset -[!include[](InclCaptureOptionsRenderTextureAsset.md)] - -### Texture Sampling -[!include[](InclCaptureOptionsTextureSampling.md)] - -## Format - -Use this section to set up the media format you need to save the recorded images in. - -|Property|Function| -|:---|:---| -| **Num Colors** |The number of colors used in the GIF palette table. The maximum is 256 colors. Specify a smaller palette to reduce the size of the GIF file while reducing image quality.| -| **Keyframe Interval** |The number of frames that share the same color palette. Increase this number to reduce the size of the GIF file while reducing image quality.| -| **Max Tasks** |The number of frames to encode in parallel. If you increase this number, it might reduce the amount of time Unity takes to encode the GIF file.| - -## Output File - -Use this section to specify the output **Path** and **File Name** pattern to save the recorded GIF file. - -> **Note:** [Output File properties](OutputFileProperties.md) work the same for all types of recorders. diff --git a/Documentation~/RecorderImage.md b/Documentation~/RecorderImage.md index 89b9184..c67954d 100644 --- a/Documentation~/RecorderImage.md +++ b/Documentation~/RecorderImage.md @@ -53,10 +53,14 @@ Use this section to set up the media format you need to save the recorded images |Property||Function| |:---|:---|:---| | **Media File Format** || The file encoding format.

Choose **PNG**, **JPEG**, or **EXR** ([OpenEXR](https://en.wikipedia.org/wiki/OpenEXR)). The Recorder encodes EXR in 16 bits. | +| **Include Alpha** || Enable this property to include the alpha channel in the recording. Disable it to only record the RGB channels.

This property is not available when the selected **Media File Format** doesn't support transparency, or when **Capture** is set to **Game View**. | | **Color Space** | | The color space (gamma curve and gamut) to use in the output images. | | | sRGB, sRGB | Uses sRGB curve and sRGB primaries. | | | Linear, sRGB (unclamped) | Uses linear curve and sRGB primaries.
This option is only available when you set the **Format** to **EXR**.

**Important:** To get the expected unclamped values in the output images, you must:

• Disable any Tonemapping post-processing effects in your Scene (menu: **Edit > Project Settings > HDRP Default Settings** and deselect **Tonemapping**) and in any Volume that includes a Tonemapping override (select the Volume, navigate in the Inspector and deselect **Tonemapping** if present).

• Disable **Dithering** on the Camera selected for the capture (in the Inspector, navigate to **General** and deselect **Dithering**). | -| **Include Alpha** || Enable this property to include the alpha channel in the recording. Disable it to only record the RGB channels.

This property is not available when the selected **Media File Format** doesn't support transparency, or when **Capture** is set to **Game View**. | +| **Compression** | | The compression method to apply when saving the data.
This property is only available when you set the **Media File Format** to **EXR**. | +| | None | Disables all compression. | +| | Zip | Applies deflate compression to blocks of 16 scanlines at a time.
This is the default selection. | +| | RLE | Applies [Run-length encoding](https://en.wikipedia.org/wiki/Run-length_encoding) compression. | ## Output File diff --git a/Documentation~/RecorderMovie.md b/Documentation~/RecorderMovie.md index c78dbe2..16349ec 100644 --- a/Documentation~/RecorderMovie.md +++ b/Documentation~/RecorderMovie.md @@ -1,6 +1,6 @@ # Movie Recorder properties -The **Movie Recorder** generates videos in the H.264 MP4, VP9 WebM, or ProRes QuickTime format. It does not support variable frame rates. +The **Movie Recorder** generates videos in the H.264 MP4, VP8 WebM, or ProRes QuickTime format. It does not support variable frame rates. This page covers all properties specific to the Movie Recorder type. @@ -53,9 +53,9 @@ Use this section to set up the media format you need to save the recorded images |Property|Function| |:---|:---| -| **Media File Format** | The encoding format of the Recorder's output. Choose **H.264 MP4**, **VP9 WebM** or **ProRes QuickTime**. | +| **Media File Format** | The encoding format of the Recorder's output. Choose **H.264 MP4**, **VP8 WebM** or **ProRes QuickTime**. | | **Include Alpha** | Enable this property to include the alpha channel in the recording. Disable it to only record the RGB channels.

This property is not available when the selected **Media File Format** or **Codec Format** doesn't support transparency, or when **Capture** is set to **Game View**. | -| **Quality** | The quality of the output movie: **Low**, **Medium**, or **High**. The lower the quality, the smaller the file size.

This property is only available when you set the **Media File Format** to **H.264 MP4** or **VP9 WebM**. | +| **Quality** | The quality of the output movie: **Low**, **Medium**, or **High**. The lower the quality, the smaller the file size.

This property is only available when you set the **Media File Format** to **H.264 MP4** or **VP8 WebM**. | | **Codec Format** | The video codec to use to encode the output file. Choose among a variety of [**Apple ProRes**](https://en.wikipedia.org/wiki/Apple_ProRes) codecs: **ProRes 4444 XQ**, **ProRes 4444**, **ProRes 422 HQ**, **ProRes 422**, **ProRes 422 LT** or **ProRes 422 Proxy**.

This property is only available when you set the **Media File Format** to **ProRes QuickTime**. | | **Color Definition** | The video color space to use for the recording. Currently, the only available option is **HD Rec. 709**, which refers to HDTV standard.

This property is only available when you set the **Media File Format** to **ProRes QuickTime**. | diff --git a/Documentation~/RecorderProperties.md b/Documentation~/RecorderProperties.md index bf6c9ee..4b8afb4 100644 --- a/Documentation~/RecorderProperties.md +++ b/Documentation~/RecorderProperties.md @@ -18,8 +18,6 @@ Each type of Recorder has specific **Capture** and **Format** properties you mus - [**Image Sequence Recorder properties**](RecorderImage.md) -- [**GIF Animation Recorder properties**](RecorderGif.md) - - [**Audio Recorder properties**](RecorderAudio.md) - [**AOV Image Sequence Recorder properties**](RecorderAOV.md) diff --git a/Documentation~/RecorderWindowRecordingProperties.md b/Documentation~/RecorderWindowRecordingProperties.md index 0e9e170..9740738 100644 --- a/Documentation~/RecorderWindowRecordingProperties.md +++ b/Documentation~/RecorderWindowRecordingProperties.md @@ -10,7 +10,7 @@ Use the general recording properties to simultaneously start or stop recordings |:---|:---|:---| |![](Images/BtnRecord.png)
**[Record Button]** | | [Starts](#starting-a-recording) or [stops](#stopping-a-recording) a recording session. | | **Start Recording**/
**Stop Recording** | | This button has exactly the same function and behavior as the Record Button (see above). | -|**Exit Play Mode** | | When you enable this option, the Unity Recorder automatically exits Play mode when it finishes recording. | +|**Exit Play Mode** | | When you enable this option, the Recorder automatically exits Play mode when it finishes recording. | | **Recording Mode** ||Allows you to specify the frames or time interval to record.| ||_Manual_ |Start or stop recording when you manually click **Start Recording** or **Stop Recording**, respectively.| || _Single Frame_ |Record a single frame. Use the **Target Frame** property to specify this frame.| @@ -28,13 +28,13 @@ Use the **Frame Rate** properties to specify how to constrain the frame rate dur | **Playback** ||Specifies how to control the frame rate during recording.| || _Constant_ |Limit the Recorder to a specific frame rate. Use the **Target** property to specify this rate.| || _Variable_ |Use the application's frame rate. Specify the upper limit of the application's rate during recording with the **Max FPS** property.

**Note:** The **Movie Recorder** does not support a variable frame rate.| -| **Target FPS** ||Sets the frame rate to capture the recording at. This property appears when you set **Playback** to **Constant**.

The Unity Recorder captures at this rate regardless of whether you run your application at a higher or lower frame rate. For example, if you set **Target FPS** to a custom value of 30 fps but you run your application at 60 fps, the Recorder captures at 30 fps.| -| **Max FPS** ||Limit the rate of updates in Play mode . This property is available when you set **Playback** to **Variable**. To prevent your application from exceeding this frame rate, the Unity Recorder inserts delays during playback. Use this property to reduce the size of the output.| +| **Target FPS** ||Sets the frame rate to capture the recording at. This property appears when you set **Playback** to **Constant**.

The Recorder captures at this rate regardless of whether you run your application at a higher or lower frame rate. For example, if you set **Target FPS** to a custom value of 30 fps but you run your application at 60 fps, the Recorder captures at 30 fps.| +| **Max FPS** ||Limit the rate of updates in Play mode . This property is available when you set **Playback** to **Variable**. To prevent your application from exceeding this frame rate, the Recorder inserts delays during playback. Use this property to reduce the size of the output.| | **Cap FPS** ||Enable this property when the frame rate of your application is faster than the **Target FPS**. This property is available when **Playback** is **Constant**.| ## Starting a recording -When you use the Recorder window, you must always start the recording manually. When you start a recording, the Unity Recorder activates Play mode (if it is not already active) and starts to capture Play mode data using all active Recorders. +When you use the Recorder window, you must always start the recording manually. When you start a recording, the Recorder activates Play mode (if it is not already active) and starts to capture Play mode data using all active Recorders. To start recording, you can do any of the following: - In the Recorder window, select the Record button or the **START RECORDING** button. diff --git a/Documentation~/TableOfContents.md b/Documentation~/TableOfContents.md index 0ccfa62..c89de09 100644 --- a/Documentation~/TableOfContents.md +++ b/Documentation~/TableOfContents.md @@ -8,7 +8,6 @@ * [Animation Clip Recorder](RecorderAnimation.md) * [Movie Recorder](RecorderMovie.md) * [Image Sequence Recorder](RecorderImage.md) - * [GIF Animation Recorder](RecorderGif.md) * [Audio Recorder](RecorderAudio.md) * [AOV Recorder](RecorderAOV.md) * [Debugging recorders](RecorderDebugging.md) diff --git a/Documentation~/index.md b/Documentation~/index.md index 6f0602e..1d6dfed 100644 --- a/Documentation~/index.md +++ b/Documentation~/index.md @@ -1,8 +1,8 @@ -# About Unity Recorder +# About Recorder -![Unity Recorder](Images/RecorderSplash.png) +![Recorder](Images/RecorderSplash.png) -Use the Unity Recorder package to capture and save data during [Play mode](https://docs.unity3d.com/Manual/GameView.html). For example, you can capture gameplay or a cinematic and save it as a video file. +Use the Recorder package to capture and save data during [Play mode](https://docs.unity3d.com/Manual/GameView.html). For example, you can capture gameplay or a cinematic and save it as a video file. >[!NOTE] >You can only use the Recorder in the Unity Editor. It does not work in standalone Unity Players or builds. @@ -19,31 +19,29 @@ You can set up and launch recordings in two ways: ### Default recorders -The Unity Recorder includes the following recorder types by default: +The Recorder includes the following recorder types by default: * **Animation Clip Recorder:** generates an animation clip in Unity Animation format (.anim extension). -* **Movie Recorder:** generates a video in H.264 MP4, VP9 WebM, or ProRes QuickTime format. +* **Movie Recorder:** generates a video in H.264 MP4, VP8 WebM, or ProRes QuickTime format. * **Image Sequence Recorder:** generates a sequence of image files in JPEG, PNG, or EXR (OpenEXR) format. -* **GIF Animation Recorder:** generates an animated GIF file. - * **Audio Recorder:** generates an audio clip in WAV format. * **AOV Recorder:** generates a sequence of image files in JPEG, PNG, or EXR (OpenEXR) format, to capture specific render pass data (for example, data related to materials, geometry, depth, motion, or lighting) in projects that use Unity's [HDRP (High Definition Render Pipeline)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest). +>**Note:** The AOV Recorder included in this version of the Recorder package replaces the one that was formerly available through a separate package. If you previously installed the separate AOV Recorder package, you should uninstall it to avoid any unexpected recording issues. + + ### Additional recorders -You can also benefit from additional Recorder types if you install specific packages along with the Unity Recorder: +You can also benefit from additional Recorder types if you install specific packages along with the Recorder: * The [Alembic for Unity](https://docs.unity3d.com/Packages/com.unity.formats.alembic@latest) package includes an **Alembic Clip Recorder**, which allows you to record and export GameObjects to an Alembic file. * The [FBX Exporter](https://docs.unity3d.com/Packages/com.unity.formats.fbx@latest) package includes an **FBX Recorder**, which allows you to record and export animations directly to FBX files. -### Legacy recorders - -As of version 1.0, Unity Recorder uses recorder types that take better advantage of Unity Editor features and are more stable than previous versions. If you're upgrading from a pre-1.0 version of Unity Recorder, or supporting legacy content, you can toggle the legacy recorder types from Unity's main menu: **Window > General > Recorder > Options > Show Legacy Recorders**. ## Package technical details @@ -53,10 +51,10 @@ To install this package, follow the instructions in the [Package Manager documen ### Requirements -This version of the Unity Recorder is compatible with the following versions of the Unity Editor: +This version of the Recorder is compatible with the following versions of the Unity Editor: * 2019.4 and later (recommended) ### Known issues and limitations -See the list of current [known issues and limitations](KnownIssues.md) that you might experience with the Unity Recorder, and their workarounds. +See the list of current [known issues and limitations](KnownIssues.md) that you might experience with the Recorder, and their workarounds. diff --git a/Editor/Encoding/CoreMediaEncoder.cs b/Editor/Encoding/CoreMediaEncoder.cs index da3d6c2..17e62ef 100644 --- a/Editor/Encoding/CoreMediaEncoder.cs +++ b/Editor/Encoding/CoreMediaEncoder.cs @@ -31,12 +31,10 @@ public CoreMediaEncoderRegister() SupportedFormats = new[] { VideoRecorderOutputFormat.MP4, VideoRecorderOutputFormat.WebM }; } - internal override bool SupportsResolution(MovieRecorderSettings settings, int width, int height, out string errorMessage) + internal override bool SupportsResolution(MovieRecorderSettings settings, int width, int height, out string errorMessage, out string warningMessage) { - if (!base.SupportsResolution(settings, width, height, out errorMessage)) - { + if (!base.SupportsResolution(settings, width, height, out errorMessage, out warningMessage)) return false; - } errorMessage = ""; if (settings.OutputFormat == VideoRecorderOutputFormat.MP4) @@ -46,11 +44,6 @@ internal override bool SupportsResolution(MovieRecorderSettings settings, int wi errorMessage = "The MP4 format does not support odd values in resolution"; return false; } - - if (width > 4096 || height > 4096) - { - Debug.LogWarning(string.Format("MP4 format might not support resolutions bigger than 4096. Current resolution: {0} x {1}.", width, height)); - } } return true; diff --git a/Editor/Encoding/MediaEncoder.cs b/Editor/Encoding/MediaEncoder.cs index c1fa23f..27b0f42 100644 --- a/Editor/Encoding/MediaEncoder.cs +++ b/Editor/Encoding/MediaEncoder.cs @@ -6,6 +6,7 @@ using Unity.Collections.LowLevel.Unsafe; using UnityEditor.Media; using UnityEditor.Recorder; +using UnityEditor.Recorder.Input; using UnityEngine; using static UnityEditor.Recorder.MovieRecorderSettings; @@ -227,15 +228,22 @@ internal virtual void GetAttributes(out List attr) attr = new List(); } - internal virtual bool SupportsResolution(MovieRecorderSettings settings, int width, int height, out string errorMessage) + internal virtual bool SupportsResolution(MovieRecorderSettings settings, int width, int height, out string errorMessage, out string warningMessage) { + errorMessage = ""; + warningMessage = ""; if (width <= 0 || height <= 0) { - errorMessage = string.Format("Invalid input resolution {0} x {1}.", width, height); - return false; + var rtSettings = settings.ImageInputSettings as RenderTextureInputSettings; + var inputIsNullRT = rtSettings != null && rtSettings.renderTexture == null; + if (!inputIsNullRT) + { + // We don't log this message for null RT input because in that case the fix should be to assign a RT + errorMessage = string.Format("The encoder doesn't support the input resolution {0}x{1}.", width, height); + return false; + } } - errorMessage = ""; return true; } diff --git a/Editor/ProRes/ProResEncoderPlugin.cs b/Editor/ProRes/ProResEncoderPlugin.cs index 8ec92c4..2c8c1cc 100644 --- a/Editor/ProRes/ProResEncoderPlugin.cs +++ b/Editor/ProRes/ProResEncoderPlugin.cs @@ -5,7 +5,7 @@ using Unity.Collections; using System.IO; using ProResOut; -#if UNITY_STANDALONE_OSX +#if UNITY_EDITOR_OSX using System.Text; #endif using UnityEngine; @@ -340,7 +340,7 @@ public void StartEncoding() int nCodecFormat = (int)codecFormat; -#if UNITY_STANDALONE_OSX +#if UNITY_EDITOR_OSX // Ensure that this codec format is supported, because on macOS we depend on AVFoundation in the OS System.Text.StringBuilder sb = new System.Text.StringBuilder(128); bool supported = ProResWrapperHelpers.SupportsCodecFormat(nCodecFormat, sb, sb.Capacity); diff --git a/Editor/Sources/AccumulationSettingsPropertyDrawer.cs b/Editor/Sources/AccumulationSettingsPropertyDrawer.cs index 0e59fc9..b9af9de 100644 --- a/Editor/Sources/AccumulationSettingsPropertyDrawer.cs +++ b/Editor/Sources/AccumulationSettingsPropertyDrawer.cs @@ -23,14 +23,8 @@ static class Styles private SerializedProperty m_ShutterFullyOpen; private SerializedProperty m_ShutterBeginsClosing; private const int k_MaxSamples = 8192; - - bool m_Initialized; void Initialize(SerializedProperty property) { - if (m_Initialized) - return; - - m_Initialized = true; m_CaptureAccumulation = property.FindPropertyRelative("captureAccumulation"); m_Samples = property.FindPropertyRelative("samples"); m_ShutterInterval = property.FindPropertyRelative("shutterInterval"); diff --git a/Editor/Sources/AspectRatioPropertyDrawer.cs b/Editor/Sources/AspectRatioPropertyDrawer.cs index 7974765..0d78c1c 100644 --- a/Editor/Sources/AspectRatioPropertyDrawer.cs +++ b/Editor/Sources/AspectRatioPropertyDrawer.cs @@ -13,8 +13,6 @@ class AspectRatioPropertyDrawer : PropertyDrawer SerializedProperty m_ImageAspect; - bool m_Initialized; - const string k_Format = "0.0###"; static GUIContent[] s_DisplayNames; @@ -32,11 +30,6 @@ class AspectRatioPropertyDrawer : PropertyDrawer void Initialize(SerializedProperty property) { - if (m_Initialized) - return; - - m_Initialized = true; - m_CustomAspectX = property.FindPropertyRelative("m_CustomAspectX"); m_CustomAspectY = property.FindPropertyRelative("m_CustomAspectY"); diff --git a/Editor/Sources/Recorders/AOVRecorder/EXRCompressionTypeDrawer.cs b/Editor/Sources/EXRCompressionTypeDrawer.cs similarity index 70% rename from Editor/Sources/Recorders/AOVRecorder/EXRCompressionTypeDrawer.cs rename to Editor/Sources/EXRCompressionTypeDrawer.cs index 0d1070a..8494e8b 100644 --- a/Editor/Sources/Recorders/AOVRecorder/EXRCompressionTypeDrawer.cs +++ b/Editor/Sources/EXRCompressionTypeDrawer.cs @@ -1,20 +1,18 @@ using System; -using System.ComponentModel; using System.Linq; -using UnityEditor.Recorder.AOV; using UnityEngine; namespace UnityEditor.Recorder { - [CustomPropertyDrawer(typeof(EXRCompressionType))] - class AOVCompressionTypePropertyDrawer : PropertyDrawer + [CustomPropertyDrawer(typeof(ImageRecorderSettings.EXRCompressionType))] + class CompressionTypePropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); EditorGUI.BeginChangeCheck(); - var compressionLabels = Enum.GetNames(typeof(EXRCompressionType)).ToArray(); + var compressionLabels = Enum.GetNames(typeof(ImageRecorderSettings.EXRCompressionType)).ToArray(); var newValue = EditorGUI.Popup(position, label.text, property.enumValueIndex, compressionLabels); property.enumValueIndex = newValue; diff --git a/Editor/Sources/Recorders/AOVRecorder/EXRCompressionTypeDrawer.cs.meta b/Editor/Sources/EXRCompressionTypeDrawer.cs.meta similarity index 100% rename from Editor/Sources/Recorders/AOVRecorder/EXRCompressionTypeDrawer.cs.meta rename to Editor/Sources/EXRCompressionTypeDrawer.cs.meta diff --git a/Editor/Sources/FileNameGenerator.cs b/Editor/Sources/FileNameGenerator.cs index a6525ed..95cac75 100644 --- a/Editor/Sources/FileNameGenerator.cs +++ b/Editor/Sources/FileNameGenerator.cs @@ -180,7 +180,7 @@ public string Leaf } /// - /// Indicates the absolute path (without the extension). + /// Indicates the absolute path of the folder to write file to. /// internal string AbsolutePath { @@ -197,12 +197,16 @@ public bool ForceAssetsFolder set { m_Path.forceAssetsFolder = value; } } - readonly RecorderSettings m_RecorderSettings; + RecorderSettings m_RecorderSettings; - internal FileNameGenerator(RecorderSettings recorderSettings) + internal RecorderSettings RecorderSettings { - m_RecorderSettings = recorderSettings; + set => m_RecorderSettings = value; + } + + internal FileNameGenerator() + { m_Wildcards = new List { new Wildcard(DefaultWildcard.Recorder, RecorderResolver), diff --git a/Editor/Sources/FileNameGeneratorDrawer.cs b/Editor/Sources/FileNameGeneratorDrawer.cs index bd52da8..09f8730 100644 --- a/Editor/Sources/FileNameGeneratorDrawer.cs +++ b/Editor/Sources/FileNameGeneratorDrawer.cs @@ -35,9 +35,6 @@ protected override void Initialize(SerializedProperty property) s_OpenPathIcon = UnityHelpers.LoadLocalPackageAsset($"{iconName}.png", true); } - if (target != null) - return; - base.Initialize(property); m_FileName = property.FindPropertyRelative("m_FileName"); diff --git a/Editor/Sources/Helpers/UnityHelpers.cs b/Editor/Sources/Helpers/UnityHelpers.cs index ffe20c0..9433d1e 100644 --- a/Editor/Sources/Helpers/UnityHelpers.cs +++ b/Editor/Sources/Helpers/UnityHelpers.cs @@ -1,11 +1,10 @@ using System.IO; -using System.Threading; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; using UnityEditor.SceneManagement; using UnityEngine; -using UnityEngine.SceneManagement; using UnityEngine.Rendering; +using UnityEngine.SceneManagement; #if HDRP_ACCUM_API using UnityEngine.Rendering.HighDefinition; #endif @@ -102,7 +101,7 @@ internal static string PackageDescription { get { - return "Unity Recorder " + PackageVersion; + return "Recorder " + PackageVersion; } } @@ -122,37 +121,6 @@ private static string PackageVersion } private static string m_PackageVersion = ""; - /// - /// Perform a vertical flip of the supplied texture. - /// - /// The texture to flip - /// Whether or not to include transparency - /// - internal static Texture2D FlipTextureVertically(Texture2D tex, bool captureAlpha) - { - var FlippedTexture = new Texture2D(tex.width, tex.height, tex.format, false); - // Texture2D -> RenderTexture for flip - var active = RenderTexture.active; // remember for later - var rt = RenderTexture.GetTemporary(tex.width, tex.height); - RenderTexture.active = rt; - // Use flip material - var copyMaterial = new Material(Shader.Find("Hidden/Recorder/Inputs/CameraInput/Copy")); - if (captureAlpha) - copyMaterial.EnableKeyword("TRANSPARENCY_ON"); - copyMaterial.EnableKeyword("VERTICAL_FLIP"); - Graphics.Blit(tex, rt, copyMaterial); // Copy Texture2D to RenderTexture using the shader above - // Flipped RenderTexture -> Texture2D - RenderTexture.active = rt; - FlippedTexture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); - FlippedTexture.Apply(); - - // Restore initial active RT - RenderTexture.active = active; // restore - RenderTexture.ReleaseTemporary(rt); - - return FlippedTexture; - } - /// /// Convert an RGBA32 texture to an RGB24 one. /// diff --git a/Editor/Sources/ImageInputSettings.cs b/Editor/Sources/ImageInputSettings.cs index 7b9f072..c0214cd 100644 --- a/Editor/Sources/ImageInputSettings.cs +++ b/Editor/Sources/ImageInputSettings.cs @@ -79,27 +79,23 @@ int ForceEvenIfNecessary(int v) return v; } - /// - protected internal override bool ValidityCheck(List errors) + protected internal override void CheckForWarnings(List warnings) { - var ok = true; + base.CheckForWarnings(warnings); - var h = OutputHeight; + if (OutputHeight > (int)maxSupportedSize) + warnings.Add($"The image size exceeds the recommended maximum height of {(int)maxSupportedSize} px: {OutputHeight}"); + } - if (h > (int)maxSupportedSize) - { - ok = false; - errors.Add("Output size exceeds maximum supported height: " + (int)maxSupportedSize + "px"); - } + protected internal override void CheckForErrors(List errors) + { + base.CheckForErrors(errors); + var h = OutputHeight; var w = OutputWidth; - if (w <= 0 || h <= 0) - { - ok = false; - errors.Add("Invalid output resolution: " + w + "x" + h); - } - return ok; + if (w <= 0 || h <= 0) + errors.Add($"Invalid source image resolution {w}x{h}"); } } } diff --git a/Editor/Sources/InputSettings.cs b/Editor/Sources/InputSettings.cs index 8c72a0f..6ac31bc 100644 --- a/Editor/Sources/InputSettings.cs +++ b/Editor/Sources/InputSettings.cs @@ -10,6 +10,14 @@ namespace UnityEditor.Recorder public abstract class RecorderInputSettings { protected internal abstract Type InputType { get; } - protected internal abstract bool ValidityCheck(List errors); + + [Obsolete("Please use methods CheckForErrors() and CheckForWarnings()")] + protected internal virtual bool ValidityCheck(List errors) + { + return true; + } + + protected internal virtual void CheckForWarnings(List warnings) {} + protected internal virtual void CheckForErrors(List errors) {} } } diff --git a/Editor/Sources/InputSettingsSelectorDrawer.cs b/Editor/Sources/InputSettingsSelectorDrawer.cs index fd544d9..a1e0709 100644 --- a/Editor/Sources/InputSettingsSelectorDrawer.cs +++ b/Editor/Sources/InputSettingsSelectorDrawer.cs @@ -9,8 +9,6 @@ namespace UnityEditor.Recorder [CustomPropertyDrawer(typeof(InputSettingsSelector), true)] class InputSettingsSelectorDrawer : TargetedPropertyDrawer { - bool m_Initialized; - GUIContent[] m_DisplayNames; Dictionary m_NameToIndex; Dictionary m_IndexToProperty; @@ -22,11 +20,7 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { - if (!m_Initialized) - { - Initialize(property); - m_Initialized = true; - } + Initialize(property); if (m_DisplayNames.Length == 0) { diff --git a/Editor/Sources/OutputPathDrawer.cs b/Editor/Sources/OutputPathDrawer.cs index 4a1c8a4..43eb5e8 100644 --- a/Editor/Sources/OutputPathDrawer.cs +++ b/Editor/Sources/OutputPathDrawer.cs @@ -16,17 +16,10 @@ protected override void Initialize(SerializedProperty property) { base.Initialize(property); - if (m_RootProperty == null) - m_RootProperty = property.FindPropertyRelative("m_Root"); - - if (m_LeafProperty == null) - m_LeafProperty = property.FindPropertyRelative("m_Leaf"); - - if (m_ForceAssetFolder == null) - m_ForceAssetFolder = property.FindPropertyRelative("m_ForceAssetFolder"); - - if (m_AbsolutePathProperty == null) - m_AbsolutePathProperty = property.FindPropertyRelative("m_AbsolutePath"); + m_RootProperty = property.FindPropertyRelative("m_Root"); + m_LeafProperty = property.FindPropertyRelative("m_Leaf"); + m_ForceAssetFolder = property.FindPropertyRelative("m_ForceAssetFolder"); + m_AbsolutePathProperty = property.FindPropertyRelative("m_AbsolutePath"); } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) @@ -40,7 +33,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten var indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; - const float rootWidth = 110.0f; + const float rootWidth = 125.0f; const float btnWidth = 30.0f; var leafWidth = target.forceAssetsFolder ? position.width - rootWidth : position.width - rootWidth - btnWidth - 10; diff --git a/Editor/Sources/OutputResolutionPropertyDrawer.cs b/Editor/Sources/OutputResolutionPropertyDrawer.cs index 758a8fd..9fb127d 100644 --- a/Editor/Sources/OutputResolutionPropertyDrawer.cs +++ b/Editor/Sources/OutputResolutionPropertyDrawer.cs @@ -15,7 +15,6 @@ class OutputResolutionPropertyDrawer : PropertyDrawer ImageHeightSelector m_HeightSelector; - bool m_Initialized; static class Styles { @@ -34,11 +33,6 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent void Initialize(SerializedProperty property) { - if (m_Initialized) - return; - - m_Initialized = true; - m_CustomWidth = property.FindPropertyRelative("m_CustomWidth"); m_CustomHeight = property.FindPropertyRelative("m_CustomHeight"); diff --git a/Editor/Sources/Recorder.cs b/Editor/Sources/Recorder.cs index 6701397..3112bff 100644 --- a/Editor/Sources/Recorder.cs +++ b/Editor/Sources/Recorder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using UnityEngine; namespace UnityEditor.Recorder @@ -59,10 +60,41 @@ void OnDestroy() internal abstract RecorderSettings settings { get; set; } + protected internal void ConsoleLogMessage(string message, LogType logType) + { + string sAborted = ""; + switch (logType) + { + case LogType.Warning: + sAborted = "Recording may cause slowdowns or generate an invalid file. "; + break; + case LogType.Error: + sAborted = "Recording failed. "; + break; + default: + break; + } + string logMessage = $"[{GetType().Name}: {settings.name}] {sAborted}{message}"; + switch (logType) + { + case LogType.Log: + Debug.Log(logMessage); + break; + case LogType.Warning: + Debug.LogWarning(logMessage); + break; + case LogType.Error: + Debug.LogError(logMessage); + break; + default: + throw new InvalidEnumArgumentException($"Log type {logType} is not supported yet."); + } + } + protected internal virtual void SessionCreated(RecordingSession session) { if (RecorderOptions.VerboseMode) - Debug.Log(string.Format("Recorder {0} session created", GetType().Name)); + ConsoleLogMessage("Session created", LogType.Log); settings.SelfAdjustSettings(); // ignore return value. @@ -71,9 +103,9 @@ protected internal virtual void SessionCreated(RecordingSession session) { var toCompare = 1.0f / fixedRate; if (Time.captureFramerate != 0 && Math.Abs(toCompare - Time.captureDeltaTime) > float.Epsilon) - Debug.LogError(string.Format("Recorder {0} is set to record at a fixed rate and another component has already set a conflicting value for [Time.captureFramerate], new value being applied : {1}!", GetType().Name, fixedRate)); + ConsoleLogMessage($"Recorder {GetType().Name} is set to record at a fixed rate and another component has already set a conflicting value for [Time.captureFramerate], new value being applied : {fixedRate}!", LogType.Error); else if (Time.captureFramerate == 0 && RecorderOptions.VerboseMode) - Debug.Log("Frame recorder set fixed frame rate to " + fixedRate); + ConsoleLogMessage($"Frame recorder set fixed frame rate to {fixedRate}", LogType.Log); // Note that Time.captureDeltaTime will be modified by HDRP SubFrameManager // to implement the accumulation motion blur/path tracer support. @@ -104,8 +136,35 @@ protected internal virtual bool BeginRecording(RecordingSession session) if (Recording) throw new Exception("Already recording!"); + // Log old warnings (non-blocking) + var oldWarnings = new List(); +#pragma warning disable 618 + if (!session.settings.ValidityCheck(oldWarnings)) +#pragma warning restore 618 + { + foreach (var w in oldWarnings) + ConsoleLogMessage(w, LogType.Warning); + } + + // Log non-blocking warnings + var warnings = new List(); + session.settings.GetWarnings(warnings); + foreach (var w in warnings) + ConsoleLogMessage(w, LogType.Warning); + + // Log blocking errors and stop + var errors = new List(); + session.settings.GetErrors(errors); + foreach (var w in errors) + ConsoleLogMessage(w, LogType.Error); + if (errors.Count > 0) + { + Recording = false; + return false; + } + if (RecorderOptions.VerboseMode) - Debug.Log(string.Format("Recorder {0} starting to record", GetType().Name)); + ConsoleLogMessage($"Starting to record", LogType.Log); return Recording = true; } @@ -129,7 +188,7 @@ protected internal virtual void EndRecording(RecordingSession session) { Time.captureFramerate = 0; if (RecorderOptions.VerboseMode) - Debug.Log("Recorder resetting 'CaptureFrameRate' to zero"); + ConsoleLogMessage("Recorder resetting 'CaptureFrameRate' to zero", LogType.Log); } } @@ -140,7 +199,7 @@ protected internal virtual void EndRecording(RecordingSession session) } if (RecorderOptions.VerboseMode) - Debug.Log(string.Format("{0} recording stopped, total frame count: {1}", GetType().Name, RecordedFramesCount)); + ConsoleLogMessage($"Recording stopped, total frame count: {RecordedFramesCount}", LogType.Log); ++settings.Take; } diff --git a/Editor/Sources/RecorderController.cs b/Editor/Sources/RecorderController.cs index 8c430de..928c73d 100644 --- a/Editor/Sources/RecorderController.cs +++ b/Editor/Sources/RecorderController.cs @@ -130,30 +130,15 @@ public bool StartRecording() return false; } - foreach (var recorderSetting in m_Settings.RecorderSettings) - { - var errors = new List(); - - // This can be done only here as some recorders needs data from scenes. - // Example: Animation Recorder needs their target to exist. - if (!recorderSetting.ValidityCheck(errors)) - { - foreach (var error in errors) - Debug.LogWarning(recorderSetting.name + ": " + error); - } - - if (errors.Count > 0) - { - if (RecorderOptions.VerboseMode) - Debug.LogWarning("Recorder '" + recorderSetting.name + - "' has warnings and may not record properly."); - } - } - if (RecorderOptions.VerboseMode) Debug.Log("Start Recording."); - var success = m_RecordingSessions.Any() && m_RecordingSessions.All(r => r.SessionCreated() && r.BeginRecording()); + // The controller successfully starts recording if all the sessions were correctly created and at least one session begun recording properly + var allSessionsCreated = m_RecordingSessions.All(r => r.SessionCreated()); + var atLeastOneSuccessfulRecording = false; + foreach (var r in m_RecordingSessions) + atLeastOneSuccessfulRecording |= r.BeginRecording(); + var success = m_RecordingSessions.Any() && allSessionsCreated && atLeastOneSuccessfulRecording; return success; } diff --git a/Editor/Sources/RecorderControllerSettings.cs b/Editor/Sources/RecorderControllerSettings.cs index 31fab4e..7b9f394 100644 --- a/Editor/Sources/RecorderControllerSettings.cs +++ b/Editor/Sources/RecorderControllerSettings.cs @@ -204,6 +204,8 @@ public IEnumerable RecorderSettings /// The Recorder Settings instance to add. public void AddRecorderSettings(RecorderSettings recorder) { + EditorUtility.SetDirty(this); + Undo.RegisterCompleteObjectUndo(this, "Add Recorder"); if (!m_RecorderSettings.Contains(recorder)) { AddRecorderInternal(recorder); @@ -219,7 +221,10 @@ public void RemoveRecorder(RecorderSettings recorder) { if (m_RecorderSettings.Contains(recorder)) { + EditorUtility.SetDirty(this); + Undo.RegisterCompleteObjectUndo(this, "Remove Recorder"); m_RecorderSettings.Remove(recorder); + Undo.DestroyObjectImmediate(recorder); Save(); } } diff --git a/Editor/Sources/RecorderControllerSettingsPresetEditor.cs b/Editor/Sources/RecorderControllerSettingsPresetEditor.cs index 7d376e4..baf3daf 100644 --- a/Editor/Sources/RecorderControllerSettingsPresetEditor.cs +++ b/Editor/Sources/RecorderControllerSettingsPresetEditor.cs @@ -62,7 +62,7 @@ public override void OnInspectorGUI() static bool FoldoutPresetEditorStateHeader(PresetEditorState state) { var r = EditorGUILayout.GetControlRect(); - state.expanded = EditorGUI.Foldout(r, state.expanded, state.presetEditor.target.name); + state.expanded = EditorGUI.Foldout(r, state.expanded, state.presetEditor.target.name, true); return state.expanded; } diff --git a/Editor/Sources/RecorderEditor.cs b/Editor/Sources/RecorderEditor.cs index 9074b6c..5ae454c 100644 --- a/Editor/Sources/RecorderEditor.cs +++ b/Editor/Sources/RecorderEditor.cs @@ -180,13 +180,28 @@ public override void OnInspectorGUI() /// protected virtual void OnValidateSettingsGUI() { - var errors = new List(); - if (!((RecorderSettings)target).ValidityCheck(errors)) + var oldWarnings = new List(); + var targetSettings = target as RecorderSettings; +#pragma warning disable 618 + if (!targetSettings.ValidityCheck(oldWarnings)) +#pragma warning restore 618 { - foreach (var error in errors) - EditorGUILayout.HelpBox(error, MessageType.Warning); - OnRecorderValidated?.Invoke(); + foreach (var e in oldWarnings) + EditorGUILayout.HelpBox(e, MessageType.Warning); } + + var warnings = new List(); + targetSettings.GetWarnings(warnings); + foreach (var w in warnings) + EditorGUILayout.HelpBox(w, MessageType.Warning); + + var errors = new List(); + targetSettings.GetErrors(errors); + foreach (var e in errors) + EditorGUILayout.HelpBox(e, MessageType.Error); + + if (oldWarnings.Count > 0 || warnings.Count > 0 || errors.Count > 0) + OnRecorderValidated?.Invoke(); } internal virtual bool DrawCaptureSection() diff --git a/Editor/Sources/RecorderItem.cs b/Editor/Sources/RecorderItem.cs index 972031e..feb8217 100644 --- a/Editor/Sources/RecorderItem.cs +++ b/Editor/Sources/RecorderItem.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using UnityEngine; using UnityObject = UnityEngine.Object; using UnityEngine.UIElements; diff --git a/Editor/Sources/RecorderOptions.cs b/Editor/Sources/RecorderOptions.cs index 7f80e0e..c8eba31 100644 --- a/Editor/Sources/RecorderOptions.cs +++ b/Editor/Sources/RecorderOptions.cs @@ -38,16 +38,6 @@ public static bool ShowRecorderGameObject } } - /// - /// If true, legacy recorders will be displayed in the "Add New Recorder" menu. - /// Legacy recorders are deprecated and will be removed from the Unity Recorder in future releases. - /// - public static bool ShowLegacyRecorders - { - get { return EditorPrefs.GetBool(k_ShowLegacyModeMenuItem, false); } - set { EditorPrefs.SetBool(k_ShowLegacyModeMenuItem, value); } - } - internal static bool exitPlayMode { get { return EditorPrefs.GetBool(k_ExitPayModeItem, false); } @@ -96,21 +86,6 @@ static bool ToggleShowRecorderGameObjectValidate() Menu.SetChecked(k_ShowRecorderGameObject, ShowRecorderGameObject); return true; } - - [MenuItem(k_ShowLegacyModeMenuItem, false, RecorderWindow.MenuRootIndex + 200)] - static void ToggleShowLegacyRecorders() - { - var value = !ShowLegacyRecorders; - EditorPrefs.SetBool(k_ShowLegacyModeMenuItem, value); - ShowLegacyRecorders = value; - } - - [MenuItem(k_ShowLegacyModeMenuItem, true)] - static bool ToggleShowLegacyRecordersValidate() - { - Menu.SetChecked(k_ShowLegacyModeMenuItem, ShowLegacyRecorders); - return true; - } } [UsedImplicitly] diff --git a/Editor/Sources/RecorderSettings.cs b/Editor/Sources/RecorderSettings.cs index 4690a84..dbfdfea 100644 --- a/Editor/Sources/RecorderSettings.cs +++ b/Editor/Sources/RecorderSettings.cs @@ -189,11 +189,12 @@ public float FrameRate /// protected RecorderSettings() { - fileNameGenerator = new FileNameGenerator(this) + fileNameGenerator = new FileNameGenerator() { Root = OutputPath.Root.Project, Leaf = "Recordings" }; + fileNameGenerator.RecorderSettings = this; } /// @@ -201,6 +202,7 @@ protected RecorderSettings() /// /// List of errors encountered. /// True if there are no errors, False otherwise. + [Obsolete("Please use methods GetErrors() and GetWarnings()")] protected internal virtual bool ValidityCheck(List errors) { var ok = true; @@ -208,9 +210,9 @@ protected internal virtual bool ValidityCheck(List errors) if (InputsSettings != null) { var inputErrors = new List(); - +#pragma warning disable 618 var valid = InputsSettings.All(x => x.ValidityCheck(inputErrors)); - +#pragma warning restore 618 if (!valid) { errors.AddRange(inputErrors); @@ -218,25 +220,56 @@ protected internal virtual bool ValidityCheck(List errors) } } + return ok; + } + + /// + /// Tests if the Recorder has any errors. + /// + /// List of errors encountered. + protected internal virtual void GetErrors(List errors) + { + if (InputsSettings != null) + { + foreach (var i in InputsSettings) + { + var inputErrors = new List(); + i.CheckForErrors(inputErrors); + errors.AddRange(inputErrors); + } + } + if (string.IsNullOrEmpty(fileNameGenerator.FileName)) { errors.Add("Missing file name"); - ok = false; } if (Math.Abs(FrameRate) <= float.Epsilon) { - ok = false; errors.Add("Invalid frame rate"); } if (!IsPlatformSupported) { errors.Add("Current platform is not supported"); - ok = false; } + } - return ok; + /// + /// Tests if the Recorder has any warnings. + /// + /// List of warnings encountered. + protected internal virtual void GetWarnings(List warnings) + { + if (InputsSettings != null) + { + foreach (var i in InputsSettings) + { + var inputWarnings = new List(); + i.CheckForWarnings(inputWarnings); + warnings.AddRange(inputWarnings); + } + } } /// @@ -267,14 +300,23 @@ public virtual void OnAfterDuplicate() { } + // Errors mean that the inspector will be blank so don't use them yet for problems that can be fixed in the inspector protected internal virtual bool HasErrors() { return false; } + // For now both errors and warnings make the recording invalid internal virtual bool HasWarnings() { - return !ValidityCheck(new List()); + var errors = new List(); + var warnings = new List(); +#pragma warning disable 618 + ValidityCheck(warnings); +#pragma warning restore 618 + GetErrors(errors); + GetWarnings(warnings); + return errors.Count > 0 || warnings.Count > 0; } /// @@ -289,9 +331,18 @@ internal void OnValidate() /// /// Indicates whether the current Recorder supports Accumulation recording or not. /// + /// True if the current Recorder supports Accumulation recording, False otherwise. public virtual bool IsAccumulationSupported() { return false; } + + /// + /// Indicates whether the color space should be converted from linear to sRGB or not. + /// + internal virtual bool NeedToConvertFromLinearToSRGB() + { + return false; + } } } diff --git a/Editor/Sources/RecorderSettingsAttribute.cs b/Editor/Sources/RecorderSettingsAttribute.cs index 9cfae05..5dd3b43 100644 --- a/Editor/Sources/RecorderSettingsAttribute.cs +++ b/Editor/Sources/RecorderSettingsAttribute.cs @@ -11,6 +11,7 @@ public class RecorderSettingsAttribute : Attribute internal readonly Type recorderType; internal readonly string displayName; internal readonly string iconName; + internal readonly bool deprecated = false; /// /// Constructor for the attribute. @@ -23,6 +24,19 @@ public RecorderSettingsAttribute(Type recorderType, string displayName) this.displayName = displayName; } + /// + /// Constructor for the attribute. + /// + /// The type of Recorder that uses this Recorder Settings instance. + /// The Recorder's display name. + /// Whether or not the Recorder is deprecated. + public RecorderSettingsAttribute(Type recorderType, string displayName, bool deprecated) + { + this.recorderType = recorderType; + this.displayName = displayName; + this.deprecated = deprecated; + } + /// /// Constructor for the attribute. /// @@ -35,5 +49,20 @@ public RecorderSettingsAttribute(Type recorderType, string displayName, string i this.recorderType = recorderType; this.displayName = displayName; } + + /// + /// Constructor for the attribute. + /// + /// The type of Recorder that uses this Recorder Settings instance. + /// The Recorder's display name. + /// The name of the icon. + /// Whether or not the Recorder is deprecated. + public RecorderSettingsAttribute(Type recorderType, string displayName, string iconName, bool deprecated) + { + this.iconName = iconName; + this.recorderType = recorderType; + this.displayName = displayName; + this.deprecated = deprecated; + } } } diff --git a/Editor/Sources/RecorderWindow.cs b/Editor/Sources/RecorderWindow.cs index 06600a8..1cef16d 100644 --- a/Editor/Sources/RecorderWindow.cs +++ b/Editor/Sources/RecorderWindow.cs @@ -14,7 +14,7 @@ namespace UnityEditor.Recorder { /// - /// Main window class of the Unity Recorder. + /// Main window class of the Recorder. /// It can be accessed from an Editor script to show the Recorder Window and eventually Start and Stop the recording using current settings. /// Recorder settings are saved in Library/Recorder/recorder.pref /// @@ -213,18 +213,24 @@ void ClearView() void RegisterCallbacks() { - Undo.undoRedoPerformed += SaveAndRepaint; + Undo.undoRedoPerformed += OnUndoRedoPerformed; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; EditorApplication.update += UpdateInternal; } void UnregisterCallbacks() { - Undo.undoRedoPerformed -= SaveAndRepaint; + Undo.undoRedoPerformed -= OnUndoRedoPerformed; EditorApplication.playModeStateChanged -= OnPlayModeStateChanged; EditorApplication.update -= UpdateInternal; } + void OnUndoRedoPerformed() + { + ReloadRecordings(); + SaveAndRepaint(); + } + void CreateView() { minSize = new Vector2(560.0f, 200.0f); @@ -643,7 +649,7 @@ void RecorderListExecuteCommand(EventBase evt, string commandName) } else if (commandName == "SoftDelete" || commandName == "Delete") { - DeleteRecorder(item, true); + DeleteRecorder(item); evt.StopPropagation(); } } @@ -705,14 +711,6 @@ void ShowNewRecorderMenu() foreach (var info in RecordersInventory.builtInRecorderInfos) AddRecorderInfoToMenu(info, newRecordMenu); - if (RecorderOptions.ShowLegacyRecorders) - { - newRecordMenu.AddSeparator(string.Empty); - - foreach (var info in RecordersInventory.legacyRecorderInfos) - AddRecorderInfoToMenu(info, newRecordMenu); - } - var recorderList = RecordersInventory.customRecorderInfos.ToList(); if (recorderList.Any()) @@ -960,7 +958,7 @@ void OnRecorderSettingsGUI() { if (m_SelectedRecorderItem.state == RecorderItem.State.HasErrors) { - EditorGUILayout.LabelField("The selected Recorder has errors."); + EditorGUILayout.LabelField("This Recorder has errors and cannot record any data."); } else { @@ -1060,18 +1058,18 @@ void ShowRecorderListMenu() { menu.AddItem(Styles.ClearRecorderListLabel, false, () => { - if (EditorUtility.DisplayDialog("Clear Recoder List?", "All recorder will be deleted. Proceed?", "Delete Recorders", "Cancel")) + Undo.IncrementCurrentGroup(); + Undo.SetCurrentGroupName("Clear Recorder List"); + var undoGroupIndex = Undo.GetCurrentGroup(); + foreach (var item in items) { - foreach (var item in items) - { - if (item.editor != null) - DestroyImmediate(item.editor); + if (item.editor != null) + DestroyImmediate(item.editor); - DeleteRecorder(item, false); - } - - ReloadRecordings(); + DeleteRecorder(item); } + Undo.CollapseUndoOperations(undoGroupIndex); + ReloadRecordings(); }); } else @@ -1130,20 +1128,12 @@ void DuplicateRecorder(RecorderItem item) AddLastAndSelect(copy, candidate.name, candidate.Enabled); } - void DeleteRecorder(RecorderItem item, bool prompt) + void DeleteRecorder(RecorderItem item) { - if (!prompt || EditorUtility.DisplayDialog("Delete Recoder?", - "Are you sure you want to delete '" + item.settings.name + "' ?", "Delete", "Cancel")) - { - var s = item.settings; - m_ControllerSettings.RemoveRecorder(s); - UnityHelpers.Destroy(s, true); - UnityHelpers.Destroy(item.editor, true); - m_RecordingListItem.Remove(item); - } - - if (prompt) - Focus(); + var s = item.settings; + m_ControllerSettings.RemoveRecorder(s); + UnityHelpers.Destroy(item.editor, true); + m_RecordingListItem.Remove(item); } void OnAddNewRecorder(RecorderInfo info) @@ -1181,7 +1171,7 @@ void OnRecordContextMenu(RecorderItem recorder) contextMenu.AddItem(Styles.DeleteLabel, false, data => { - DeleteRecorder((RecorderItem)data, true); + DeleteRecorder((RecorderItem)data); }, recorder); } diff --git a/Editor/Sources/Recorders/AOVRecorder/AOVRecorder.cs b/Editor/Sources/Recorders/AOVRecorder/AOVRecorder.cs index f263a49..b2863fd 100644 --- a/Editor/Sources/Recorders/AOVRecorder/AOVRecorder.cs +++ b/Editor/Sources/Recorders/AOVRecorder/AOVRecorder.cs @@ -34,7 +34,7 @@ protected internal override bool BeginRecording(RecordingSession session) if (settings.HasErrors()) { - Debug.LogError($"The '{settings.name}' AOV Recorder has errors and will not save data."); + Debug.LogError($"The '{settings.name}' AOV Recorder has errors and cannot record any data."); return false; } @@ -80,7 +80,7 @@ protected override void WriteFrame(Texture2D tex) { case ImageRecorderSettings.ImageRecorderOutputFormat.EXR: { - bytes = tex.EncodeToEXR(Settings.m_EXRCompression.ToNativeType()); + bytes = tex.EncodeToEXR(ImageRecorderSettings.ToNativeType(Settings.EXRCompression)); WriteToFile(bytes); break; } diff --git a/Editor/Sources/Recorders/AOVRecorder/AOVRecorderEditor.cs b/Editor/Sources/Recorders/AOVRecorder/AOVRecorderEditor.cs index 45eb32e..5d1cc95 100644 --- a/Editor/Sources/Recorders/AOVRecorder/AOVRecorderEditor.cs +++ b/Editor/Sources/Recorders/AOVRecorder/AOVRecorderEditor.cs @@ -18,7 +18,7 @@ static class Styles { internal static readonly GUIContent FormatLabel = new GUIContent("Format"); internal static readonly GUIContent AOVLabel = new GUIContent("Aov to Export", "The AOV render pass to record."); - internal static readonly GUIContent AOVCLabel = new GUIContent("Compression", "The data compression method to apply when using EXR format."); + internal static readonly GUIContent AOVCLabel = new GUIContent("Compression", "The data compression method to apply when using the EXR format."); internal static readonly GUIContent ColorSpace = new GUIContent("Color Space", "The color space (gamma curve, gamut) to use in the output images.\n\nIf you select an option to get unclamped values, you must:\n- Use High Definition Render Pipeline (HDRP).\n- Disable any Tonemapping in your Scene.\n- Disable Dithering on the selected Camera."); } @@ -43,20 +43,22 @@ protected override void FileTypeAndFormatGUI() if (imageSettings.CanCaptureHDRFrames()) { - ++EditorGUI.indentLevel; m_ColorSpace.intValue = EditorGUILayout.Popup(Styles.ColorSpace, m_ColorSpace.intValue, list_of_colorspaces); - --EditorGUI.indentLevel; } else { using (new EditorGUI.DisabledScope(!imageSettings.CanCaptureHDRFrames())) { - ++EditorGUI.indentLevel; EditorGUILayout.Popup(Styles.ColorSpace, 0, list_of_colorspaces); - --EditorGUI.indentLevel; } } + + if ((ImageRecorderSettings.ImageRecorderOutputFormat)m_OutputFormat.enumValueIndex == + ImageRecorderSettings.ImageRecorderOutputFormat.EXR) + { + EditorGUILayout.PropertyField(m_EXRCompression, Styles.AOVCLabel); + } } protected override void AOVGUI() @@ -76,7 +78,7 @@ protected override void AOVGUI() // HDRP_LIGHTDECO_API support has been removed from the project due to HDRP downgrading. var colorToRestore = EditorStyles.label.normal.textColor; EditorStyles.label.normal.textColor = Color.red; - EditorGUILayout.LabelField(Styles.AOVLabel.text, $"Value '{selectedAOV}' requires HDRP 8.9.9 or above."); + EditorGUILayout.LabelField(Styles.AOVLabel.text, $"You need HDRP 8.9.9 or above to record '{selectedAOV}'."); EditorStyles.label.normal.textColor = colorToRestore; } else @@ -86,9 +88,6 @@ protected override void AOVGUI() m_AOVSelection.intValue = (int)newSelectedAOV; } - if ((ImageRecorderSettings.ImageRecorderOutputFormat)m_OutputFormat.enumValueIndex == ImageRecorderSettings.ImageRecorderOutputFormat.EXR) - EditorGUILayout.PropertyField(m_EXRCompression, Styles.AOVCLabel); - DrawSeparator(); #else // Draw nothing, user will see errors (see AOVRecorderSettings.HasErrors) and an empty AOV GUI diff --git a/Editor/Sources/Recorders/AOVRecorder/AOVRecorderSettings.cs b/Editor/Sources/Recorders/AOVRecorder/AOVRecorderSettings.cs index c96ffaf..a97693e 100644 --- a/Editor/Sources/Recorders/AOVRecorder/AOVRecorderSettings.cs +++ b/Editor/Sources/Recorders/AOVRecorder/AOVRecorderSettings.cs @@ -85,40 +85,21 @@ public enum AOVType Depth = 17 } - public enum AOVColorSpaceType - { - sRGB_sRGB, - Unclamped_linear_sRGB - } - /// - /// Compression type for EXR files. + /// A class that represents the settings of an AOV Sequence Recorder. /// - public enum EXRCompressionType - { - /// - /// No compression. - /// - None, - /// - /// Run-length encoding compression. - /// - RLE, - /// - /// Zip compression. - /// - Zip - } - [RecorderSettings(typeof(AOVRecorder), "AOV Image Sequence", "aovimagesequence_16")] - internal class AOVRecorderSettings : RecorderSettings + public class AOVRecorderSettings : RecorderSettings { [SerializeField] internal ImageRecorderSettings.ImageRecorderOutputFormat m_OutputFormat = ImageRecorderSettings.ImageRecorderOutputFormat.EXR; [SerializeField] internal AOVType m_AOVSelection = AOVType.Beauty; - [SerializeField] internal EXRCompressionType m_EXRCompression = EXRCompressionType.Zip; + [SerializeField] internal ImageRecorderSettings.EXRCompressionType m_EXRCompression = ImageRecorderSettings.EXRCompressionType.Zip; [SerializeField] internal AOVImageInputSelector m_AOVImageInputSelector = new AOVImageInputSelector(); - [SerializeField] internal AOVColorSpaceType m_ColorSpace = AOVColorSpaceType.Unclamped_linear_sRGB; + [SerializeField] internal ImageRecorderSettings.ColorSpaceType m_ColorSpace = ImageRecorderSettings.ColorSpaceType.Unclamped_linear_sRGB; + /// + /// Default constructor. + /// public AOVRecorderSettings() { FileNameGenerator.FileName = "aov_image_" + DefaultWildcard.Frame; @@ -142,39 +123,72 @@ protected internal override string Extension } } + /// + /// Indicates the selected AOV to render. + /// + public AOVType AOVSelection + { + get => m_AOVSelection; + set => m_AOVSelection = value; + } + + /// + /// Stores the color space to use to encode the output image files. + /// + public ImageRecorderSettings.ColorSpaceType OutputColorSpace + { + get => m_ColorSpace; + set => m_ColorSpace = value; + } + + /// + /// Stores the data compression method to use to encode image files in the EXR format. + /// + public ImageRecorderSettings.EXRCompressionType EXRCompression + { + get => m_EXRCompression; + set => m_EXRCompression = value; + } + internal bool CanCaptureHDRFrames() { bool isFormatExr = m_OutputFormat == ImageRecorderSettings.ImageRecorderOutputFormat.EXR; return isFormatExr; } + /// + /// Stores the output image format currently used for this Recorder. + /// + public ImageRecorderSettings.ImageRecorderOutputFormat OutputFormat + { + get { return m_OutputFormat; } + set { m_OutputFormat = value; } + } + + /// + /// Use this property to capture the frames in HDR (if the setup supports it). + /// public bool CaptureHDR { - get => CanCaptureHDRFrames() && m_ColorSpace == AOVColorSpaceType.Unclamped_linear_sRGB; + get => CanCaptureHDRFrames() && m_ColorSpace == ImageRecorderSettings.ColorSpaceType.Unclamped_linear_sRGB; } + /// + /// The settings of the input image. + /// public ImageInputSettings imageInputSettings { get { return m_AOVImageInputSelector.imageInputSettings; } set { m_AOVImageInputSelector.imageInputSettings = value; } } - protected internal override bool ValidityCheck(List errors) + protected internal override void GetErrors(List errors) { - var ok = base.ValidityCheck(errors); - - if (string.IsNullOrEmpty(FileNameGenerator.FileName)) - { - ok = false; - errors.Add("missing file name"); - } + base.GetErrors(errors); #if !HDRP_AVAILABLE - ok = false; errors.Add("HDRP package not available"); #endif - - return ok; } #if HDRP_AVAILABLE @@ -200,6 +214,9 @@ protected internal override bool HasErrors() #endif } + /// + /// The list of settings of the Recorder Inputs. + /// public override IEnumerable InputsSettings { get { yield return m_AOVImageInputSelector.Selected; } diff --git a/Editor/Sources/Recorders/AOVRecorder/Formats.meta b/Editor/Sources/Recorders/AOVRecorder/Formats.meta deleted file mode 100644 index cdd683f..0000000 --- a/Editor/Sources/Recorders/AOVRecorder/Formats.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c278b233d6c0a3248af9df528dc2d162 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/AOVRecorder/Formats/Extensions.cs b/Editor/Sources/Recorders/AOVRecorder/Formats/Extensions.cs deleted file mode 100644 index deba01c..0000000 --- a/Editor/Sources/Recorders/AOVRecorder/Formats/Extensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.ComponentModel; -using UnityEditor.Recorder.AOV; -using UnityEngine; - -namespace UnityEditor.Recorder -{ - static class EXRCompressionTypeExtensions - { - internal static Texture2D.EXRFlags ToNativeType(this EXRCompressionType type) - { - Texture2D.EXRFlags nativeType = Texture2D.EXRFlags.None; - switch (type) - { - case EXRCompressionType.RLE: - nativeType = Texture2D.EXRFlags.CompressRLE; - break; - case EXRCompressionType.Zip: - nativeType = Texture2D.EXRFlags.CompressZIP; - break; - case EXRCompressionType.None: - nativeType = Texture2D.EXRFlags.None; - break; - default: - throw new InvalidEnumArgumentException($"Unexpected compression type '{type}'."); - } - return nativeType; - } - } -} diff --git a/Editor/Sources/Recorders/AOVRecorder/Formats/Extensions.cs.meta b/Editor/Sources/Recorders/AOVRecorder/Formats/Extensions.cs.meta deleted file mode 100644 index 376d5a0..0000000 --- a/Editor/Sources/Recorders/AOVRecorder/Formats/Extensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9eda8fef5db92d345a1ca9e9791f22e0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorder.cs b/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorder.cs index 4b7966d..3270938 100644 --- a/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorder.cs +++ b/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorder.cs @@ -1,3 +1,5 @@ +using System; +using System.Collections.Generic; using UnityEditor.Animations; using UnityEditor.Recorder.Input; using UnityEngine; @@ -10,33 +12,53 @@ protected internal override void RecordFrame(RecordingSession session) { } - protected internal override void EndRecording(RecordingSession session) + protected internal override bool BeginRecording(RecordingSession session) { - var ars = (AnimationRecorderSettings)session.settings; + if (!base.BeginRecording(session)) + return false; foreach (var input in m_Inputs) { var aInput = (AnimationInput)input; - if (aInput.GameObjectRecorder == null) - continue; + { + Recording = false; + return false; + } + } + + return true; + } + + protected internal override void EndRecording(RecordingSession session) + { + if (Recording) // no need to do this if recording was not successful + { + var ars = (AnimationRecorderSettings)session.settings; + foreach (var input in m_Inputs) + { + var aInput = (AnimationInput)input; - var clip = new AnimationClip(); + if (aInput.GameObjectRecorder == null) + continue; - ars.fileNameGenerator.CreateDirectory(session); + var clip = new AnimationClip(); - var absolutePath = FileNameGenerator.SanitizePath(ars.fileNameGenerator.BuildAbsolutePath(session)); - var clipName = absolutePath.Replace(FileNameGenerator.SanitizePath(Application.dataPath), "Assets"); + ars.fileNameGenerator.CreateDirectory(session); - AssetDatabase.CreateAsset(clip, clipName); - var aniSettings = (aInput.settings as AnimationInputSettings); - aInput.GameObjectRecorder.SaveToClip(clip, ars.FrameRate, aniSettings.CurveFilterOptions); - if (aniSettings.ClampedTangents) - { - FilterClip(clip); - } + var absolutePath = FileNameGenerator.SanitizePath(ars.fileNameGenerator.BuildAbsolutePath(session)); + var clipName = absolutePath.Replace(FileNameGenerator.SanitizePath(Application.dataPath), "Assets"); - aInput.GameObjectRecorder.ResetRecording(); + AssetDatabase.CreateAsset(clip, clipName); + var aniSettings = (aInput.settings as AnimationInputSettings); + aInput.GameObjectRecorder.SaveToClip(clip, ars.FrameRate, aniSettings.CurveFilterOptions); + if (aniSettings.ClampedTangents) + { + FilterClip(clip); + } + + aInput.GameObjectRecorder.ResetRecording(); + } } base.EndRecording(session); diff --git a/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorderSettings.cs b/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorderSettings.cs index ee19289..b75c416 100644 --- a/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorderSettings.cs +++ b/Editor/Sources/Recorders/AnimationRecorder/AnimationRecorderSettings.cs @@ -78,17 +78,14 @@ protected internal override string Extension } /// - protected internal override bool ValidityCheck(List errors) + protected internal override void GetErrors(List errors) { - var ok = base.ValidityCheck(errors); + base.GetErrors(errors); if (m_AnimationInputSettings.gameObject == null) - { - ok = false; - errors.Add("No input object set"); - } - - return ok; + errors.Add("No assigned game object to record"); + else if (m_AnimationInputSettings.bindingType.Count == 0) + errors.Add($"No components to record"); } /// diff --git a/Editor/Sources/Recorders/AudioRecorder/AudioRecorder.cs b/Editor/Sources/Recorders/AudioRecorder/AudioRecorder.cs index f42119e..d8a531d 100644 --- a/Editor/Sources/Recorders/AudioRecorder/AudioRecorder.cs +++ b/Editor/Sources/Recorders/AudioRecorder/AudioRecorder.cs @@ -23,7 +23,8 @@ protected internal override bool BeginRecording(RecordingSession session) } catch (Exception) { - Debug.LogError(string.Format("Audio recorder output directory \"{0}\" could not be created.", Settings.fileNameGenerator.BuildAbsolutePath(session))); + ConsoleLogMessage($"Unable to create the output directory \"{Settings.fileNameGenerator.BuildAbsolutePath(session)}\".", LogType.Error); + Recording = false; return false; } @@ -46,7 +47,7 @@ protected internal override bool BeginRecording(RecordingSession session) audioAttrsList.Add(audioAttrs); if (RecorderOptions.VerboseMode) - Debug.Log(string.Format("Audio starting to write audio {0}ch @ {1}Hz", audioAttrs.channelCount, audioAttrs.sampleRate.numerator)); + ConsoleLogMessage($"Audio starting to write audio {audioAttrs.channelCount}ch @ {audioAttrs.sampleRate.numerator}Hz", LogType.Log); } try @@ -56,10 +57,10 @@ protected internal override bool BeginRecording(RecordingSession session) return true; } - catch + catch (Exception ex) { if (RecorderOptions.VerboseMode) - Debug.LogError("AudioRecorder unable to create MovieEncoder."); + ConsoleLogMessage($"Unable to create encoder: '{ex.Message}'", LogType.Error); } return false; diff --git a/Editor/Sources/Recorders/GIFRecorder/GIFRecorder.cs b/Editor/Sources/Recorders/GIFRecorder/GIFRecorder.cs index 3293b90..061ceb9 100644 --- a/Editor/Sources/Recorders/GIFRecorder/GIFRecorder.cs +++ b/Editor/Sources/Recorders/GIFRecorder/GIFRecorder.cs @@ -4,62 +4,12 @@ namespace UnityEditor.Recorder { +#pragma warning disable 618 class GIFRecorder : GenericRecorder { - fcAPI.fcGifContext m_ctx; - fcAPI.fcStream m_stream; - - protected internal override bool BeginRecording(RecordingSession session) - { - if (!base.BeginRecording(session)) { return false; } - - Settings.fileNameGenerator.CreateDirectory(session); - - return true; - } - - protected internal override void EndRecording(RecordingSession session) - { - // Case REC-98 crash gif animation when start/stop recording in playmode - // If you start recording while in playmode pause the RecordFrame - // will never be called and m_ctx and m_stream will de-reference null - // pointers that will crash unity. - if (m_ctx) - { - m_ctx.Release(); - } - - if (m_stream) - { - m_stream.Release(); - } - - base.EndRecording(session); - } - +#pragma warning restore 618 protected internal override void RecordFrame(RecordingSession session) { - if (m_Inputs.Count != 1) - throw new Exception("Unsupported number of sources"); - - var input = (BaseRenderTextureInput)m_Inputs[0]; - var frame = input.OutputRenderTexture; - - if (!m_ctx) - { - var gifSettings = Settings.gifEncoderSettings; - gifSettings.width = frame.width; - gifSettings.height = frame.height; - m_ctx = fcAPI.fcGifCreateContext(ref gifSettings); - var path = Settings.fileNameGenerator.BuildAbsolutePath(session); - m_stream = fcAPI.fcCreateFileStream(path); - fcAPI.fcGifAddOutputStream(m_ctx, m_stream); - } - - fcAPI.fcLock(frame, TextureFormat.RGB24, (data, fmt) => - { - fcAPI.fcGifAddFramePixels(m_ctx, data, fmt, session.recorderTime); - }); } } } diff --git a/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettings.cs b/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettings.cs index a926114..c8a6927 100644 --- a/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettings.cs +++ b/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettings.cs @@ -1,54 +1,22 @@ +using System; using UnityEditor.Recorder.FrameCapturer; using UnityEngine; namespace UnityEditor.Recorder { /// - /// A class that represents the settings of a GIF Recorder. + /// Deprecated GIF Recorder. /// - [RecorderSettings(typeof(GIFRecorder), "GIF Animation", "imagesequence_16")] + [Obsolete("The GIFRecorder is deprecated")] + [RecorderSettings(typeof(GIFRecorder), "GIF Animation", "imagesequence_16", true)] public class GIFRecorderSettings : BaseFCRecorderSettings { - [SerializeField] internal fcAPI.fcGifConfig gifEncoderSettings = fcAPI.fcGifConfig.default_value; - - /// - /// The number of colors used in the GIF palette for the output. Maximum is 256. - /// - public int NumColors - { - get { return gifEncoderSettings.numColors; } - set { gifEncoderSettings.numColors = Mathf.Clamp(value, 1, 256); } - } - - /// - /// The frame interval between keyframes (value between 1 and 120). This defines how many frames share the same color palette. - /// - public int KeyframeInterval - { - get { return gifEncoderSettings.keyframeInterval; } - set { gifEncoderSettings.keyframeInterval = Mathf.Clamp(value, 1, 120); } - } - - - /// - /// The maximum number of threads to use to encode output frames (value between 1 and 32). - /// - public int MaxTasks - { - get { return gifEncoderSettings.maxTasks; } - set { gifEncoderSettings.maxTasks = Mathf.Clamp(value, 1, 32); } - } - /// /// Default constructor. /// + [Obsolete("The GIFRecorder is deprecated")] public GIFRecorderSettings() { - fileNameGenerator.FileName = "gif_animation_" + DefaultWildcard.Take; - - m_ImageInputSelector.cameraInputSettings.FlipFinalOutput = true; - m_ImageInputSelector.renderTextureInputSettings.FlipFinalOutput = true; - m_ImageInputSelector.renderTextureSamplerSettings.FlipFinalOutput = true; } /// diff --git a/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettingsEditor.cs b/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettingsEditor.cs index 8eabdce..9c94ad0 100644 --- a/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettingsEditor.cs +++ b/Editor/Sources/Recorders/GIFRecorder/GIFRecorderSettingsEditor.cs @@ -2,12 +2,14 @@ namespace UnityEditor.Recorder { +#pragma warning disable 618 [CustomEditor(typeof(GIFRecorderSettings))] +#pragma warning restore 618 class GIFRecorderSettingsEditor : RecorderEditor { - protected override void OnEncodingGui() + public override void OnInspectorGUI() { - EditorGUILayout.PropertyField(serializedObject.FindProperty("gifEncoderSettings"), new GUIContent("Encoding"), true); + EditorGUILayout.LabelField("The selected GIF Animation recorder has been deprecated."); } } } diff --git a/Editor/Sources/Recorders/ImageRecorder/ImageRecorder.cs b/Editor/Sources/Recorders/ImageRecorder/ImageRecorder.cs index d22d10b..a4073da 100644 --- a/Editor/Sources/Recorders/ImageRecorder/ImageRecorder.cs +++ b/Editor/Sources/Recorders/ImageRecorder/ImageRecorder.cs @@ -22,7 +22,8 @@ protected override TextureFormat ReadbackTextureFormat protected internal override bool BeginRecording(RecordingSession session) { - if (!base.BeginRecording(session)) { return false; } + if (!base.BeginRecording(session)) + return false; Settings.fileNameGenerator.CreateDirectory(session); @@ -55,7 +56,7 @@ protected override void WriteFrame(Texture2D tex) bytes = tex.EncodeToJPG(); break; case ImageRecorderSettings.ImageRecorderOutputFormat.EXR: - bytes = tex.EncodeToEXR(); + bytes = tex.EncodeToEXR(ImageRecorderSettings.ToNativeType(Settings.EXRCompression)); break; default: Profiler.EndSample(); diff --git a/Editor/Sources/Recorders/ImageRecorder/ImageRecorderEditor.cs b/Editor/Sources/Recorders/ImageRecorder/ImageRecorderEditor.cs index dfd91b7..def313a 100644 --- a/Editor/Sources/Recorders/ImageRecorder/ImageRecorderEditor.cs +++ b/Editor/Sources/Recorders/ImageRecorder/ImageRecorderEditor.cs @@ -9,11 +9,13 @@ class ImageRecorderEditor : RecorderEditor SerializedProperty m_OutputFormat; SerializedProperty m_CaptureAlpha; SerializedProperty m_ColorSpace; + SerializedProperty m_EXRCompression; static class Styles { internal static readonly GUIContent FormatLabel = new GUIContent("Media File Format", "The file encoding format of the recorded output."); - internal static readonly GUIContent CaptureAlphaLabel = new GUIContent("Include Alpha", "To Include the alpha channel in the recording."); + internal static readonly GUIContent CaptureAlphaLabel = new GUIContent("Include Alpha", "To include the alpha channel in the recording.\n\nIn the High Definition Render Pipeline (HDRP), you need to set the buffer format to R16G16B16A16."); + internal static readonly GUIContent CLabel = new GUIContent("Compression", "The data compression method to apply when using the EXR format."); internal static readonly GUIContent ColorSpace = new GUIContent("Color Space", "The color space (gamma curve, gamut) to use in the output images.\n\nIf you select an option to get unclamped values, you must:\n- Use High Definition Render Pipeline (HDRP).\n- Disable any Tonemapping in your Scene.\n- Disable Dithering on the selected Camera."); } @@ -26,6 +28,7 @@ protected override void OnEnable() m_OutputFormat = serializedObject.FindProperty("outputFormat"); m_CaptureAlpha = serializedObject.FindProperty("captureAlpha"); + m_EXRCompression = serializedObject.FindProperty("m_EXRCompression"); m_ColorSpace = serializedObject.FindProperty("m_ColorSpace"); } @@ -33,7 +36,7 @@ protected override void FileTypeAndFormatGUI() { EditorGUILayout.PropertyField(m_OutputFormat, Styles.FormatLabel); var imageSettings = (ImageRecorderSettings)target; - if (!UnityHelpers.UsingHDRP()) + if (!UnityHelpers.UsingURP()) { using (new EditorGUI.DisabledScope(!imageSettings.CanCaptureAlpha())) { @@ -50,10 +53,15 @@ protected override void FileTypeAndFormatGUI() } else { + // Disable the dropdown but show sRGB using (new EditorGUI.DisabledScope(!imageSettings.CanCaptureHDRFrames())) - { EditorGUILayout.Popup(Styles.ColorSpace, 0, list_of_colorspaces); - } + } + + if ((ImageRecorderSettings.ImageRecorderOutputFormat)m_OutputFormat.enumValueIndex == + ImageRecorderSettings.ImageRecorderOutputFormat.EXR) + { + EditorGUILayout.PropertyField(m_EXRCompression, Styles.CLabel); } } } diff --git a/Editor/Sources/Recorders/ImageRecorder/ImageRecorderSettings.cs b/Editor/Sources/Recorders/ImageRecorder/ImageRecorderSettings.cs index c97161d..daa01ac 100644 --- a/Editor/Sources/Recorders/ImageRecorder/ImageRecorderSettings.cs +++ b/Editor/Sources/Recorders/ImageRecorder/ImageRecorderSettings.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using UnityEditor.Recorder.Input; using UnityEngine; -using UnityEngine.Rendering; -using UnityEngine.Serialization; namespace UnityEditor.Recorder { @@ -31,9 +30,59 @@ public enum ImageRecorderOutputFormat /// EXR } - internal enum ColorSpaceType + + /// + /// Compression type for EXR files. + /// + public enum EXRCompressionType + { + /// + /// No compression. + /// + None, + /// + /// Run-length encoding compression. + /// + RLE, + /// + /// Zip compression. + /// + Zip + } + + static internal Texture2D.EXRFlags ToNativeType(EXRCompressionType type) { + Texture2D.EXRFlags nativeType = Texture2D.EXRFlags.None; + switch (type) + { + case ImageRecorderSettings.EXRCompressionType.RLE: + nativeType = Texture2D.EXRFlags.CompressRLE; + break; + case ImageRecorderSettings.EXRCompressionType.Zip: + nativeType = Texture2D.EXRFlags.CompressZIP; + break; + case ImageRecorderSettings.EXRCompressionType.None: + nativeType = Texture2D.EXRFlags.None; + break; + default: + throw new InvalidEnumArgumentException($"Unexpected compression type '{type}'."); + } + + return nativeType; + } + + /// + /// Color Space (gamma curve, gamut) to use in the output images. + /// + public enum ColorSpaceType + { + /// + /// The sRGB color space. + /// sRGB_sRGB, + /// + /// The linear sRGB color space. + /// Unclamped_linear_sRGB } @@ -68,11 +117,12 @@ public bool CaptureAlpha /// public bool CaptureHDR { - get { return CanCaptureHDRFrames() && m_ColorSpace == ColorSpaceType.Unclamped_linear_sRGB;; } + get { return CanCaptureHDRFrames() && m_ColorSpace == ColorSpaceType.Unclamped_linear_sRGB; } } [SerializeField] ImageInputSelector m_ImageInputSelector = new ImageInputSelector(); + [SerializeField] internal ImageRecorderSettings.EXRCompressionType m_EXRCompression = ImageRecorderSettings.EXRCompressionType.Zip; [SerializeField] internal ColorSpaceType m_ColorSpace = ColorSpaceType.Unclamped_linear_sRGB; /// /// Default constructor. @@ -101,6 +151,24 @@ protected internal override string Extension } } + /// + /// Stores the data compression method to use to encode image files in the EXR format. + /// + public EXRCompressionType EXRCompression + { + get => m_EXRCompression; + set => m_EXRCompression = value; + } + + /// + /// Stores the color space to use to encode the output image files. + /// + public ColorSpaceType OutputColorSpace + { + get => m_ColorSpace; + set => m_ColorSpace = value; + } + /// /// The settings of the input image. /// @@ -110,12 +178,6 @@ public ImageInputSettings imageInputSettings set { m_ImageInputSelector.ImageInputSettings = value; } } - protected internal override bool ValidityCheck(List errors) - { - var ok = base.ValidityCheck(errors); - return ok; - } - /// /// The list of settings of the Recorder Inputs. /// @@ -136,7 +198,7 @@ internal bool CanCaptureAlpha() bool formatSupportAlpha = OutputFormat == ImageRecorderOutputFormat.PNG || OutputFormat == ImageRecorderOutputFormat.EXR; bool inputSupportAlpha = imageInputSettings.SupportsTransparent; - return (formatSupportAlpha && inputSupportAlpha && !UnityHelpers.UsingHDRP()); + return (formatSupportAlpha && inputSupportAlpha && !UnityHelpers.UsingURP()); } internal override void SelfAdjustSettings() @@ -183,9 +245,7 @@ public AccumulationSettings GetAccumulationSettings() return AccumulationSettings; } - /// - /// Indicates if the current Recorder supports Accumulation recording (True) or not (False). - /// + /// public override bool IsAccumulationSupported() { if (GetAccumulationSettings() != null) @@ -199,5 +259,28 @@ public override bool IsAccumulationSupported() } return false; } + + internal override bool NeedToConvertFromLinearToSRGB() + { + // We need to convert from linear to sRGB for image recorders only if the project settings say linear and the + // output is expected to be sRGB + var expectSRGB = false; + switch (OutputFormat) + { + case ImageRecorderOutputFormat.EXR: + expectSRGB = m_ColorSpace == ColorSpaceType.sRGB_sRGB; + break; + case ImageRecorderOutputFormat.PNG: + case ImageRecorderOutputFormat.JPEG: + expectSRGB = true; // PNG & JPEG must always be sRGB + break; + default: + throw new InvalidEnumArgumentException( + $"Unexpected image output format '{OutputFormat}'"); + } + + var convertLinearToSrgb = PlayerSettings.colorSpace == ColorSpace.Linear && expectSRGB; + return convertLinearToSrgb; + } } } diff --git a/Editor/Sources/Recorders/MovieRecorder/MovieRecorder.cs b/Editor/Sources/Recorders/MovieRecorder/MovieRecorder.cs index 458d1f4..0b1dde2 100644 --- a/Editor/Sources/Recorders/MovieRecorder/MovieRecorder.cs +++ b/Editor/Sources/Recorders/MovieRecorder/MovieRecorder.cs @@ -46,39 +46,29 @@ protected internal override bool BeginRecording(RecordingSession session) } catch (Exception) { - Debug.LogError(string.Format("Movie recorder output directory \"{0}\" could not be created.", Settings.fileNameGenerator.BuildAbsolutePath(session))); + ConsoleLogMessage($"Unable to create the output directory \"{Settings.fileNameGenerator.BuildAbsolutePath(session)}\".", LogType.Error); + Recording = false; return false; } var input = m_Inputs[0] as BaseRenderTextureInput; if (input == null) { - Debug.LogError("MediaRecorder could not find input."); + ConsoleLogMessage("Movie Recorder could not find its input.", LogType.Error); + Recording = false; return false; } int width = input.OutputWidth; int height = input.OutputHeight; - if (width <= 0 || height <= 0) - { - Debug.LogError(string.Format("MovieRecorder got invalid input resolution {0} x {1}.", width, height)); - return false; - } - var currentEncoderReg = Settings.GetCurrentEncoder(); - string erroMessage; - if (!currentEncoderReg.SupportsResolution(Settings, width, height, out erroMessage)) - { - Debug.LogError(erroMessage); - return false; - } - + string errorMessage; var imageInputSettings = m_Inputs[0].settings as ImageInputSettings; - var alphaWillBeInImage = imageInputSettings != null && imageInputSettings.SupportsTransparent && imageInputSettings.RecordTransparency; - if (alphaWillBeInImage && !currentEncoderReg.SupportsTransparency(Settings, out erroMessage)) + if (alphaWillBeInImage && !currentEncoderReg.SupportsTransparency(Settings, out errorMessage)) { - Debug.LogError(erroMessage); + ConsoleLogMessage(errorMessage, LogType.Error); + Recording = false; return false; } @@ -92,11 +82,9 @@ protected internal override bool BeginRecording(RecordingSession session) }; if (RecorderOptions.VerboseMode) - Debug.Log( - string.Format( - "MovieRecorder starting to write video {0}x{1}@[{2}/{3}] fps into {4}", - width, height, videoAttrs.frameRate.numerator, - videoAttrs.frameRate.denominator, Settings.fileNameGenerator.BuildAbsolutePath(session))); + ConsoleLogMessage( + $"MovieRecorder starting to write video {width}x{height}@[{videoAttrs.frameRate.numerator}/{videoAttrs.frameRate.denominator}] fps into {Settings.fileNameGenerator.BuildAbsolutePath(session)}", + LogType.Log); var audioInput = (AudioInput)m_Inputs[1]; var audioAttrsList = new List(); @@ -126,12 +114,12 @@ protected internal override bool BeginRecording(RecordingSession session) audioAttrsList.Add(audioAttrs); if (RecorderOptions.VerboseMode) - Debug.Log(string.Format("MovieRecorder starting to write audio {0}ch @ {1}Hz", audioAttrs.channelCount, audioAttrs.sampleRate.numerator)); + ConsoleLogMessage($"Starting to write audio {audioAttrs.channelCount}ch @ {audioAttrs.sampleRate.numerator}Hz", LogType.Log); } else { if (RecorderOptions.VerboseMode) - Debug.Log("MovieRecorder starting with no audio."); + ConsoleLogMessage("Starting with no audio.", LogType.Log); } try @@ -176,7 +164,8 @@ protected internal override bool BeginRecording(RecordingSession session) } catch (Exception ex) { - Debug.LogError("MovieRecorder unable to create MovieEncoder. " + ex.Message); + ConsoleLogMessage($"Unable to create encoder: '{ex.Message}'", LogType.Error); + Recording = false; return false; } } @@ -186,6 +175,9 @@ protected internal override void RecordFrame(RecordingSession session) if (m_Inputs.Count != 2) throw new Exception("Unsupported number of sources"); + if (!m_RecordingStartedProperly) + return; // error will have been triggered in BeginRecording() + base.RecordFrame(session); var audioInput = (AudioInput)m_Inputs[1]; if (audioInput.audioSettings.PreserveAudio && !UnityHelpers.CaptureAccumulation(settings)) @@ -199,7 +191,7 @@ protected internal override void EndRecording(RecordingSession session) { s_ConcurrentCount--; if (s_ConcurrentCount < 0) - Debug.LogError($"Recording ended with no matching beginning recording."); + ConsoleLogMessage($"Recording ended with no matching beginning recording.", LogType.Error); if (s_ConcurrentCount <= 1 && s_WarnedUserOfConcurrentCount) s_WarnedUserOfConcurrentCount = false; // reset so that we can warn at the next occurence m_RecordingAlreadyEnded = true; @@ -213,7 +205,7 @@ private void WarnOfConcurrentRecorders() { if (s_ConcurrentCount > 1 && !s_WarnedUserOfConcurrentCount) { - Debug.LogWarning($"There are two or more concurrent Movie Recorders. You may experience slowdowns and other issues, since this is not recommended."); + ConsoleLogMessage($"There are two or more concurrent Movie Recorders in your project. You should keep only one of them active per recording to avoid experiencing slowdowns or other issues.", LogType.Warning); s_WarnedUserOfConcurrentCount = true; } } @@ -227,6 +219,15 @@ protected override void WriteFrame(Texture2D t) protected override void WriteFrame(AsyncGPUReadbackRequest r) { var format = Settings.GetCurrentEncoder().GetTextureFormat(Settings); + if (r.hasError) + { + var rtInput = Settings.ImageInputSettings as RenderTextureInputSettings; + if (rtInput != null) + ConsoleLogMessage("The rendered image has errors. Verify that the Render Texture correctly receives data.", LogType.Error); + else + ConsoleLogMessage("The rendered image has errors.", LogType.Error); + return; + } Settings.m_EncoderManager.AddFrame(m_EncoderHandle, r.width, r.height, 0, format, r.GetData()); WarnOfConcurrentRecorders(); } diff --git a/Editor/Sources/Recorders/MovieRecorder/MovieRecorderSettings.cs b/Editor/Sources/Recorders/MovieRecorder/MovieRecorderSettings.cs index 0894dc5..69de54d 100644 --- a/Editor/Sources/Recorders/MovieRecorder/MovieRecorderSettings.cs +++ b/Editor/Sources/Recorders/MovieRecorder/MovieRecorderSettings.cs @@ -33,7 +33,7 @@ internal static string FormatToName(this MovieRecorderSettings.VideoRecorderOutp case MovieRecorderSettings.VideoRecorderOutputFormat.MP4: return "H.264 MP4"; case MovieRecorderSettings.VideoRecorderOutputFormat.WebM: - return "VP9 WebM"; + return "VP8 WebM"; case MovieRecorderSettings.VideoRecorderOutputFormat.MOV: return "ProRes QuickTime"; default: @@ -216,9 +216,7 @@ public AccumulationSettings GetAccumulationSettings() return AccumulationSettings; } - /// - /// Indicates whether the current Recorder supports Accumulation recording or not. - /// + /// public override bool IsAccumulationSupported() { if (GetAccumulationSettings() != null) @@ -338,30 +336,35 @@ protected internal override string Extension } } - /// - protected internal override bool ValidityCheck(List errors) + protected internal override void GetWarnings(List warnings) { - var ok = base.ValidityCheck(errors); + base.GetWarnings(warnings); - if (FrameRatePlayback == FrameRatePlayback.Variable) + var iis = m_ImageInputSelector.Selected as ImageInputSettings; + if (iis != null) { - errors.Add("Movie recorder does not properly support Variable frame rate playback. Please consider using Constant frame rate instead"); - ok = false; + string errorMsg, warningMsg; + encodersRegistered[encoderSelected].SupportsResolution(this, iis.OutputWidth, iis.OutputHeight, + out errorMsg, out warningMsg); + if (warningMsg != String.Empty) + warnings.Add(warningMsg); } + } + + protected internal override void GetErrors(List errors) + { + base.GetErrors(errors); + + if (FrameRatePlayback == FrameRatePlayback.Variable) + errors.Add("Movie Recorder does not properly support variable frame rate playback. Consider using Constant frame rate instead."); var iis = m_ImageInputSelector.Selected as ImageInputSettings; if (iis != null) { - string errorMsg; - if (!encodersRegistered[encoderSelected] - .SupportsResolution(this, iis.OutputWidth, iis.OutputHeight, out errorMsg)) - { + string errorMsg, warningMsg; + if (!encodersRegistered[encoderSelected].SupportsResolution(this, iis.OutputWidth, iis.OutputHeight, out errorMsg, out warningMsg)) errors.Add(errorMsg); - ok = false; - } } - - return ok; } internal override void SelfAdjustSettings() diff --git a/Editor/Sources/Recorders/_Inputs/AOV/AOVCameraInput.cs b/Editor/Sources/Recorders/_Inputs/AOV/AOVCameraInput.cs index 48f3fb2..b45452b 100644 --- a/Editor/Sources/Recorders/_Inputs/AOV/AOVCameraInput.cs +++ b/Editor/Sources/Recorders/_Inputs/AOV/AOVCameraInput.cs @@ -298,6 +298,15 @@ protected internal override void FrameDone(RecordingSession session) base.FrameDone(session); DisableAOVCapture(session); } + + protected internal override void EndRecording(RecordingSession session) + { + base.EndRecording(session); + if (m_ColorRT != null) + UnityHelpers.Destroy(m_ColorRT); + if (m_TempRT != null) + UnityHelpers.Destroy(m_TempRT); + } } } #else // HDRP_AVAILABLE diff --git a/Editor/Sources/Recorders/_Inputs/Animation/AnimationInput.cs b/Editor/Sources/Recorders/_Inputs/Animation/AnimationInput.cs index 517dc25..b07a43f 100644 --- a/Editor/Sources/Recorders/_Inputs/Animation/AnimationInput.cs +++ b/Editor/Sources/Recorders/_Inputs/Animation/AnimationInput.cs @@ -1,4 +1,5 @@ using UnityEditor.Animations; +using UnityEngine; namespace UnityEditor.Recorder.Input { @@ -21,7 +22,7 @@ protected internal override void BeginRecording(RecordingSession session) var srcGO = aniSettings.gameObject; if (srcGO == null) - throw new System.NullReferenceException("srcGO"); + return; // error message will be posted by AnimationRecorderSettings.GetErrors GameObjectRecorder = new GameObjectRecorder(srcGO); diff --git a/Editor/Sources/Recorders/_Inputs/Animation/AnimationInputSettings.cs b/Editor/Sources/Recorders/_Inputs/Animation/AnimationInputSettings.cs index 7d4bad4..2fcd51a 100644 --- a/Editor/Sources/Recorders/_Inputs/Animation/AnimationInputSettings.cs +++ b/Editor/Sources/Recorders/_Inputs/Animation/AnimationInputSettings.cs @@ -163,19 +163,12 @@ protected internal override Type InputType get { return typeof(AnimationInput); } } - /// - protected internal override bool ValidityCheck(List errors) + protected internal override void CheckForErrors(List errors) { - var ok = true; + base.CheckForErrors(errors); - if (bindingType.Count > 0 && bindingType.Any(x => typeof(ScriptableObject).IsAssignableFrom(x)) - ) - { - ok = false; + if (bindingType.Count > 0 && bindingType.Any(x => typeof(ScriptableObject).IsAssignableFrom(x))) errors.Add("ScriptableObjects are not supported inputs."); - } - - return ok; } static string GenerateBindingId() diff --git a/Editor/Sources/Recorders/_Inputs/Audio/AudioInputSettings.cs b/Editor/Sources/Recorders/_Inputs/Audio/AudioInputSettings.cs index 8751aed..11a72e1 100644 --- a/Editor/Sources/Recorders/_Inputs/Audio/AudioInputSettings.cs +++ b/Editor/Sources/Recorders/_Inputs/Audio/AudioInputSettings.cs @@ -27,11 +27,5 @@ protected internal override Type InputType { get { return typeof(AudioInput); } } - - /// - protected internal override bool ValidityCheck(List errors) - { - return true; - } } } diff --git a/Editor/Sources/Recorders/_Inputs/Camera/CameraInput.cs b/Editor/Sources/Recorders/_Inputs/Camera/CameraInput.cs index a52ab80..269a530 100644 --- a/Editor/Sources/Recorders/_Inputs/Camera/CameraInput.cs +++ b/Editor/Sources/Recorders/_Inputs/Camera/CameraInput.cs @@ -293,24 +293,22 @@ protected internal override void NewFrameStarting(RecordingSession session) { var tag = ((CameraInputSettings)settings).CameraTag; - if (TargetCamera == null || !TargetCamera.gameObject.CompareTag(tag)) + try { - try - { - var objs = GameObject.FindGameObjectsWithTag(tag); + var objs = GameObject.FindGameObjectsWithTag(tag); - var cams = objs.Select(obj => obj.GetComponent()).Where(c => c != null); - if (cams.Count() > 1) - Debug.LogWarning("More than one camera has the requested target tag '" + tag + "'"); + var cams = objs.Select(obj => obj.GetComponent()).Where(c => c != null); + if (cams.Count() > 1) + Debug.LogWarning("More than one camera has the requested target tag '" + tag + "'"); - TargetCamera = cams.FirstOrDefault(); - } - catch (UnityException) - { - Debug.LogWarning("No camera has the requested target tag '" + tag + "'"); - TargetCamera = null; - } + TargetCamera = cams.FirstOrDefault(); } + catch (UnityException) + { + Debug.LogWarning("No camera has the requested target tag '" + tag + "'"); + TargetCamera = null; + } + break; } } @@ -428,8 +426,6 @@ void PrepFrameRenderTexture(RecordingSession session) OutputRenderTexture.Create(); if (m_UICamera != null) m_UICamera.targetTexture = OutputRenderTexture; - - return; } } } diff --git a/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettings.cs b/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettings.cs index 2c08ce0..b2e5384 100644 --- a/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettings.cs +++ b/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettings.cs @@ -70,16 +70,11 @@ protected internal override Type InputType } /// - protected internal override bool ValidityCheck(List errors) + protected internal override void CheckForErrors(List errors) { - var ok = base.ValidityCheck(errors); + base.CheckForErrors(errors); if (Source == ImageSource.TaggedCamera && string.IsNullOrEmpty(CameraTag)) - { - ok = false; errors.Add("Missing tag for camera selection"); - } - - return ok; } } } diff --git a/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettingsPropertyDrawer.cs b/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettingsPropertyDrawer.cs index 59c7098..6f76032 100644 --- a/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettingsPropertyDrawer.cs +++ b/Editor/Sources/Recorders/_Inputs/Camera/CameraInputSettingsPropertyDrawer.cs @@ -14,7 +14,6 @@ class CameraInputSettingsPropertyDrawer : InputPropertyDrawer errors) + protected internal override void CheckForErrors(List errors) { - var ok = true; + base.CheckForErrors(errors); if (source == ImageSource.TaggedCamera && string.IsNullOrEmpty(cameraTag)) - { - ok = false; errors.Add("Missing camera tag"); - } if (m_OutputWidth != (1 << (int)Math.Log(m_OutputWidth, 2))) - { - ok = false; errors.Add("Output width must be a power of 2."); - } if (m_OutputWidth < 128 || m_OutputWidth > 8 * 1024) - { - ok = false; - errors.Add(string.Format("Output width must fall between {0} and {1}.", 128, 8 * 1024)); - } + errors.Add($"Output width must fall between {128} and {8 * 1024}."); if (m_OutputHeight != (1 << (int)Math.Log(m_OutputHeight, 2))) - { - ok = false; errors.Add("Output height must be a power of 2."); - } if (m_OutputHeight < 128 || m_OutputHeight > 8 * 1024) - { - ok = false; - errors.Add(string.Format("Output height must fall between {0} and {1}.", 128, 8 * 1024)); - } + errors.Add($"Output height must fall between {128} and {8 * 1024}."); if (mapSize != (1 << (int)Math.Log(mapSize, 2))) - { - ok = false; errors.Add("Cube Map size must be a power of 2."); - } if (mapSize < 16 || mapSize > 8 * 1024) - { - ok = false; errors.Add(string.Format("Cube Map size must fall between {0} and {1}.", 16, 8 * 1024)); - } if (renderStereo && stereoSeparation < float.Epsilon) - { - ok = false; errors.Add("Stereo separation value is too small."); - } - - return ok; } } } diff --git a/Editor/Sources/Recorders/_Inputs/GameView/GameViewInput.cs b/Editor/Sources/Recorders/_Inputs/GameView/GameViewInput.cs index c3b7c29..699fc71 100644 --- a/Editor/Sources/Recorders/_Inputs/GameView/GameViewInput.cs +++ b/Editor/Sources/Recorders/_Inputs/GameView/GameViewInput.cs @@ -77,6 +77,9 @@ protected internal override void BeginRecording(RecordingSession session) OutputWidth = scSettings.OutputWidth; OutputHeight = scSettings.OutputHeight; + if (OutputWidth <= 0 || OutputHeight <= 0) + return; // error will be handled by ImageInputSettings.CheckForErrors. Otherwise we get a failure at RenderTexture.GetTemporary() + int w, h; GameViewSize.GetGameRenderSize(out w, out h); if (w != OutputWidth || h != OutputHeight) diff --git a/Editor/Sources/Recorders/_Inputs/GameView/GameViewInputPropertyDrawer.cs b/Editor/Sources/Recorders/_Inputs/GameView/GameViewInputPropertyDrawer.cs index 6dfafb7..8385223 100644 --- a/Editor/Sources/Recorders/_Inputs/GameView/GameViewInputPropertyDrawer.cs +++ b/Editor/Sources/Recorders/_Inputs/GameView/GameViewInputPropertyDrawer.cs @@ -14,9 +14,6 @@ static class Styles protected override void Initialize(SerializedProperty property) { - if (target != null) - return; - base.Initialize(property); m_OutputResolution = property.FindPropertyRelative("m_OutputResolution"); diff --git a/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInput.cs b/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInput.cs index d8aa62d..2656b61 100644 --- a/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInput.cs +++ b/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInput.cs @@ -1,50 +1,98 @@ using System; +using System.ComponentModel; +using UnityEngine; namespace UnityEditor.Recorder.Input { class RenderTextureInput : BaseRenderTextureInput { - TextureFlipper m_VFlipper; + // Whether or not the incoming RenderTexture must be flipped vertically + private bool m_needToFlipVertically = false; - RenderTextureInputSettings cbSettings + // Whether or not the incoming RenderTexture must be converted from linear to sRGB color space + private bool m_needToConvertLinearToSRGB = false; + + RenderTextureInputSettings cbSettings => (RenderTextureInputSettings)settings; + + // An internal RenderTexture copied from the input RenderTexture when vertical flip and/or sRGB conversion need to be performed + internal RenderTexture workTexture = null; + + // A material to perform vertical flips and/or sRGB conversion of a RenderTexture + private Material MaterialRenderTextureCopy { - get { return (RenderTextureInputSettings)settings; } + get + { + if (_matSRGBConversion == null) + _matSRGBConversion = new Material(Shader.Find("Hidden/RenderTextureCopy")); + return _matSRGBConversion; + } } + private Material _matSRGBConversion = null; // a shader for doing linear to sRGB conversion protected internal override void BeginRecording(RecordingSession session) { if (cbSettings.renderTexture == null) - throw new Exception("No Render Texture object provided as source"); + return; // error will have been triggered in RenderTextureInputSettings.CheckForErrors() OutputHeight = cbSettings.OutputHeight; OutputWidth = cbSettings.OutputWidth; - OutputRenderTexture = cbSettings.renderTexture; - bool needToFlip = cbSettings.FlipFinalOutput; // whether or not the recorder settings have the flip box checked + m_needToFlipVertically = cbSettings.FlipFinalOutput; // whether or not the recorder settings have the flip box checked var movieRecorderSettings = session.settings as MovieRecorderSettings; if (movieRecorderSettings != null) { bool encoderAlreadyFlips = movieRecorderSettings.encodersRegistered[movieRecorderSettings.encoderSelected].PerformsVerticalFlip; - needToFlip = needToFlip ? encoderAlreadyFlips : !encoderAlreadyFlips; + m_needToFlipVertically = m_needToFlipVertically ? encoderAlreadyFlips : !encoderAlreadyFlips; + } + + m_needToConvertLinearToSRGB = session.settings.NeedToConvertFromLinearToSRGB(); + if (m_needToFlipVertically || m_needToConvertLinearToSRGB) + { + workTexture = new RenderTexture(OutputRenderTexture); + workTexture.name = "RenderTextureInput_intermediate"; } - if (needToFlip) - m_VFlipper = new TextureFlipper(); } protected internal override void NewFrameReady(RecordingSession session) { - bool needToFlip = cbSettings.FlipFinalOutput; // whether or not the recorder settings have the flip box checked - var movieRecorderSettings = session.settings as MovieRecorderSettings; - if (movieRecorderSettings != null) + if (cbSettings.renderTexture == null) + return; // error will have been triggered in BeginRecording() + + if (m_needToFlipVertically) + MaterialRenderTextureCopy.EnableKeyword("VERTICAL_FLIP"); + + if (m_needToConvertLinearToSRGB) + MaterialRenderTextureCopy.EnableKeyword("SRGB_CONVERSION"); + + if (m_needToFlipVertically || m_needToConvertLinearToSRGB) { - bool encoderAlreadyFlips = movieRecorderSettings.encodersRegistered[movieRecorderSettings.encoderSelected].PerformsVerticalFlip; - needToFlip = needToFlip ? encoderAlreadyFlips : !encoderAlreadyFlips; + // Perform the actual conversion + var rememberActive = RenderTexture.active; + Graphics.Blit(cbSettings.renderTexture, workTexture, MaterialRenderTextureCopy); + RenderTexture.active = rememberActive; // restore active RT + + // Make the final texture use the modified texture + OutputRenderTexture = workTexture; + } + else + { + // Just use the input without any changes + OutputRenderTexture = cbSettings.renderTexture; } - if (needToFlip) - OutputRenderTexture = m_VFlipper.Flip(OutputRenderTexture); base.NewFrameReady(session); } + + protected internal override void EndRecording(RecordingSession session) + { + base.EndRecording(session); + + if (workTexture != null) + { + UnityHelpers.Destroy(workTexture); + workTexture = null; + } + } } } diff --git a/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettings.cs b/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettings.cs index e8d097c..e669da1 100644 --- a/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettings.cs +++ b/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettings.cs @@ -60,18 +60,11 @@ public override int OutputHeight } } - /// - protected internal override bool ValidityCheck(List errors) + protected internal override void CheckForErrors(List errors) { - var ok = true; - + base.CheckForErrors(errors); if (renderTexture == null) - { - ok = false; errors.Add("Missing source render texture object/asset."); - } - - return ok; } } } diff --git a/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettingsPropertyDrawer.cs b/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettingsPropertyDrawer.cs index 9b09e3c..525d981 100644 --- a/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettingsPropertyDrawer.cs +++ b/Editor/Sources/Recorders/_Inputs/RenderTexture/RenderTextureInputSettingsPropertyDrawer.cs @@ -18,11 +18,8 @@ protected override void Initialize(SerializedProperty property) { base.Initialize(property); - if (m_SourceRTxtr == null) - m_SourceRTxtr = property.FindPropertyRelative("renderTexture"); - - if (m_FlipFinalOutput == null) - m_FlipFinalOutput = property.FindPropertyRelative("flipFinalOutput"); + m_SourceRTxtr = property.FindPropertyRelative("renderTexture"); + m_FlipFinalOutput = property.FindPropertyRelative("flipFinalOutput"); } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) diff --git a/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/RenderTextureSamplerSettings.cs b/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/RenderTextureSamplerSettings.cs index b4ff661..0c0633a 100644 --- a/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/RenderTextureSamplerSettings.cs +++ b/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/RenderTextureSamplerSettings.cs @@ -101,18 +101,11 @@ protected internal override Type InputType } /// - protected internal override bool ValidityCheck(List errors) + protected internal override void CheckForWarnings(List warnings) { - var ok = true; - var h = OutputHeight; if (h > kMaxSupportedSize) - { - ok = false; - errors.Add("Output size exceeds maximum supported height: " + kMaxSupportedSize + "px"); - } - - return ok; + warnings.Add($"The image size exceeds the recommended maximum height: {(int)kMaxSupportedSize} px"); } /// diff --git a/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/Shaders/BS4SuperShader.shader b/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/Shaders/BS4SuperShader.shader index 6183a4e..5d829a4 100644 --- a/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/Shaders/BS4SuperShader.shader +++ b/Editor/Sources/Recorders/_Inputs/RenderTextureSampler/Shaders/BS4SuperShader.shader @@ -63,7 +63,7 @@ float4 float4ToGammaSpace(float4 value) float4 frag(v2f i) : SV_Target { const int width = ceil(_MainTex_TexelSize.z / _Target_TexelSize.z / 2.f); const float ratio = 1.f / (1.41f * width); - + float weight = 0.f; float4 color = float4(0.f, 0.f, 0.f, 0.f); @@ -71,20 +71,20 @@ float4 frag(v2f i) : SV_Target { for(int x = -width; x <= width; ++x) { float2 off = float2(x * _MainTex_TexelSize.x, y * _MainTex_TexelSize.y); float2 uv = i.uv + off; - - float3 s = tex2D(_MainTex, uv).rgb; - + + float4 s = tex2D(_MainTex, uv).rgba; + float c = clamp(sqrt(x*x + y*y) * ratio * (1.f/_KernelScale), -1.57f, 1.57f); float w = pow(cos(c), _KernelCosPower); - color.rgb += s.rgb * w; + color.rgba += s.rgba * w; weight += w; } } if (_ApplyGammaCorrection == 0) - return _NormalizationFactor * color.rgbb / weight; + return _NormalizationFactor * color.rgba / weight; else - return float4ToGammaSpace(_NormalizationFactor * color.rgbb / weight); + return float4ToGammaSpace(_NormalizationFactor * color.rgba / weight); } ENDCG diff --git a/Editor/Sources/Recorders/_Legacy/BaseFCRecorderSettings.cs b/Editor/Sources/Recorders/_Legacy/BaseFCRecorderSettings.cs index ebc1e7a..61b1f86 100644 --- a/Editor/Sources/Recorders/_Legacy/BaseFCRecorderSettings.cs +++ b/Editor/Sources/Recorders/_Legacy/BaseFCRecorderSettings.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using UnityEngine; using UnityEditor.Recorder.Input; @@ -7,16 +8,11 @@ namespace UnityEditor.Recorder.FrameCapturer /// /// The settings common to all recordings that capture image data. /// + [Obsolete("The legacy recorders are deprecated")] public abstract class BaseFCRecorderSettings : RecorderSettings { [SerializeField] internal UTJImageInputSelector m_ImageInputSelector = new UTJImageInputSelector(); - protected internal override bool ValidityCheck(List errors) - { - var ok = base.ValidityCheck(errors); - return ok; - } - /// /// The properties of the image input. /// @@ -26,22 +22,6 @@ public ImageInputSettings imageInputSettings set { m_ImageInputSelector.imageInputSettings = value; } } - /// - /// Specifies whether this class is supported on the current platform or not. - /// - public override bool IsPlatformSupported - { - get - { - return Application.platform == RuntimePlatform.WindowsEditor || - Application.platform == RuntimePlatform.WindowsPlayer || - Application.platform == RuntimePlatform.OSXEditor || - Application.platform == RuntimePlatform.OSXPlayer || - Application.platform == RuntimePlatform.LinuxEditor || - Application.platform == RuntimePlatform.LinuxPlayer; - } - } - /// /// The list of settings of the Recorder inputs. /// diff --git a/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorder.cs b/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorder.cs index df96bde..2ec0015 100644 --- a/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorder.cs +++ b/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorder.cs @@ -4,44 +4,8 @@ namespace UnityEditor.Recorder.FrameCapturer { class EXRRecorder : GenericRecorder { - static readonly string[] s_channelNames = { "R", "G", "B", "A" }; - fcAPI.fcExrContext m_ctx; - - protected internal override bool BeginRecording(RecordingSession session) - { - if (!base.BeginRecording(session)) { return false; } - - Settings.fileNameGenerator.CreateDirectory(session); - - m_ctx = fcAPI.fcExrCreateContext(ref Settings.m_ExrEncoderSettings); - return m_ctx; - } - - protected internal override void EndRecording(RecordingSession session) - { - m_ctx.Release(); - base.EndRecording(session); - } - protected internal override void RecordFrame(RecordingSession session) { - if (m_Inputs.Count != 1) - throw new Exception("Unsupported number of sources"); - - var path = Settings.fileNameGenerator.BuildAbsolutePath(session); - - var input = (BaseRenderTextureInput)m_Inputs[0]; - var frame = input.OutputRenderTexture; - fcAPI.fcLock(frame, (data, fmt) => - { - fcAPI.fcExrBeginImage(m_ctx, path, frame.width, frame.height); - int channels = (int)fmt & 7; - for (int i = 0; i < channels; ++i) - { - fcAPI.fcExrAddLayerPixels(m_ctx, data, fmt, i, s_channelNames[i]); - } - fcAPI.fcExrEndImage(m_ctx); - }); } } } diff --git a/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettings.cs b/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettings.cs index da9ebb5..fb9f9a9 100644 --- a/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettings.cs +++ b/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettings.cs @@ -1,15 +1,10 @@ namespace UnityEditor.Recorder.FrameCapturer { - [RecorderSettings(typeof(EXRRecorder), "Legacy/OpenEXR")] + [RecorderSettings(typeof(EXRRecorder), "Legacy/OpenEXR", true)] +#pragma warning disable 618 class EXRRecorderSettings : BaseFCRecorderSettings { - public fcAPI.fcExrConfig m_ExrEncoderSettings = fcAPI.fcExrConfig.default_value; - - public EXRRecorderSettings() - { - fileNameGenerator.FileName = "image_" + DefaultWildcard.Frame; - } - +#pragma warning restore 618 protected internal override string Extension { get { return "exr"; } diff --git a/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettingsEditor.cs b/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettingsEditor.cs index 89c099b..be04bc4 100644 --- a/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettingsEditor.cs +++ b/Editor/Sources/Recorders/_Legacy/EXR/EXRRecorderSettingsEditor.cs @@ -5,9 +5,9 @@ namespace UnityEditor.Recorder.FrameCapturer [CustomEditor(typeof(EXRRecorderSettings))] class EXRRecorderSettingsEditor : RecorderEditor { - protected override void OnEncodingGui() + public override void OnInspectorGUI() { - EditorGUILayout.PropertyField(serializedObject.FindProperty("m_ExrEncoderSettings"), new GUIContent("Encoding"), true); + EditorGUILayout.LabelField("The selected legacy EXR recorder has been deprecated."); } } } diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer.meta deleted file mode 100644 index a40bd4d..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 522bab85d8eab374194107c6d00ba0e5 -folderAsset: yes -timeCreated: 1432793486 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins.meta deleted file mode 100644 index fe6cf57..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 178d677034729554ba412d8026f03471 -folderAsset: yes -timeCreated: 1432793503 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86.meta deleted file mode 100644 index 6b2520b..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: b6a99610875e99f4a86c25c0d98826fb -folderAsset: yes -timeCreated: 1433034131 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86/fccore.dll b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86/fccore.dll deleted file mode 100644 index dd17ac5..0000000 Binary files a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86/fccore.dll and /dev/null differ diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86/fccore.dll.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86/fccore.dll.meta deleted file mode 100644 index 3adf547..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86/fccore.dll.meta +++ /dev/null @@ -1,111 +0,0 @@ -fileFormatVersion: 2 -guid: aa20290b6edf1374384422fa698914c1 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 0 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - '': Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Linux: 1 - Exclude Linux64: 1 - Exclude LinuxUniversal: 1 - Exclude OSXUniversal: 1 - Exclude WebGL: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - - first: - '': OSXIntel - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - '': OSXIntel64 - second: - enabled: 0 - settings: - CPU: None - - first: - Any: - second: - enabled: 0 - settings: {} - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86 - DefaultValueInitialized: true - OS: Windows - - first: - Facebook: Win - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Facebook: Win64 - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Linux - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: LinuxUniversal - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: None - - first: - iPhone: iOS - second: - enabled: 0 - settings: - AddToEmbeddedBinaries: false - CompileFlags: - FrameworkDependencies: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64.meta deleted file mode 100644 index a461240..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: bb423a2251dfbf04488bb95a0f1ec0e1 -folderAsset: yes -timeCreated: 1432793511 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux.meta deleted file mode 100644 index a8cbb2e..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 837796ba76e21119f95433759abd2c15 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux/libfccore.so b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux/libfccore.so deleted file mode 100644 index 639d6e7..0000000 Binary files a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux/libfccore.so and /dev/null differ diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux/libfccore.so.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux/libfccore.so.meta deleted file mode 100644 index 0b232ab..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/Linux/libfccore.so.meta +++ /dev/null @@ -1,83 +0,0 @@ -fileFormatVersion: 2 -guid: 0af7abacc99baea51b0926dac109b024 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - '': Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Linux: 1 - Exclude Linux64: 1 - Exclude LinuxUniversal: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - - first: - Any: - second: - enabled: 0 - settings: {} - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86_64 - DefaultValueInitialized: true - OS: Linux - - first: - Facebook: Win - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Facebook: Win64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: Linux - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.bundle.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.bundle.meta deleted file mode 100644 index 5ec22b9..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.bundle.meta +++ /dev/null @@ -1,114 +0,0 @@ -fileFormatVersion: 2 -guid: 095a7aaa840de2c40b28e8f46c6527bd -folderAsset: yes -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 0 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - '': Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Linux: 0 - Exclude Linux64: 1 - Exclude LinuxUniversal: 0 - Exclude OSXIntel: 1 - Exclude OSXIntel64: 0 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - - first: - Any: - second: - enabled: 0 - settings: {} - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86_64 - DefaultValueInitialized: true - OS: OSX - - first: - Facebook: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Facebook: Win64 - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Linux - second: - enabled: 1 - settings: - CPU: None - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: LinuxUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: OSXIntel - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: OSXIntel64 - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - iPhone: iOS - second: - enabled: 0 - settings: - AddToEmbeddedBinaries: false - CPU: AnyCPU - CompileFlags: - FrameworkDependencies: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.bundle/Contents.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.bundle/Contents.meta deleted file mode 100644 index d7f1621..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.bundle/Contents.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 96396973072080b44b74b8b56e8ca90f -folderAsset: yes -timeCreated: 1494431117 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.dll b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.dll deleted file mode 100644 index 536c327..0000000 Binary files a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.dll and /dev/null differ diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.dll.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.dll.meta deleted file mode 100644 index 76795c9..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Plugins/x86_64/fccore.dll.meta +++ /dev/null @@ -1,111 +0,0 @@ -fileFormatVersion: 2 -guid: 63c38849eea80254baf1f89f59024f36 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 0 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - '': Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Linux: 1 - Exclude Linux64: 1 - Exclude LinuxUniversal: 1 - Exclude OSXUniversal: 1 - Exclude WebGL: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - - first: - '': OSXIntel - second: - enabled: 0 - settings: - CPU: None - - first: - '': OSXIntel64 - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Any: - second: - enabled: 0 - settings: {} - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86_64 - DefaultValueInitialized: true - OS: Windows - - first: - Facebook: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Facebook: Win64 - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Linux - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: LinuxUniversal - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - iPhone: iOS - second: - enabled: 0 - settings: - AddToEmbeddedBinaries: false - CompileFlags: - FrameworkDependencies: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts.meta deleted file mode 100644 index 732594b..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 2eb1eb6bf0605b8469d2d383642f1fe4 -folderAsset: yes -timeCreated: 1432793494 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder.meta deleted file mode 100644 index 34de13d..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: fde401d160f133842addfb7db5ae4c97 -folderAsset: yes -timeCreated: 1494318897 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EXREncoder.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EXREncoder.cs deleted file mode 100644 index e43a7a5..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EXREncoder.cs +++ /dev/null @@ -1,54 +0,0 @@ -using UnityEngine; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - class EXREncoder : MovieEncoder - { - static readonly string[] s_channelNames = { "R", "G", "B", "A" }; - fcAPI.fcExrContext m_ctx; - fcAPI.fcExrConfig m_config; - string m_outPath; - int m_frame; - - public override void Release() { m_ctx.Release(); } - public override bool IsValid() { return m_ctx; } - public override Type type { get { return Type.Exr; } } - - public override void Initialize(object config, string outPath) - { - if (!fcAPI.fcExrIsSupported()) - { - Debug.LogError("Exr encoder is not available on this platform."); - return; - } - - m_config = (fcAPI.fcExrConfig)config; - m_ctx = fcAPI.fcExrCreateContext(ref m_config); - m_outPath = outPath; - m_frame = 0; - } - - public override void AddVideoFrame(byte[] frame, fcAPI.fcPixelFormat format, double timestamp = -1.0) - { - if (m_ctx) - { - string path = m_outPath + "_" + m_frame.ToString("0000") + ".exr"; - int channels = System.Math.Min(m_config.channels, (int)format & 7); - - fcAPI.fcExrBeginImage(m_ctx, path, m_config.width, m_config.height); - for (int i = 0; i < channels; ++i) - { - fcAPI.fcExrAddLayerPixels(m_ctx, frame, format, i, s_channelNames[i]); - } - fcAPI.fcExrEndImage(m_ctx); - } - ++m_frame; - } - - public override void AddAudioSamples(float[] samples) - { - // not supported - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EXREncoder.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EXREncoder.cs.meta deleted file mode 100644 index 56be2bc..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EXREncoder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 2edf1ed5e1f1c8544b925c302853bbb8 -timeCreated: 1494000131 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EncoderBase.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EncoderBase.cs deleted file mode 100644 index aa67afc..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EncoderBase.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - abstract class EncoderBase - { - protected EncoderBase() - { - AppDomain.CurrentDomain.DomainUnload += WaitAsyncDelete; - } - - static void WaitAsyncDelete(object sender, EventArgs e) - { - fcAPI.fcWaitAsyncDelete(); - } - - public abstract void Release(); - public abstract bool IsValid(); - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EncoderBase.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EncoderBase.cs.meta deleted file mode 100644 index 91c130e..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/EncoderBase.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5078fb266c916184bb5cd9e635b82f9d -timeCreated: 1494630775 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/GIFEncoder.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/GIFEncoder.cs deleted file mode 100644 index 5935a0f..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/GIFEncoder.cs +++ /dev/null @@ -1,46 +0,0 @@ -using UnityEngine; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - class GIFEncoder : MovieEncoder - { - fcAPI.fcGifContext m_ctx; - fcAPI.fcGifConfig m_config; - - public override void Release() { m_ctx.Release(); } - public override bool IsValid() { return m_ctx; } - public override Type type { get { return Type.Gif; } } - - public override void Initialize(object config, string outPath) - { - if (!fcAPI.fcGifIsSupported()) - { - Debug.LogError("Gif encoder is not available on this platform."); - return; - } - - m_config = (fcAPI.fcGifConfig)config; - m_config.numColors = Mathf.Clamp(m_config.numColors, 1, 256); - m_ctx = fcAPI.fcGifCreateContext(ref m_config); - - var path = outPath + ".gif"; - var stream = fcAPI.fcCreateFileStream(path); - fcAPI.fcGifAddOutputStream(m_ctx, stream); - stream.Release(); - } - - public override void AddVideoFrame(byte[] frame, fcAPI.fcPixelFormat format, double timestamp) - { - if (m_ctx) - { - fcAPI.fcGifAddFramePixels(m_ctx, frame, format, timestamp); - } - } - - public override void AddAudioSamples(float[] samples) - { - // not supported - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/GIFEncoder.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/GIFEncoder.cs.meta deleted file mode 100644 index f51cc3c..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/GIFEncoder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: e328bea6ad6257848a01305be866b33b -timeCreated: 1493996447 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MP4Encoder.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MP4Encoder.cs deleted file mode 100644 index e6cbd7e..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MP4Encoder.cs +++ /dev/null @@ -1,47 +0,0 @@ -using UnityEngine; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - class MP4Encoder : MovieEncoder - { - fcAPI.fcMP4Context m_ctx; - fcAPI.fcMP4Config m_config; - - public override void Release() { m_ctx.Release(); } - public override bool IsValid() { return m_ctx; } - public override Type type { get { return Type.MP4; } } - - public override void Initialize(object config, string outPath) - { - if (!fcAPI.fcMP4OSIsSupported()) - { - Debug.LogError("MP4 encoder is not available on this platform."); - return; - } - - m_config = (fcAPI.fcMP4Config)config; - m_config.audioSampleRate = AudioSettings.outputSampleRate; - m_config.audioNumChannels = fcAPI.fcGetNumAudioChannels(); - - var path = outPath + ".mp4"; - m_ctx = fcAPI.fcMP4OSCreateContext(ref m_config, path); - } - - public override void AddVideoFrame(byte[] frame, fcAPI.fcPixelFormat format, double timestamp) - { - if (m_ctx && m_config.video) - { - fcAPI.fcMP4AddVideoFramePixels(m_ctx, frame, format, timestamp); - } - } - - public override void AddAudioSamples(float[] samples) - { - if (m_ctx && m_config.audio) - { - fcAPI.fcMP4AddAudioSamples(m_ctx, samples, samples.Length); - } - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MP4Encoder.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MP4Encoder.cs.meta deleted file mode 100644 index 172d681..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MP4Encoder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 15136ad38d3c16f4d91a6c802884de03 -timeCreated: 1493996447 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MovieEncoder.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MovieEncoder.cs deleted file mode 100644 index 8d1774b..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MovieEncoder.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace UnityEditor.Recorder.FrameCapturer -{ - [Serializable] - class MovieEncoderConfigs - { - public MovieEncoder.Type format = MovieEncoder.Type.WebM; - public fcAPI.fcPngConfig pngEncoderSettings = fcAPI.fcPngConfig.default_value; - public fcAPI.fcExrConfig exrEncoderSettings = fcAPI.fcExrConfig.default_value; - public fcAPI.fcGifConfig gifEncoderSettings = fcAPI.fcGifConfig.default_value; - public fcAPI.fcWebMConfig webmEncoderSettings = fcAPI.fcWebMConfig.default_value; - public fcAPI.fcMP4Config mp4EncoderSettings = fcAPI.fcMP4Config.default_value; - - public MovieEncoderConfigs(MovieEncoder.Type t) - { - format = t; - } - - public bool supportVideo - { - get - { - return - format == MovieEncoder.Type.Png || - format == MovieEncoder.Type.Exr || - format == MovieEncoder.Type.Gif || - format == MovieEncoder.Type.WebM || - format == MovieEncoder.Type.MP4; - } - } - - public bool supportAudio - { - get - { - return - format == MovieEncoder.Type.WebM || - format == MovieEncoder.Type.MP4; - } - } - - public bool captureVideo - { - get - { - switch (format) - { - case MovieEncoder.Type.Png: return true; - case MovieEncoder.Type.Exr: return true; - case MovieEncoder.Type.Gif: return true; - case MovieEncoder.Type.WebM: return webmEncoderSettings.video; - case MovieEncoder.Type.MP4: return webmEncoderSettings.video; - } - return false; - } - set - { - webmEncoderSettings.video = - mp4EncoderSettings.video = value; - } - } - public bool captureAudio - { - get - { - switch (format) - { - case MovieEncoder.Type.Png: return false; - case MovieEncoder.Type.Exr: return false; - case MovieEncoder.Type.Gif: return false; - case MovieEncoder.Type.WebM: return webmEncoderSettings.audio; - case MovieEncoder.Type.MP4: return webmEncoderSettings.audio; - } - return false; - } - set - { - webmEncoderSettings.audio = - mp4EncoderSettings.audio = value; - } - } - - public void Setup(int w, int h, int ch = 4, int targetFrameRate = 60) - { - pngEncoderSettings.width = - exrEncoderSettings.width = - gifEncoderSettings.width = - webmEncoderSettings.videoWidth = - mp4EncoderSettings.videoWidth = w; - - pngEncoderSettings.height = - exrEncoderSettings.height = - gifEncoderSettings.height = - webmEncoderSettings.videoHeight = - mp4EncoderSettings.videoHeight = h; - - pngEncoderSettings.channels = - exrEncoderSettings.channels = ch; - - webmEncoderSettings.videoTargetFramerate = - mp4EncoderSettings.videoTargetFramerate = targetFrameRate; - } - } - - abstract class MovieEncoder : EncoderBase - { - public enum Type - { - Png, - Exr, - Gif, - WebM, - MP4, - } - - public static Type[] GetAvailableEncoderTypes() - { - var ret = new List(); - if (fcAPI.fcPngIsSupported()) { ret.Add(Type.Png); } - if (fcAPI.fcExrIsSupported()) { ret.Add(Type.Exr); } - if (fcAPI.fcGifIsSupported()) { ret.Add(Type.Gif); } - if (fcAPI.fcWebMIsSupported()) { ret.Add(Type.WebM); } - if (fcAPI.fcMP4OSIsSupported()) { ret.Add(Type.MP4); } - return ret.ToArray(); - } - - public abstract Type type { get; } - - // config: config struct (fcGifConfig, fcWebMConfig, etc) - public abstract void Initialize(object config, string outPath); - public abstract void AddVideoFrame(byte[] frame, fcAPI.fcPixelFormat format, double timestamp = -1.0); - public abstract void AddAudioSamples(float[] samples); - - - public static MovieEncoder Create(Type t) - { - switch (t) - { - case Type.Png: return new PNGEncoder(); - case Type.Exr: return new EXREncoder(); - case Type.Gif: return new GIFEncoder(); - case Type.WebM: return new WEBMEncoder(); - case Type.MP4: return new MP4Encoder(); - } - return null; - } - -// public static MovieEncoder Create(MovieEncoderConfigs c, string path) -// { -// var ret = Create(c.format); -// switch (c.format) -// { -// case Type.Png: ret.Initialize(c.pngEncoderSettings, path); break; -// case Type.Exr: ret.Initialize(c.exrEncoderSettings, path); break; -// case Type.Gif: ret.Initialize(c.gifEncoderSettings, path); break; -// case Type.WebM:ret.Initialize(c.webmEncoderSettings,path); break; -// case Type.MP4: ret.Initialize(c.mp4EncoderSettings, path); break; -// } -// return ret; -// } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MovieEncoder.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MovieEncoder.cs.meta deleted file mode 100644 index 9303521..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/MovieEncoder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 05a483774a00261429ff072ba4a63bea -timeCreated: 1493995555 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/PNGEncoder.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/PNGEncoder.cs deleted file mode 100644 index e4e5dfb..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/PNGEncoder.cs +++ /dev/null @@ -1,48 +0,0 @@ -using UnityEngine; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - class PNGEncoder : MovieEncoder - { - fcAPI.fcPngContext m_ctx; - fcAPI.fcPngConfig m_config; - string m_outPath; - int m_frame; - - - public override void Release() { m_ctx.Release(); } - public override bool IsValid() { return m_ctx; } - public override Type type { get { return Type.Png; } } - - public override void Initialize(object config, string outPath) - { - if (!fcAPI.fcPngIsSupported()) - { - Debug.LogError("Png encoder is not available on this platform."); - return; - } - - m_config = (fcAPI.fcPngConfig)config; - m_ctx = fcAPI.fcPngCreateContext(ref m_config); - m_outPath = outPath; - m_frame = 0; - } - - public override void AddVideoFrame(byte[] frame, fcAPI.fcPixelFormat format, double timestamp = -1.0) - { - if (m_ctx) - { - string path = m_outPath + "_" + m_frame.ToString("0000") + ".png"; - int channels = System.Math.Min(m_config.channels, (int)format & 7); - fcAPI.fcPngExportPixels(m_ctx, path, frame, m_config.width, m_config.height, format, channels); - } - ++m_frame; - } - - public override void AddAudioSamples(float[] samples) - { - // not supported - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/PNGEncoder.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/PNGEncoder.cs.meta deleted file mode 100644 index 4c97028..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/PNGEncoder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: cb579d3ab681ded4bbcd41bac0530cb4 -timeCreated: 1494000131 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/WEBMEncoder.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/WEBMEncoder.cs deleted file mode 100644 index b64a411..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/WEBMEncoder.cs +++ /dev/null @@ -1,60 +0,0 @@ -using UnityEngine; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - class WEBMEncoder : MovieEncoder - { - fcAPI.fcWebMContext m_ctx; - fcAPI.fcWebMConfig m_config; - - public override void Release() { m_ctx.Release(); } - public override bool IsValid() { return m_ctx; } - public override Type type { get { return Type.WebM; } } - - public override void Initialize(object config, string outPath) - { - if (!fcAPI.fcWebMIsSupported()) - { - Debug.LogError("WebM encoder is not available on this platform."); - return; - } - - m_config = (fcAPI.fcWebMConfig)config; - if (m_config.audio && m_config.audioEncoder == fcAPI.fcWebMAudioEncoder.Opus) - { - var sampleRate = AudioSettings.outputSampleRate; - if (sampleRate != 8000 && sampleRate != 12000 && sampleRate != 16000 && sampleRate != 24000 && sampleRate != 48000) - { - Debug.LogError("Current output sample rate is " + sampleRate + ". It must be 8000, 12000, 16000, 24000 or 48000 to use Opus audio encoder. Fallback to Vorbis."); - m_config.audioEncoder = fcAPI.fcWebMAudioEncoder.Vorbis; - } - } - - m_config.audioSampleRate = AudioSettings.outputSampleRate; - m_config.audioNumChannels = fcAPI.fcGetNumAudioChannels(); - m_ctx = fcAPI.fcWebMCreateContext(ref m_config); - - var path = outPath + ".webm"; - var stream = fcAPI.fcCreateFileStream(path); - fcAPI.fcWebMAddOutputStream(m_ctx, stream); - stream.Release(); - } - - public override void AddVideoFrame(byte[] frame, fcAPI.fcPixelFormat format, double timestamp) - { - if (m_ctx && m_config.video) - { - fcAPI.fcWebMAddVideoFramePixels(m_ctx, frame, format, timestamp); - } - } - - public override void AddAudioSamples(float[] samples) - { - if (m_ctx && m_config.audio) - { - fcAPI.fcWebMAddAudioSamples(m_ctx, samples, samples.Length); - } - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/WEBMEncoder.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/WEBMEncoder.cs.meta deleted file mode 100644 index 77686af..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/WEBMEncoder.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: feb89bd50fd2c9b4589670dc229526c7 -timeCreated: 1493996447 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/fcAPI.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/fcAPI.cs deleted file mode 100644 index be52f6a..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/fcAPI.cs +++ /dev/null @@ -1,527 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using UnityEngine; - -namespace UnityEditor.Recorder.FrameCapturer -{ - static class fcAPI - { - // ------------------------------------------------------------- - // Foundation - // ------------------------------------------------------------- - - internal enum fcPixelFormat - { - Unknown = 0, - - ChannelMask = 0xF, - TypeMask = 0xF << 4, - Type_f16 = 0x1 << 4, - Type_f32 = 0x2 << 4, - Type_u8 = 0x3 << 4, - Type_i16 = 0x4 << 4, - Type_i32 = 0x5 << 4, - - Rf16 = Type_f16 | 1, - RGf16 = Type_f16 | 2, - RGBf16 = Type_f16 | 3, - RGBAf16 = Type_f16 | 4, - Rf32 = Type_f32 | 1, - RGf32 = Type_f32 | 2, - RGBf32 = Type_f32 | 3, - RGBAf32 = Type_f32 | 4, - Ru8 = Type_u8 | 1, - RGu8 = Type_u8 | 2, - RGBu8 = Type_u8 | 3, - RGBAu8 = Type_u8 | 4, - Ri16 = Type_i16 | 1, - RGi16 = Type_i16 | 2, - RGBi16 = Type_i16 | 3, - RGBAi16 = Type_i16 | 4, - Ri32 = Type_i32 | 1, - RGi32 = Type_i32 | 2, - RGBi32 = Type_i32 | 3, - RGBAi32 = Type_i32 | 4, - }; - - internal enum fcBitrateMode - { - CBR, - VBR, - } - - internal enum fcAudioBitsPerSample - { - _8Bits = 8, - _16Bits = 16, - _24Bits = 24, - } - - internal struct fcDeferredCall - { - public int handle; - public void Release() { fcReleaseDeferredCall(this); handle = 0; } - public static implicit operator int(fcDeferredCall v) { return v.handle; } - } - - internal struct fcStream - { - public IntPtr ptr; - public void Release() { fcReleaseStream(this); ptr = IntPtr.Zero; } - public static implicit operator bool(fcStream v) { return v.ptr != IntPtr.Zero; } - } - [DllImport("fccore")] internal static extern fcStream fcCreateFileStream(string path); - [DllImport("fccore")] static extern void fcReleaseStream(fcStream s); - - [DllImport("fccore")] static extern void fcGuardBegin(); - [DllImport("fccore")] static extern void fcGuardEnd(); - [DllImport("fccore")] static extern void fcReleaseDeferredCall(fcDeferredCall dc); - - internal static fcPixelFormat fcGetPixelFormat(TextureFormat v) - { - switch (v) - { - case TextureFormat.Alpha8: return fcPixelFormat.Ru8; - case TextureFormat.RGB24: return fcPixelFormat.RGBu8; - case TextureFormat.RGBA32: return fcPixelFormat.RGBAu8; - case TextureFormat.ARGB32: return fcPixelFormat.RGBAu8; - case TextureFormat.RGBAHalf: return fcPixelFormat.RGBAf16; - case TextureFormat.RGHalf: return fcPixelFormat.RGf16; - case TextureFormat.RHalf: return fcPixelFormat.Rf16; - case TextureFormat.RGBAFloat: return fcPixelFormat.RGBAf32; - case TextureFormat.RGFloat: return fcPixelFormat.RGf32; - case TextureFormat.RFloat: return fcPixelFormat.Rf32; - } - return fcPixelFormat.Unknown; - } - - internal static int fcGetNumAudioChannels() - { - switch (AudioSettings.speakerMode) - { - case AudioSpeakerMode.Mono: return 1; - case AudioSpeakerMode.Stereo: return 2; - case AudioSpeakerMode.Quad: return 4; - case AudioSpeakerMode.Surround: return 5; - case AudioSpeakerMode.Mode5point1: return 6; - case AudioSpeakerMode.Mode7point1: return 8; - case AudioSpeakerMode.Prologic: return 6; - } - return 0; - } - - [DllImport("fccore")] internal static extern void fcWaitAsyncDelete(); - [DllImport("fccore")] internal static extern void fcReleaseContext(IntPtr ctx); - - - // ------------------------------------------------------------- - // PNG Exporter - // ------------------------------------------------------------- - - internal enum fcPngPixelFormat - { - Auto, // select optimal one for input data - UInt8, - UInt16, - }; - - [Serializable] - internal struct fcPngConfig - { - public fcPngPixelFormat pixelFormat; - [Range(1, 32)] public int maxTasks; - // C# ext - [HideInInspector] public int width; - [HideInInspector] public int height; - [HideInInspector] public int channels; - - internal static fcPngConfig default_value - { - get - { - return new fcPngConfig - { - pixelFormat = fcPngPixelFormat.Auto, - maxTasks = 2, - }; - } - } - }; - - internal struct fcPngContext - { - public IntPtr ptr; - public void Release() { fcReleaseContext(ptr); ptr = IntPtr.Zero; } - public static implicit operator bool(fcPngContext v) { return v.ptr != IntPtr.Zero; } - } - - [DllImport("fccore")] internal static extern Bool fcPngIsSupported(); - [DllImport("fccore")] internal static extern fcPngContext fcPngCreateContext(ref fcPngConfig conf); - [DllImport("fccore")] internal static extern Bool fcPngExportPixels(fcPngContext ctx, string path, byte[] pixels, int width, int height, fcPixelFormat fmt, int num_channels); - - - // ------------------------------------------------------------- - // EXR Exporter - // ------------------------------------------------------------- - - internal enum fcExrPixelFormat - { - Auto, // select optimal one for input data - Half, - Float, - Int, - }; - - internal enum fcExrCompression - { - None, - RLE, - ZipS, // par-line - Zip, // block - PIZ, - }; - - [Serializable] - internal struct fcExrConfig - { - public fcExrPixelFormat pixelFormat; - public fcExrCompression compression; - [Range(1, 32)] public int maxTasks; - // C# ext - [HideInInspector] public int width; - [HideInInspector] public int height; - [HideInInspector] public int channels; - - internal static fcExrConfig default_value - { - get - { - return new fcExrConfig - { - pixelFormat = fcExrPixelFormat.Auto, - compression = fcExrCompression.Zip, - maxTasks = 2, - }; - } - } - }; - - internal struct fcExrContext - { - public IntPtr ptr; - public void Release() { fcReleaseContext(ptr); ptr = IntPtr.Zero; } - public static implicit operator bool(fcExrContext v) { return v.ptr != IntPtr.Zero; } - } - - [DllImport("fccore")] internal static extern Bool fcExrIsSupported(); - [DllImport("fccore")] internal static extern fcExrContext fcExrCreateContext(ref fcExrConfig conf); - [DllImport("fccore")] internal static extern Bool fcExrBeginImage(fcExrContext ctx, string path, int width, int height); - [DllImport("fccore")] internal static extern Bool fcExrAddLayerPixels(fcExrContext ctx, byte[] pixels, fcPixelFormat fmt, int ch, string name); - [DllImport("fccore")] internal static extern Bool fcExrEndImage(fcExrContext ctx); - - - // ------------------------------------------------------------- - // GIF Exporter - // ------------------------------------------------------------- - - [Serializable] - internal struct fcGifConfig - { - [HideInInspector] public int width; - [HideInInspector] public int height; - [Range(1, 256)] - [Tooltip("The number of colors used in the GIF palette.")] - public int numColors; - [Range(1, 120)] - [Tooltip("The number of successive frames that share the same color palette.")] - public int keyframeInterval; - [Range(1, 32)] - [Tooltip("The maximum number of frames to encode in parallel.")] - public int maxTasks; - - internal static fcGifConfig default_value - { - get - { - return new fcGifConfig - { - numColors = 256, - maxTasks = 8, - keyframeInterval = 30, - }; - } - } - }; - internal struct fcGifContext - { - public IntPtr ptr; - public void Release() { fcReleaseContext(ptr); ptr = IntPtr.Zero; } - public static implicit operator bool(fcGifContext v) { return v.ptr != IntPtr.Zero; } - } - - [DllImport("fccore")] internal static extern Bool fcGifIsSupported(); - [DllImport("fccore")] internal static extern fcGifContext fcGifCreateContext(ref fcGifConfig conf); - [DllImport("fccore")] internal static extern void fcGifAddOutputStream(fcGifContext ctx, fcStream stream); - [DllImport("fccore")] internal static extern Bool fcGifAddFramePixels(fcGifContext ctx, byte[] pixels, fcPixelFormat fmt, double timestamp = -1.0); - - - // ------------------------------------------------------------- - // MP4 Exporter - // ------------------------------------------------------------- - - internal enum fcMP4VideoFlags - { - H264NVIDIA = 1 << 1, - H264AMD = 1 << 2, - H264IntelHW = 1 << 3, - H264IntelSW = 1 << 4, - H264OpenH264 = 1 << 5, - H264Mask = H264NVIDIA | H264AMD | H264IntelHW | H264IntelSW | H264OpenH264, - }; - - internal enum fcMP4AudioFlags - { - AACIntel = 1 << 1, - AACFAAC = 1 << 2, - AACMask = AACIntel | AACFAAC, - }; - - [Serializable] - internal struct fcMP4Config - { - [HideInInspector] public Bool video; - [HideInInspector] public int videoWidth; - [HideInInspector] public int videoHeight; - [HideInInspector] public int videoTargetFramerate; - public fcBitrateMode videoBitrateMode; - public int videoTargetBitrate; - [HideInInspector] public int videoFlags; - [Range(1, 32)] public int videoMaxTasks; - - [HideInInspector] public Bool audio; - [HideInInspector] public int audioSampleRate; - [HideInInspector] public int audioNumChannels; - public fcBitrateMode audioBitrateMode; - public int audioTargetBitrate; - [HideInInspector] public int audioFlags; - [Range(1, 32)] public int audioMaxTasks; - - internal static fcMP4Config default_value - { - get - { - return new fcMP4Config - { - video = true, - videoBitrateMode = fcBitrateMode.VBR, - videoTargetBitrate = 1024 * 1000, - videoTargetFramerate = 30, - videoFlags = (int)fcMP4VideoFlags.H264Mask, - videoMaxTasks = 4, - - audio = true, - audioSampleRate = 48000, - audioNumChannels = 2, - audioBitrateMode = fcBitrateMode.VBR, - audioTargetBitrate = 128 * 1000, - audioFlags = (int)fcMP4AudioFlags.AACMask, - audioMaxTasks = 4, - }; - } - } - }; - internal struct fcMP4Context - { - public IntPtr ptr; - public void Release() { fcReleaseContext(ptr); ptr = IntPtr.Zero; } - public static implicit operator bool(fcMP4Context v) { return v.ptr != IntPtr.Zero; } - } - - [DllImport("fccore")] internal static extern Bool fcMP4OSIsSupported(); - [DllImport("fccore")] internal static extern fcMP4Context fcMP4OSCreateContext(ref fcMP4Config conf, string path); - [DllImport("fccore")] internal static extern Bool fcMP4AddVideoFramePixels(fcMP4Context ctx, byte[] pixels, fcPixelFormat fmt, double timestamp = -1.0); - [DllImport("fccore")] internal static extern Bool fcMP4AddAudioSamples(fcMP4Context ctx, float[] samples, int num_samples); - - - // ------------------------------------------------------------- - // WebM Exporter - // ------------------------------------------------------------- - - internal struct fcWebMContext - { - public IntPtr ptr; - public void Release() { fcReleaseContext(ptr); ptr = IntPtr.Zero; } - public static implicit operator bool(fcWebMContext v) { return v.ptr != IntPtr.Zero; } - } - - internal enum fcWebMVideoEncoder - { - VP8, - VP9, - VP9LossLess, - }; - internal enum fcWebMAudioEncoder - { - Vorbis, - Opus, - }; - - [Serializable] - internal struct fcWebMConfig - { - [HideInInspector] public Bool video; - public fcWebMVideoEncoder videoEncoder; - [HideInInspector] public int videoWidth; - [HideInInspector] public int videoHeight; - [HideInInspector] public int videoTargetFramerate; - public fcBitrateMode videoBitrateMode; - public int videoTargetBitrate; - [Range(1, 32)] public int videoMaxTasks; - - [HideInInspector] public Bool audio; - public fcWebMAudioEncoder audioEncoder; - [HideInInspector] public int audioSampleRate; - [HideInInspector] public int audioNumChannels; - public fcBitrateMode audioBitrateMode; - public int audioTargetBitrate; - [Range(1, 32)] public int audioMaxTasks; - - internal static fcWebMConfig default_value - { - get - { - return new fcWebMConfig - { - video = true, - videoEncoder = fcWebMVideoEncoder.VP8, - videoTargetFramerate = 60, - videoBitrateMode = fcBitrateMode.VBR, - videoTargetBitrate = 1024 * 1000, - videoMaxTasks = 4, - - audio = true, - audioEncoder = fcWebMAudioEncoder.Vorbis, - audioSampleRate = 48000, - audioNumChannels = 2, - audioBitrateMode = fcBitrateMode.VBR, - audioTargetBitrate = 128 * 1000, - audioMaxTasks = 4, - }; - } - } - } - - [DllImport("fccore")] internal static extern Bool fcWebMIsSupported(); - [DllImport("fccore")] internal static extern fcWebMContext fcWebMCreateContext(ref fcWebMConfig conf); - [DllImport("fccore")] internal static extern void fcWebMAddOutputStream(fcWebMContext ctx, fcStream stream); - // timestamp=-1 is treated as current time. - [DllImport("fccore")] internal static extern Bool fcWebMAddVideoFramePixels(fcWebMContext ctx, byte[] pixels, fcPixelFormat fmt, double timestamp = -1.0); - // timestamp=-1 is treated as current time. - [DllImport("fccore")] internal static extern Bool fcWebMAddAudioSamples(fcWebMContext ctx, float[] samples, int num_samples); - - - // ------------------------------------------------------------- - // Wave Exporter - // ------------------------------------------------------------- - - [Serializable] - internal struct fcWaveConfig - { - [HideInInspector] public int sampleRate; - [HideInInspector] public int numChannels; - public fcAudioBitsPerSample bitsPerSample; - [Range(1, 32)] public int maxTasks; - - internal static fcWaveConfig default_value - { - get - { - return new fcWaveConfig - { - sampleRate = 48000, - numChannels = 2, - bitsPerSample = fcAudioBitsPerSample._16Bits, - maxTasks = 2, - }; - } - } - } - - // ------------------------------------------------------------- - // Ogg Exporter - // ------------------------------------------------------------- - - [Serializable] - internal struct fcOggConfig - { - [HideInInspector] public int sampleRate; - [HideInInspector] public int numChannels; - public fcBitrateMode bitrateMode; - public int targetBitrate; - [Range(1, 32)] public int maxTasks; - - internal static fcOggConfig default_value - { - get - { - return new fcOggConfig - { - sampleRate = 48000, - numChannels = 2, - bitrateMode = fcBitrateMode.VBR, - targetBitrate = 128 * 1000, - maxTasks = 2, - }; - } - } - } - - // ------------------------------------------------------------- - // Flac Exporter - // ------------------------------------------------------------- - - [Serializable] - internal struct fcFlacConfig - { -#pragma warning disable CS0649 - [HideInInspector] public int sampleRate; - [HideInInspector] public int numChannels; - public fcAudioBitsPerSample bitsPerSample; - [Range(0, 9)] public int compressionLevel; - public int blockSize; - [HideInInspector] public Bool verify; - [Range(1, 32)] public int maxTasks; -#pragma warning restore CS0649 - } - - internal static void fcLock(RenderTexture src, TextureFormat dstfmt, Action body) - { - var tex = new Texture2D(src.width, src.height, dstfmt, false); - RenderTexture.active = src; - tex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0, false); - tex.Apply(); - body(tex.GetRawTextureData(), fcGetPixelFormat(tex.format)); - UnityEngine.Object.Destroy(tex); - } - - internal static void fcLock(RenderTexture src, Action body) - { - TextureFormat dstfmt = TextureFormat.RGBA32; - switch (src.format) - { - case RenderTextureFormat.DefaultHDR: - case RenderTextureFormat.ARGB2101010: - case RenderTextureFormat.RGB111110Float: - case RenderTextureFormat.ARGBHalf: - case RenderTextureFormat.RGHalf: - case RenderTextureFormat.Depth: - case RenderTextureFormat.Shadowmap: - case RenderTextureFormat.RHalf: dstfmt = TextureFormat.RGBAHalf; break; - case RenderTextureFormat.ARGBFloat: - case RenderTextureFormat.RGFloat: - case RenderTextureFormat.RFloat: dstfmt = TextureFormat.RGBAFloat; break; - } - fcLock(src, dstfmt, body); - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/fcAPI.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/fcAPI.cs.meta deleted file mode 100644 index 11e6a79..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Encoder/fcAPI.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d6913dd8876ab8149ac67f69aba208ac -timeCreated: 1432919907 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc.meta deleted file mode 100644 index 1b3be1a..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 324c02e09f53928429e39bbbd971fa1c -folderAsset: yes -timeCreated: 1457073395 -licenseType: Store -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/Bool.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/Bool.cs deleted file mode 100644 index 69ec7d5..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/Bool.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using UnityEngine; - -namespace UnityEditor.Recorder.FrameCapturer -{ - // bool is marshal as int (4 byte) by default and you need ugly [MarshalAs(UnmanagedType.U1)] to pass to (or receive from) C++ code. - // this struct emulates bool and marshal as byte (1 byte). this makes things bit easier in some cases. - [Serializable] - struct Bool - { - [SerializeField] byte v; - public static implicit operator bool(Bool v) { return v.v != 0; } - public static implicit operator Bool(bool v) { Bool r; r.v = v ? (byte)1 : (byte)0; return r; } - - public static Bool True { get { Bool r; r.v = 1; return r; } } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/Bool.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/Bool.cs.meta deleted file mode 100644 index 72f9adf..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/Bool.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: e74a0ade798956d49a6bbb833422663e -timeCreated: 1457112037 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/BoolDrawer.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/BoolDrawer.cs deleted file mode 100644 index c8c4f97..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/BoolDrawer.cs +++ /dev/null @@ -1,30 +0,0 @@ -using UnityEngine; - -namespace UnityEditor.Recorder.FrameCapturer -{ - [CustomPropertyDrawer(typeof(Bool))] - class BoolDrawer : PropertyDrawer - { - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - { - EditorGUI.BeginProperty(position, label, property); - position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); - - var indent = EditorGUI.indentLevel; - EditorGUI.indentLevel = 0; - - var p = property.FindPropertyRelative("v"); - bool value = p.intValue != 0; - - EditorGUI.BeginChangeCheck(); - value = EditorGUI.Toggle(position, value); - if (EditorGUI.EndChangeCheck()) - { - p.intValue = value ? 1 : 0; - } - - EditorGUI.indentLevel = indent; - EditorGUI.EndProperty(); - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/BoolDrawer.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/BoolDrawer.cs.meta deleted file mode 100644 index f648ed7..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/BoolDrawer.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a7234308adeab3d419817de7e29c50f1 -timeCreated: 1494004664 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPath.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPath.cs deleted file mode 100644 index 768c303..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPath.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using UnityEngine; - - -namespace UnityEditor.Recorder.FrameCapturer -{ - [Serializable] - class DataPath - { - public enum Root - { - Absolute, - Current, - PersistentData, - StreamingAssets, - TemporaryCache, - DataPath, - } - - [SerializeField] Root m_root = Root.Current; - [SerializeField] string m_leaf = string.Empty; - [SerializeField] bool m_readOnly = false; // just for inspector - - public Root root - { - get { return m_root; } - set { m_root = value; } - } - public string leaf - { - get { return m_leaf; } - set { m_leaf = value; } - } - public bool readOnly - { - get { return m_readOnly; } - set { m_readOnly = value; } - } - - public DataPath() {} - public DataPath(Root root, string leaf) - { - m_root = root; - m_leaf = leaf; - } - - public DataPath(string path) - { - if (path.Contains(Application.streamingAssetsPath)) - { - m_root = Root.StreamingAssets; - m_leaf = path.Replace(Application.streamingAssetsPath, "").TrimStart('/'); - } - else if (path.Contains(Application.dataPath)) - { - m_root = Root.DataPath; - m_leaf = path.Replace(Application.dataPath, "").TrimStart('/'); - } - else if (path.Contains(Application.persistentDataPath)) - { - m_root = Root.PersistentData; - m_leaf = path.Replace(Application.persistentDataPath, "").TrimStart('/'); - } - else if (path.Contains(Application.temporaryCachePath)) - { - m_root = Root.TemporaryCache; - m_leaf = path.Replace(Application.temporaryCachePath, "").TrimStart('/'); - } - else - { - var cur = System.IO.Directory.GetCurrentDirectory().Replace("\\", "/"); - if (path.Contains(cur)) - { - m_root = Root.Current; - m_leaf = path.Replace(cur, "").TrimStart('/'); - } - else - { - m_root = Root.Absolute; - m_leaf = path; - } - } - } - - public string GetFullPath() - { - if (m_root == Root.Absolute) - { - return m_leaf; - } - if (m_root == Root.Current) - { - return m_leaf.Length == 0 ? "." : "./" + m_leaf; - } - - string ret = ""; - switch (m_root) - { - case Root.PersistentData: - ret = Application.persistentDataPath; - break; - case Root.StreamingAssets: - ret = Application.streamingAssetsPath; - break; - case Root.TemporaryCache: - ret = Application.temporaryCachePath; - break; - case Root.DataPath: - ret = Application.dataPath; - break; - } - - if (!m_leaf.StartsWith("/")) - { - ret += "/"; - } - ret += m_leaf; - return ret; - } - - public void CreateDirectory() - { - try - { - var path = GetFullPath(); - if (path.Length > 0) - { - System.IO.Directory.CreateDirectory(path); - } - } - catch (Exception) - { - } - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPath.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPath.cs.meta deleted file mode 100644 index ed4d4ab..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPath.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 0fd1bcdf4e762654da9323b7b37cfecb -timeCreated: 1457112037 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPathDrawer.cs b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPathDrawer.cs deleted file mode 100644 index 38b656c..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPathDrawer.cs +++ /dev/null @@ -1,48 +0,0 @@ -using UnityEngine; - -namespace UnityEditor.Recorder.FrameCapturer -{ - [CustomPropertyDrawer(typeof(DataPath))] - class DataPathDrawer : PropertyDrawer - { - public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - { - bool ro = property.FindPropertyRelative("m_readOnly").boolValue; - if (ro) { EditorGUI.BeginDisabledGroup(true); } - - EditorGUI.BeginProperty(position, label, property); - position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); - - var indent = EditorGUI.indentLevel; - EditorGUI.indentLevel = 0; - - float buttonWidth = 22; - float rootWidth = 70; - float leafWidth = position.width - rootWidth - 5 - buttonWidth; - var rootRect = new Rect(position.x, position.y, rootWidth, position.height); - var leafRect = new Rect(position.x + rootWidth + 5, position.y, leafWidth, position.height); - var buttonRect = new Rect(position.x + rootWidth + 5 + leafWidth, position.y, buttonWidth, position.height); - - var pRoot = property.FindPropertyRelative("m_root"); - var pLeaf = property.FindPropertyRelative("m_leaf"); - EditorGUI.PropertyField(rootRect, pRoot, GUIContent.none); - EditorGUI.PropertyField(leafRect, pLeaf, GUIContent.none); - if (GUI.Button(buttonRect, "...")) - { - var tmp = new DataPath((DataPath.Root)pRoot.intValue, pLeaf.stringValue); - var path = EditorUtility.OpenFolderPanel("Select Directory", tmp.GetFullPath(), ""); - if (path.Length > 0) - { - var newPath = new DataPath(path); - pRoot.intValue = (int)newPath.root; - pLeaf.stringValue = newPath.leaf; - } - } - - EditorGUI.indentLevel = indent; - EditorGUI.EndProperty(); - - if (ro) { EditorGUI.EndDisabledGroup(); } - } - } -} diff --git a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPathDrawer.cs.meta b/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPathDrawer.cs.meta deleted file mode 100644 index eb219ed..0000000 --- a/Editor/Sources/Recorders/_Legacy/FrameCapturer/Scripts/Misc/DataPathDrawer.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: a2c8844522598244c853bbfcb74cf8ac -timeCreated: 1494004664 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Sources/Recorders/_Legacy/MP4/MP4Recorder.cs b/Editor/Sources/Recorders/_Legacy/MP4/MP4Recorder.cs index 1971034..b36bfb0 100644 --- a/Editor/Sources/Recorders/_Legacy/MP4/MP4Recorder.cs +++ b/Editor/Sources/Recorders/_Legacy/MP4/MP4Recorder.cs @@ -5,57 +5,8 @@ namespace UnityEditor.Recorder.FrameCapturer { class MP4Recorder : GenericRecorder { - fcAPI.fcMP4Context m_ctx; - - protected internal override bool BeginRecording(RecordingSession session) - { - if (!base.BeginRecording(session)) { return false; } - - Settings.fileNameGenerator.CreateDirectory(session); - - var input = (BaseRenderTextureInput)m_Inputs[0]; - if (input.OutputWidth > 4096 || input.OutputHeight > 2160) - { - Debug.LogError("Mp4 format does not support resolutions larger than 4096x2160."); - } - - return true; - } - - protected internal override void EndRecording(RecordingSession session) - { - m_ctx.Release(); - base.EndRecording(session); - } - protected internal override void RecordFrame(RecordingSession session) { - if (m_Inputs.Count != 1) - throw new Exception("Unsupported number of sources"); - - var input = (BaseRenderTextureInput)m_Inputs[0]; - var frame = input.OutputRenderTexture; - - if (!m_ctx) - { - var s = Settings.m_MP4EncoderSettings; - s.video = true; - s.audio = false; - s.videoWidth = frame.width; - s.videoHeight = frame.height; - s.videoTargetFramerate = (int)Math.Ceiling(Settings.FrameRate); - if (Settings.m_AutoSelectBR) - { - s.videoTargetBitrate = (int)(((frame.width * frame.height / 1000.0) / 245 + 1.16) * (s.videoTargetFramerate / 48.0 + 0.5) * 1000000); - } - var path = Settings.fileNameGenerator.BuildAbsolutePath(session); - m_ctx = fcAPI.fcMP4OSCreateContext(ref s, path); - } - - fcAPI.fcLock(frame, TextureFormat.RGB24, (data, fmt) => - { - fcAPI.fcMP4AddVideoFramePixels(m_ctx, data, fmt, session.recorderTime); - }); } } } diff --git a/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettings.cs b/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettings.cs index d815e8d..5e2b459 100644 --- a/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettings.cs +++ b/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettings.cs @@ -2,28 +2,11 @@ namespace UnityEditor.Recorder.FrameCapturer { - [RecorderSettings(typeof(MP4Recorder), "Legacy/MP4")] + [RecorderSettings(typeof(MP4Recorder), "Legacy/MP4", true)] +#pragma warning disable 618 class MP4RecorderSettings : BaseFCRecorderSettings { - public fcAPI.fcMP4Config m_MP4EncoderSettings = fcAPI.fcMP4Config.default_value; - public bool m_AutoSelectBR; - - public MP4RecorderSettings() - { - fileNameGenerator.FileName = "movie"; - m_AutoSelectBR = true; - - m_ImageInputSelector.cameraInputSettings.maxSupportedSize = ImageHeight.x2160p_4K; - } - - public override bool IsPlatformSupported - { - get - { - return Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer; - } - } - +#pragma warning restore 618 protected internal override string Extension { get { return "mp4"; } diff --git a/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettingsEditor.cs b/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettingsEditor.cs index 998c70e..cbc5fdc 100644 --- a/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettingsEditor.cs +++ b/Editor/Sources/Recorders/_Legacy/MP4/MP4RecorderSettingsEditor.cs @@ -5,34 +5,9 @@ namespace UnityEditor.Recorder.FrameCapturer [CustomEditor(typeof(MP4RecorderSettings))] class MP4RecorderSettingsEditor : RecorderEditor { - SerializedProperty m_VideoBitRateMode; - SerializedProperty m_VideoBitRate; - SerializedProperty m_VideoMaxTasks; - SerializedProperty m_AutoSelectBR; - - protected override void OnEnable() - { - base.OnEnable(); - - if (target == null) - return; - - var pf = new PropertyFinder(serializedObject); - var encoding = pf.Find(w => w.m_MP4EncoderSettings); - var settings = target as MP4RecorderSettings; - m_VideoBitRateMode = encoding.FindPropertyRelative(() => settings.m_MP4EncoderSettings.videoBitrateMode); - m_VideoBitRate = encoding.FindPropertyRelative(() => settings.m_MP4EncoderSettings.videoTargetBitrate); - m_VideoMaxTasks = encoding.FindPropertyRelative(() => settings.m_MP4EncoderSettings.videoMaxTasks); - m_AutoSelectBR = pf.Find(w => w.m_AutoSelectBR); - } - - protected override void OnEncodingGui() + public override void OnInspectorGUI() { - EditorGUILayout.PropertyField(m_VideoBitRateMode, new GUIContent("Bitrate mode"), true); - EditorGUILayout.PropertyField(m_AutoSelectBR, new GUIContent("Autoselect bitrate"), true); - using (new EditorGUI.DisabledScope(m_AutoSelectBR.boolValue)) - EditorGUILayout.PropertyField(m_VideoBitRate, new GUIContent("Bitrate (bps)"), true); - EditorGUILayout.PropertyField(m_VideoMaxTasks, new GUIContent("Max tasks"), true); + EditorGUILayout.LabelField("The selected legacy MP4 recorder has been deprecated."); } } } diff --git a/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorder.cs b/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorder.cs index f9373eb..eb0bc8c 100644 --- a/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorder.cs +++ b/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorder.cs @@ -4,37 +4,8 @@ namespace UnityEditor.Recorder.FrameCapturer { class PNGRecorder : GenericRecorder { - fcAPI.fcPngContext m_ctx; - - protected internal override bool BeginRecording(RecordingSession session) - { - if (!base.BeginRecording(session)) { return false; } - - Settings.fileNameGenerator.CreateDirectory(session); - - m_ctx = fcAPI.fcPngCreateContext(ref Settings.m_PngEncoderSettings); - return m_ctx; - } - - protected internal override void EndRecording(RecordingSession session) - { - m_ctx.Release(); - base.EndRecording(session); - } - protected internal override void RecordFrame(RecordingSession session) { - if (m_Inputs.Count != 1) - throw new Exception("Unsupported number of sources"); - - var input = (BaseRenderTextureInput)m_Inputs[0]; - var frame = input.OutputRenderTexture; - var path = Settings.fileNameGenerator.BuildAbsolutePath(session); - - fcAPI.fcLock(frame, (data, fmt) => - { - fcAPI.fcPngExportPixels(m_ctx, path, data, frame.width, frame.height, fmt, 0); - }); } } } diff --git a/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettings.cs b/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettings.cs index e6c7cb5..a43090a 100644 --- a/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettings.cs +++ b/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettings.cs @@ -1,15 +1,10 @@ namespace UnityEditor.Recorder.FrameCapturer { - [RecorderSettings(typeof(PNGRecorder), "Legacy/PNG")] + [RecorderSettings(typeof(PNGRecorder), "Legacy/PNG", true)] +#pragma warning disable 618 class PNGRecorderSettings : BaseFCRecorderSettings { - public fcAPI.fcPngConfig m_PngEncoderSettings = fcAPI.fcPngConfig.default_value; - - public PNGRecorderSettings() - { - fileNameGenerator.FileName = "image_" + DefaultWildcard.Frame; - } - +#pragma warning restore 618 protected internal override string Extension { get { return "png"; } diff --git a/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettingsEditor.cs b/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettingsEditor.cs index b74b4c6..b292916 100644 --- a/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettingsEditor.cs +++ b/Editor/Sources/Recorders/_Legacy/PNG/PNGRecorderSettingsEditor.cs @@ -5,9 +5,9 @@ namespace UnityEditor.Recorder.FrameCapturer [CustomEditor(typeof(PNGRecorderSettings))] class PNGRecorderSettingsEditor : RecorderEditor { - protected override void OnEncodingGui() + public override void OnInspectorGUI() { - EditorGUILayout.PropertyField(serializedObject.FindProperty("m_PngEncoderSettings"), new GUIContent("Encoding"), true); + EditorGUILayout.LabelField("The selected legacy PNG recorder has been deprecated."); } } } diff --git a/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorder.cs b/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorder.cs index 9ba507d..c8bd67b 100644 --- a/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorder.cs +++ b/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorder.cs @@ -5,56 +5,8 @@ namespace UnityEditor.Recorder.FrameCapturer { class WEBMRecorder : GenericRecorder { - fcAPI.fcWebMContext m_ctx; - fcAPI.fcStream m_stream; - - protected internal override bool BeginRecording(RecordingSession session) - { - if (!base.BeginRecording(session)) { return false; } - - Settings.fileNameGenerator.CreateDirectory(session); - - return true; - } - - protected internal override void EndRecording(RecordingSession session) - { - m_ctx.Release(); - m_stream.Release(); - base.EndRecording(session); - } - protected internal override void RecordFrame(RecordingSession session) { - if (m_Inputs.Count != 1) - throw new Exception("Unsupported number of sources"); - - var input = (BaseRenderTextureInput)m_Inputs[0]; - var frame = input.OutputRenderTexture; - - if (!m_ctx) - { - var webmSettings = Settings.m_WebmEncoderSettings; - webmSettings.video = true; - webmSettings.audio = false; - webmSettings.videoWidth = frame.width; - webmSettings.videoHeight = frame.height; - if (Settings.m_AutoSelectBR) - { - webmSettings.videoTargetBitrate = (int)(((frame.width * frame.height / 1000.0) / 245 + 1.16) * (webmSettings.videoTargetFramerate / 48.0 + 0.5) * 1000000); - } - - webmSettings.videoTargetFramerate = (int)Math.Ceiling(Settings.FrameRate); - m_ctx = fcAPI.fcWebMCreateContext(ref webmSettings); - var path = Settings.fileNameGenerator.BuildAbsolutePath(session); - m_stream = fcAPI.fcCreateFileStream(path); - fcAPI.fcWebMAddOutputStream(m_ctx, m_stream); - } - - fcAPI.fcLock(frame, TextureFormat.RGB24, (data, fmt) => - { - fcAPI.fcWebMAddVideoFramePixels(m_ctx, data, fmt, session.recorderTime); - }); } } } diff --git a/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettings.cs b/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettings.cs index 21b8636..6942020 100644 --- a/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettings.cs +++ b/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettings.cs @@ -1,17 +1,10 @@ namespace UnityEditor.Recorder.FrameCapturer { - [RecorderSettings(typeof(WEBMRecorder), "Legacy/WebM")] + [RecorderSettings(typeof(WEBMRecorder), "Legacy/WebM", true)] +#pragma warning disable 618 class WEBMRecorderSettings : BaseFCRecorderSettings { - public fcAPI.fcWebMConfig m_WebmEncoderSettings = fcAPI.fcWebMConfig.default_value; - public bool m_AutoSelectBR; - - public WEBMRecorderSettings() - { - fileNameGenerator.FileName = "movie"; - m_AutoSelectBR = true; - } - +#pragma warning restore 618 protected internal override string Extension { get { return "webm"; } diff --git a/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettingsEditor.cs b/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettingsEditor.cs index cb1ce67..6f2b08d 100644 --- a/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettingsEditor.cs +++ b/Editor/Sources/Recorders/_Legacy/WEBM/WEBMRecorderSettingsEditor.cs @@ -5,39 +5,9 @@ namespace UnityEditor.Recorder.FrameCapturer [CustomEditor(typeof(WEBMRecorderSettings))] class WEBMRecorderSettingsEditor : RecorderEditor { - SerializedProperty m_VideoEncoder; - SerializedProperty m_VideoBitRateMode; - SerializedProperty m_VideoBitRate; - SerializedProperty m_VideoMaxTasks; - SerializedProperty m_AutoSelectBR; - - protected override void OnEnable() - { - base.OnEnable(); - - if (target == null) - return; - - var pf = new PropertyFinder(serializedObject); - var encoding = pf.Find(w => w.m_WebmEncoderSettings); - var settings = target as WEBMRecorderSettings; - m_VideoBitRateMode = encoding.FindPropertyRelative(() => settings.m_WebmEncoderSettings.videoBitrateMode); - m_VideoBitRate = encoding.FindPropertyRelative(() => settings.m_WebmEncoderSettings.videoTargetBitrate); - m_VideoMaxTasks = encoding.FindPropertyRelative(() => settings.m_WebmEncoderSettings.videoMaxTasks); - m_VideoEncoder = encoding.FindPropertyRelative(() => settings.m_WebmEncoderSettings.videoEncoder); - m_AutoSelectBR = pf.Find(w => w.m_AutoSelectBR); - } - - protected override void OnEncodingGui() + public override void OnInspectorGUI() { - EditorGUILayout.PropertyField(m_VideoEncoder, new GUIContent("Encoder"), true); - EditorGUILayout.PropertyField(m_VideoBitRateMode, new GUIContent("Bitrate mode"), true); - EditorGUILayout.PropertyField(m_AutoSelectBR, new GUIContent("Autoselect bitrate"), true); - - using (new EditorGUI.DisabledScope(m_AutoSelectBR.boolValue)) - EditorGUILayout.PropertyField(m_VideoBitRate, new GUIContent("Bitrate (bps)"), true); - - EditorGUILayout.PropertyField(m_VideoMaxTasks, new GUIContent("Max tasks"), true); + EditorGUILayout.LabelField("The selected legacy WEBM recorder has been deprecated."); } } } diff --git a/Editor/Sources/RecordersInventory.cs b/Editor/Sources/RecordersInventory.cs index 8d2a2b8..394a10e 100644 --- a/Editor/Sources/RecordersInventory.cs +++ b/Editor/Sources/RecordersInventory.cs @@ -15,6 +15,7 @@ class RecorderInfo public Type settingsType; public string displayName; public string iconName; + public bool deprecated; } static class RecordersInventory @@ -70,7 +71,8 @@ static void Init() settingsType = settingsType, recorderType = settingsAttrib.recorderType, displayName = settingsAttrib.displayName, - iconName = settingsAttrib.iconName + iconName = settingsAttrib.iconName, + deprecated = settingsAttrib.deprecated }; s_Recorders.Add(settingsType, info); @@ -87,7 +89,6 @@ static void Init() s_Recorders[typeof(AnimationRecorderSettings)], s_Recorders[typeof(MovieRecorderSettings)], s_Recorders[typeof(ImageRecorderSettings)], - s_Recorders[typeof(GIFRecorderSettings)], #if HDRP_AVAILABLE s_Recorders[typeof(AOVRecorderSettings)], #endif @@ -99,6 +100,9 @@ static void Init() { s_LegacyRecorderInfos = new HashSet { +#pragma warning disable 618 + s_Recorders[typeof(GIFRecorderSettings)], +#pragma warning restore 618 s_Recorders[typeof(MP4RecorderSettings)], s_Recorders[typeof(EXRRecorderSettings)], s_Recorders[typeof(PNGRecorderSettings)], @@ -146,7 +150,8 @@ internal static IEnumerable customRecorderInfos return custom; #else // Remove AOV Recorder from list of custom because it will be inserted in the above catch-all other logic - return custom.Where(c => c.recorderType != typeof(AOVRecorder)); + var result = custom.Where(c => c.recorderType != typeof(AOVRecorder)); + return result; #endif } } diff --git a/Editor/Sources/RecordingSession.cs b/Editor/Sources/RecordingSession.cs index e368d20..81f726e 100644 --- a/Editor/Sources/RecordingSession.cs +++ b/Editor/Sources/RecordingSession.cs @@ -122,8 +122,10 @@ internal bool BeginRecording() recordingStartTS = (Time.time / (Mathf.Approximately(Time.timeScale, 0f) ? 1f : Time.timeScale)); recorder.SignalInputsOfStage(ERecordingSessionStage.BeginRecording, this); + // This must be after the above call otherwise GameView will not be initialized if (!recorder.BeginRecording(this)) return false; + m_InitialFrame = Time.renderedFrameCount; m_FPSTimeStart = Time.unscaledTime; @@ -138,9 +140,6 @@ internal bool BeginRecording() internal void EndRecording() { - if (!isRecording) - return; - try { recorder.SignalInputsOfStage(ERecordingSessionStage.EndRecording, this); diff --git a/Editor/Sources/TargetedPropertyDrawer.cs b/Editor/Sources/TargetedPropertyDrawer.cs index b1be698..dff3c6c 100644 --- a/Editor/Sources/TargetedPropertyDrawer.cs +++ b/Editor/Sources/TargetedPropertyDrawer.cs @@ -8,16 +8,13 @@ class TargetedPropertyDrawer : PropertyDrawer where T : class protected virtual void Initialize(SerializedProperty prop) { - if (target == null) - { - var path = prop.propertyPath.Split('.'); - object obj = prop.serializedObject.targetObject; + var path = prop.propertyPath.Split('.'); + object obj = prop.serializedObject.targetObject; - foreach (var pathNode in path) - obj = GetSerializedField(obj, pathNode).GetValue(obj); + foreach (var pathNode in path) + obj = GetSerializedField(obj, pathNode).GetValue(obj); - target = obj as T; - } + target = obj as T; } static FieldInfo GetSerializedField(object target, string pathNode) diff --git a/Editor/Timeline/RecorderClip.cs b/Editor/Timeline/RecorderClip.cs index fd7d334..bfc1630 100644 --- a/Editor/Timeline/RecorderClip.cs +++ b/Editor/Timeline/RecorderClip.cs @@ -28,7 +28,7 @@ Type recorderType } /// - /// Unity Recorder does not support any clip features. + /// Recorder does not support any clip features. /// For more information see: https://docs.unity3d.com/2018.1/Documentation/ScriptReference/Timeline.ClipCaps.html /// public ClipCaps clipCaps diff --git a/Editor/Timeline/RecorderSelector.cs b/Editor/Timeline/RecorderSelector.cs index c552031..6e5e6e2 100644 --- a/Editor/Timeline/RecorderSelector.cs +++ b/Editor/Timeline/RecorderSelector.cs @@ -22,9 +22,6 @@ public void Init(RecorderSettings settings) { var recorderList = RecordersInventory.builtInRecorderInfos.ToList(); - if (RecorderOptions.ShowLegacyRecorders) - recorderList.AddRange(RecordersInventory.legacyRecorderInfos); - recorderList.AddRange(RecordersInventory.customRecorderInfos); m_RecorderTypes = recorderList.Select(x => x.settingsType).ToList(); @@ -53,7 +50,7 @@ public void OnGui() if (newIndex < 0) { - // For instance a Recorder Clip for an AOV after the HDRP package has been removed + EditorGUILayout.EndHorizontal(); return; } diff --git a/Editor/Unity.Recorder.Editor.api b/Editor/Unity.Recorder.Editor.api index 0f9074f..de29431 100644 --- a/Editor/Unity.Recorder.Editor.api +++ b/Editor/Unity.Recorder.Editor.api @@ -33,8 +33,8 @@ namespace UnityEditor.Recorder public virtual System.Collections.Generic.IEnumerable InputsSettings { get; } public virtual bool IsPlatformSupported { get; } public AnimationRecorderSettings() {} + protected virtual void GetErrors(System.Collections.Generic.List errors); public virtual void OnAfterDuplicate(); - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); } public abstract class BaseRenderTextureInput : UnityEditor.Recorder.RecorderInput @@ -109,13 +109,10 @@ namespace UnityEditor.Recorder protected GenericRecorder() {} } - [UnityEditor.Recorder.RecorderSettings(typeof(UnityEditor.Recorder.GIFRecorder), @"GIF Animation", @"imagesequence_16")] public class GIFRecorderSettings : UnityEditor.Recorder.FrameCapturer.BaseFCRecorderSettings + [System.Obsolete(@"The GIFRecorder is deprecated")] [UnityEditor.Recorder.RecorderSettings(typeof(UnityEditor.Recorder.GIFRecorder), @"GIF Animation", @"imagesequence_16", true)] public class GIFRecorderSettings : UnityEditor.Recorder.FrameCapturer.BaseFCRecorderSettings { protected virtual string Extension { get; } - public int KeyframeInterval { get; set; } - public int MaxTasks { get; set; } - public int NumColors { get; set; } - public GIFRecorderSettings() {} + [System.Obsolete(@"The GIFRecorder is deprecated")] public GIFRecorderSettings() {} } public class ImageInputSelector : UnityEditor.Recorder.InputSettingsSelector @@ -134,14 +131,28 @@ namespace UnityEditor.Recorder public AccumulationSettings AccumulationSettings { get; set; } public bool CaptureAlpha { get; set; } public bool CaptureHDR { get; } + public UnityEditor.Recorder.ImageRecorderSettings.EXRCompressionType EXRCompression { get; set; } protected virtual string Extension { get; } public UnityEditor.Recorder.Input.ImageInputSettings imageInputSettings { get; set; } public virtual System.Collections.Generic.IEnumerable InputsSettings { get; } + public UnityEditor.Recorder.ImageRecorderSettings.ColorSpaceType OutputColorSpace { get; set; } public UnityEditor.Recorder.ImageRecorderSettings.ImageRecorderOutputFormat OutputFormat { get; set; } public ImageRecorderSettings() {} public virtual AccumulationSettings GetAccumulationSettings(); public virtual bool IsAccumulationSupported(); - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + public enum ColorSpaceType + { + public const UnityEditor.Recorder.ImageRecorderSettings.ColorSpaceType sRGB_sRGB = 0; + public const UnityEditor.Recorder.ImageRecorderSettings.ColorSpaceType Unclamped_linear_sRGB = 1; + public int value__; + } + public enum EXRCompressionType + { + public const UnityEditor.Recorder.ImageRecorderSettings.EXRCompressionType None = 0; + public const UnityEditor.Recorder.ImageRecorderSettings.EXRCompressionType RLE = 1; + public int value__; + public const UnityEditor.Recorder.ImageRecorderSettings.EXRCompressionType Zip = 2; + } public enum ImageRecorderOutputFormat { public const UnityEditor.Recorder.ImageRecorderSettings.ImageRecorderOutputFormat EXR = 2; @@ -177,9 +188,10 @@ namespace UnityEditor.Recorder public UnityEditor.VideoBitrateMode VideoBitRateMode { get; set; } public MovieRecorderSettings() {} public virtual AccumulationSettings GetAccumulationSettings(); + protected virtual void GetErrors(System.Collections.Generic.List errors); public void GetPresetsForEncoder(int indexEncoder, out System.Collections.Generic.List presetNames, out System.Collections.Generic.List presetOptions); + protected virtual void GetWarnings(System.Collections.Generic.List warnings); public virtual bool IsAccumulationSupported(); - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); public enum VideoRecorderOutputFormat { public const UnityEditor.Recorder.MovieRecorderSettings.VideoRecorderOutputFormat MOV = 2; @@ -211,6 +223,7 @@ namespace UnityEditor.Recorder public bool Recording { get; protected set; } protected Recorder() {} protected virtual bool BeginRecording(UnityEditor.Recorder.RecordingSession session); + protected void ConsoleLogMessage(string message, UnityEngine.LogType logType); protected virtual void EndRecording(UnityEditor.Recorder.RecordingSession session); protected virtual void PrepareNewFrame(UnityEditor.Recorder.RecordingSession ctx); protected abstract void RecordFrame(UnityEditor.Recorder.RecordingSession ctx); @@ -290,12 +303,13 @@ namespace UnityEditor.Recorder { protected abstract System.Type InputType { get; } protected RecorderInputSettings() {} - protected abstract bool ValidityCheck(System.Collections.Generic.List errors); + protected virtual void CheckForErrors(System.Collections.Generic.List errors); + protected virtual void CheckForWarnings(System.Collections.Generic.List warnings); + [System.Obsolete(@"Please use methods CheckForErrors() and CheckForWarnings()")] protected virtual bool ValidityCheck(System.Collections.Generic.List errors); } public static class RecorderOptions { - public static bool ShowLegacyRecorders { get; set; } public static bool ShowRecorderGameObject { get; set; } public static bool VerboseMode { get; set; } } @@ -318,16 +332,20 @@ namespace UnityEditor.Recorder public float StartTime { get; set; } public int Take { get; set; } protected RecorderSettings() {} + protected virtual void GetErrors(System.Collections.Generic.List errors); + protected virtual void GetWarnings(System.Collections.Generic.List warnings); protected virtual bool HasErrors(); public virtual bool IsAccumulationSupported(); public virtual void OnAfterDuplicate(); - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + [System.Obsolete(@"Please use methods GetErrors() and GetWarnings()")] protected virtual bool ValidityCheck(System.Collections.Generic.List errors); } [System.AttributeUsage(4, Inherited = false)] public class RecorderSettingsAttribute : System.Attribute { public RecorderSettingsAttribute(System.Type recorderType, string displayName) {} + public RecorderSettingsAttribute(System.Type recorderType, string displayName, bool deprecated) {} public RecorderSettingsAttribute(System.Type recorderType, string displayName, string iconName) {} + public RecorderSettingsAttribute(System.Type recorderType, string displayName, string iconName, bool deprecated) {} } public class RecorderWindow : UnityEditor.EditorWindow @@ -369,11 +387,19 @@ namespace UnityEditor.Recorder namespace UnityEditor.Recorder.AOV { - public enum AOVColorSpaceType + [UnityEditor.Recorder.RecorderSettings(typeof(UnityEditor.Recorder.AOVRecorder), @"AOV Image Sequence", @"aovimagesequence_16")] public class AOVRecorderSettings : UnityEditor.Recorder.RecorderSettings { - public const UnityEditor.Recorder.AOV.AOVColorSpaceType sRGB_sRGB = 0; - public const UnityEditor.Recorder.AOV.AOVColorSpaceType Unclamped_linear_sRGB = 1; - public int value__; + public UnityEditor.Recorder.AOV.AOVType AOVSelection { get; set; } + public bool CaptureHDR { get; } + public UnityEditor.Recorder.ImageRecorderSettings.EXRCompressionType EXRCompression { get; set; } + protected virtual string Extension { get; } + public UnityEditor.Recorder.Input.ImageInputSettings imageInputSettings { get; set; } + public virtual System.Collections.Generic.IEnumerable InputsSettings { get; } + public UnityEditor.Recorder.ImageRecorderSettings.ColorSpaceType OutputColorSpace { get; set; } + public UnityEditor.Recorder.ImageRecorderSettings.ImageRecorderOutputFormat OutputFormat { get; set; } + public AOVRecorderSettings() {} + protected virtual void GetErrors(System.Collections.Generic.List errors); + protected virtual bool HasErrors(); } public enum AOVType @@ -398,14 +424,6 @@ namespace UnityEditor.Recorder.AOV public const UnityEditor.Recorder.AOV.AOVType SpecularLighting = 9; public int value__; } - - public enum EXRCompressionType - { - public const UnityEditor.Recorder.AOV.EXRCompressionType None = 0; - public const UnityEditor.Recorder.AOV.EXRCompressionType RLE = 1; - public int value__; - public const UnityEditor.Recorder.AOV.EXRCompressionType Zip = 2; - } } namespace UnityEditor.Recorder.AOV.Input @@ -419,13 +437,11 @@ namespace UnityEditor.Recorder.AOV.Input namespace UnityEditor.Recorder.FrameCapturer { - public abstract class BaseFCRecorderSettings : UnityEditor.Recorder.RecorderSettings + [System.Obsolete(@"The legacy recorders are deprecated")] public abstract class BaseFCRecorderSettings : UnityEditor.Recorder.RecorderSettings { public UnityEditor.Recorder.Input.ImageInputSettings imageInputSettings { get; set; } public virtual System.Collections.Generic.IEnumerable InputsSettings { get; } - public virtual bool IsPlatformSupported { get; } protected BaseFCRecorderSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); } } @@ -448,9 +464,9 @@ namespace UnityEditor.Recorder.Input public UnityEditor.Recorder.Input.AnimationInputSettings.CurveSimplificationOptions SimplyCurves { get; set; } public AnimationInputSettings() {} public void AddComponentToRecord(System.Type componentType); + protected virtual void CheckForErrors(System.Collections.Generic.List errors); public void ClearExposedReference(); public void DuplicateExposedReference(); - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); public enum CurveSimplificationOptions { public const UnityEditor.Recorder.Input.AnimationInputSettings.CurveSimplificationOptions Disabled = 2; @@ -465,7 +481,6 @@ namespace UnityEditor.Recorder.Input protected virtual System.Type InputType { get; } public bool PreserveAudio { get; set; } public AudioInputSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); } [System.ComponentModel.DisplayName(@"360 View")] public class Camera360InputSettings : UnityEditor.Recorder.Input.ImageInputSettings @@ -480,7 +495,7 @@ namespace UnityEditor.Recorder.Input public UnityEditor.Recorder.ImageSource Source { get; set; } public float StereoSeparation { get; set; } public Camera360InputSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + protected virtual void CheckForErrors(System.Collections.Generic.List errors); } public class CameraInput : UnityEditor.Recorder.BaseRenderTextureInput @@ -501,7 +516,7 @@ namespace UnityEditor.Recorder.Input protected virtual System.Type InputType { get; } public UnityEditor.Recorder.ImageSource Source { get; set; } public CameraInputSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + protected virtual void CheckForErrors(System.Collections.Generic.List errors); } [System.ComponentModel.DisplayName(@"Game View")] public class GameViewInputSettings : UnityEditor.Recorder.Input.StandardImageInputSettings @@ -529,7 +544,7 @@ namespace UnityEditor.Recorder.Input public virtual int OutputWidth { get; set; } public UnityEngine.RenderTexture RenderTexture { get; set; } public RenderTextureInputSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + protected virtual void CheckForErrors(System.Collections.Generic.List errors); } [System.ComponentModel.DisplayName(@"Texture Sampling")] public class RenderTextureSamplerSettings : UnityEditor.Recorder.Input.ImageInputSettings @@ -544,7 +559,7 @@ namespace UnityEditor.Recorder.Input public int RenderWidth { get; set; } public UnityEditor.Recorder.Input.SuperSamplingCount SuperSampling { get; set; } public RenderTextureSamplerSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + protected virtual void CheckForWarnings(System.Collections.Generic.List warnings); } public abstract class StandardImageInputSettings : UnityEditor.Recorder.Input.ImageInputSettings @@ -552,7 +567,8 @@ namespace UnityEditor.Recorder.Input public virtual int OutputHeight { get; set; } public virtual int OutputWidth { get; set; } protected StandardImageInputSettings() {} - protected virtual bool ValidityCheck(System.Collections.Generic.List errors); + protected virtual void CheckForErrors(System.Collections.Generic.List errors); + protected virtual void CheckForWarnings(System.Collections.Generic.List warnings); } public enum SuperSamplingCount diff --git a/LICENSE.md b/LICENSE.md index 83898fb..61b0fa0 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,5 @@ -Unity Recorder copyright © 2020 Unity Technologies ApS +Recorder copyright © 2021 Unity Technologies ApS -Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). +Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions. diff --git a/README.md b/README.md index 8c53b89..6056976 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# UNITY RECORDER +# RECORDER -Use the Unity Recorder to capture and save in-game data during [Play Mode](https://docs.unity3d.com/Manual/GameView.html). For example, use the Unity Recorder to capture and save gameplay as an MP4 file. +Use the Recorder to capture and save in-game data during [Play Mode](https://docs.unity3d.com/Manual/GameView.html). For example, use the Recorder to capture and save gameplay as an MP4 file. -A recorder specifies details for creating a recording, including a data source, resolution, and output format. The Unity Recorder package includes the following recorders: +A recorder specifies details for creating a recording, including a data source, resolution, and output format. The Recorder package includes the following recorders: * __Animation Recorder__: generates an animation clip in ANIM format. @@ -12,4 +12,4 @@ A recorder specifies details for creating a recording, including a data source, * __GIF Recorder__: generates an animated GIF file. -The Unity Recorder also supports [Timeline](https://docs.unity3d.com/Manual/TimelineSection.html). Use Recorder tracks and clips to trigger recording sessions from Timeline instances. +The Recorder also supports [Timeline](https://docs.unity3d.com/Manual/TimelineSection.html). Use Recorder tracks and clips to trigger recording sessions from Timeline instances. diff --git a/Samples~/RecorderEditor/RecorderEditorExample.cs b/Samples~/RecorderEditor/RecorderEditorExample.cs index 63f71ef..4b8da8c 100644 --- a/Samples~/RecorderEditor/RecorderEditorExample.cs +++ b/Samples~/RecorderEditor/RecorderEditorExample.cs @@ -8,17 +8,19 @@ namespace UnityEditor.Recorder.Examples /// public static class RecorderEditorExample { + static readonly string s_WindowTitle = "Recorder"; + [MenuItem(RecorderWindow.MenuRoot + "Examples/Start Recording", false, RecorderWindow.MenuRootIndex + 100)] static void StartRecording() { - var recorderWindow = EditorWindow.GetWindow(); + var recorderWindow = EditorWindow.GetWindow(false, s_WindowTitle); recorderWindow.StartRecording(); } [MenuItem(RecorderWindow.MenuRoot + "Examples/Stop Recording", false, RecorderWindow.MenuRootIndex + 100)] static void StopRecording() { - var recorderWindow = EditorWindow.GetWindow(); + var recorderWindow = EditorWindow.GetWindow(false, s_WindowTitle); recorderWindow.StopRecording(); } } diff --git a/package.json b/package.json index 1905f64..00ea526 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "com.unity.recorder", - "displayName": "Unity Recorder", - "version": "2.6.0-exp.4", + "displayName": "Recorder", + "version": "3.0.0-pre.1", "unity": "2019.4", "unityRelease": "1f1", "dependencies": { "com.unity.timeline": "1.0.0" }, - "description": "The Unity Recorder allows you to capture and save data from the Unity Editor during Play Mode: animations, videos, images, audio, and more.", + "description": "The Recorder allows you to capture and save data from the Unity Editor during Play mode: animations, videos, images, audio, arbitrary output variables (AOVs), and more.", "keywords": [ "unity", "recorder", @@ -23,15 +23,15 @@ "layer" ], "relatedPackages": { - "com.unity.recorder.tests": "2.6.0-exp.4" + "com.unity.recorder.tests": "3.0.0-pre.1" }, "upmCi": { - "footprint": "0a96f4dc26909f265ef46ad6fdb74bde6e623dbe" + "footprint": "2df27a01351b1257811772af197b4424c484641a" }, "repository": { "url": "https://github.cds.internal.unity3d.com/unity/com.unity.recorder.git", "type": "git", - "revision": "d947d3d8f3d1f765057794c28a3be8c915560c83" + "revision": "2701984743dde4c63b0b0273c49efe80748d97a4" }, "samples": [ {