Tips:
需要有Recorder Package引用或存在在项目
using UnityEngine;
using UnityEditor;
using UnityEditor.Recorder;
using UnityEditor.Recorder.Input;
using System.IO;
using System;
public class RecorderWindow : EditorWindow
{
private RecorderController recorderController;
private bool isRecording = false;
private string outputPath = "Recordings";
private string fileName = "Gameplay";
private int resolutionWidth = 1920;
private int resolutionHeight = 1080;
private bool includeAudio = true;
private bool showAdvanced = false;
private int frameRate = 60;
private bool autoTimestamp = true;
private Vector2 scrollPosition;
[MenuItem("Tools/Recorder Control")]
public static void ShowWindow()
{
var window = GetWindow<RecorderWindow>("录制控制");
window.minSize = new Vector2(350, 450);
window.SetupRecorder();
}
private void SetupRecorder()
{
if (recorderController != null) return;
var controllerSettings = ScriptableObject.CreateInstance<RecorderControllerSettings>();
recorderController = new RecorderController(controllerSettings);
}
private void OnGUI()
{
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("录制控制", EditorStyles.boldLabel);
EditorGUILayout.Space(5);
// Recording Status
var status = isRecording ? "录制中" : "准备就绪";
var statusColor = isRecording ? new Color(0.8f, 0.2f, 0.2f) : new Color(0.2f, 0.7f, 0.2f);
var origColor = GUI.color;
GUI.color = statusColor;
EditorGUILayout.LabelField($"状态: {status}", EditorStyles.boldLabel);
GUI.color = origColor;
EditorGUILayout.Space(15);
// Recording Controls
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(isRecording ? "停止录制" : "开始录制", GUILayout.Height(40)))
{
if (isRecording) StopRecording();
else StartRecording();
}
if (GUILayout.Button("打开输出目录", GUILayout.Height(40)))
{
OpenOutputFolder();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space(20);
EditorGUILayout.LabelField("录制设置", EditorStyles.boldLabel);
EditorGUILayout.Space(10);
// Output Settings
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField("输出设置", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
outputPath = EditorGUILayout.TextField("输出路径", outputPath);
if (GUILayout.Button("浏览", GUILayout.Width(60)))
{
outputPath = EditorUtility.SaveFolderPanel("选择输出目录", outputPath, "");
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
fileName = EditorGUILayout.TextField("文件名称", fileName);
autoTimestamp = EditorGUILayout.Toggle("添加时间戳", autoTimestamp, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
// Video Settings
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField("视频设置", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
resolutionWidth = EditorGUILayout.IntField("宽度", resolutionWidth);
resolutionHeight = EditorGUILayout.IntField("高度", resolutionHeight);
EditorGUILayout.EndHorizontal();
frameRate = EditorGUILayout.IntSlider("帧率", frameRate, 1, 120);
includeAudio = EditorGUILayout.Toggle("包含音频", includeAudio);
EditorGUILayout.EndVertical();
// Advanced Settings
showAdvanced = EditorGUILayout.Foldout(showAdvanced, "高级设置", true);
if (showAdvanced)
{
EditorGUILayout.BeginVertical("box");
EditorGUILayout.HelpBox("这些设置用于特殊需求,通常使用默认值即可", MessageType.Info);
EditorGUILayout.Space(5);
if (GUILayout.Button("重置为默认设置"))
{
ResetToDefaults();
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.Space(20);
EditorGUILayout.EndScrollView();
// Footer
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField("快捷键: F9 - 开始/停止录制", EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField("输出目录: " + GetFullOutputPath(), EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.EndVertical();
}
private void StartRecording()
{
SetupRecorder();
var controllerSettings = recorderController.Settings;
controllerSettings.ClearRecorderSettings(); // Clear existing settings
// Create video recorder
var videoRecorder = ScriptableObject.CreateInstance<MovieRecorderSettings>();
videoRecorder.name = "Gameplay Recorder";
videoRecorder.Enabled = true;
// Output settings
videoRecorder.OutputFile = Path.Combine(outputPath, fileName);
if (autoTimestamp)
{
videoRecorder.OutputFile += "_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
}
// Resolution settings
videoRecorder.ImageInputSettings = new GameViewInputSettings
{
OutputWidth = resolutionWidth,
OutputHeight = resolutionHeight
};
// Video format
videoRecorder.VideoBitRateMode = VideoBitrateMode.High;
videoRecorder.OutputFormat = MovieRecorderSettings.VideoRecorderOutputFormat.MP4;
// Audio settings
if (includeAudio)
{
var audioRecorder = ScriptableObject.CreateInstance<AudioRecorderSettings>();
audioRecorder.Enabled = true;
controllerSettings.AddRecorderSettings(audioRecorder);
}
// Frame rate settings
controllerSettings.SetRecordModeToManual();
controllerSettings.FrameRate = frameRate;
// Add video recorder
controllerSettings.AddRecorderSettings(videoRecorder);
// Start recording
recorderController.PrepareRecording();
recorderController.StartRecording();
isRecording = true;
Debug.Log($"录制已开始: {GetFullOutputPath()}.mp4");
}
private void StopRecording()
{
if (recorderController != null)
{
recorderController.StopRecording();
Debug.Log($"录制已停止,文件保存至: {GetFullOutputPath()}.mp4");
}
isRecording = false;
}
private string GetFullOutputPath()
{
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), outputPath, fileName);
if (autoTimestamp)
{
fullPath += "_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
}
return fullPath;
}
private void OpenOutputFolder()
{
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), outputPath);
if (!Directory.Exists(fullPath))
{
Directory.CreateDirectory(fullPath);
}
EditorUtility.RevealInFinder(fullPath);
}
private void ResetToDefaults()
{
outputPath = "Recordings";
fileName = "Gameplay";
resolutionWidth = 1920;
resolutionHeight = 1080;
includeAudio = true;
frameRate = 60;
autoTimestamp = true;
}
private void OnInspectorUpdate()
{
if (isRecording && recorderController != null)
{
Repaint();
}
}
private void Update()
{
// Handle F9 key for recording
if (Event.current != null && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.F9)
{
if (isRecording) StopRecording();
else StartRecording();
Event.current.Use();
}
}
private void OnDestroy()
{
if (isRecording)
{
StopRecording();
}
}
}
