Created
October 8, 2023 06:52
-
-
Save undefined9071/9b9caec1b5597769b0afda6ca03049ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.IO; | |
using System.Linq; | |
using UnityEditor.Animations; | |
using UnityEngine; | |
using UnityEngine.Playables; | |
using UnityEngine.Timeline; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
#endif | |
public class TimelineRecorder : MonoBehaviour { | |
[SerializeField] public PlayableDirector director; | |
[SerializeField] public GameObject rootBone; | |
[HideInInspector] public GameObjectRecorder m_Recorder; | |
// 0.05f : low compression, slow, high quality | |
// 0.1f : high compression, fast, low quality | |
[SerializeField] public float positionError = 0.05f; | |
[SerializeField] public float rotationError = 0.05f; | |
} | |
#if UNITY_EDITOR | |
[CustomEditor(typeof(TimelineRecorder))] | |
[CanEditMultipleObjects] | |
public class TimelineRecorderCustomEditor : Editor { | |
static TimelineRecorder Instance; | |
public override void OnInspectorGUI() { | |
base.OnInspectorGUI(); | |
Instance = target as TimelineRecorder; | |
EditorGUILayout.HelpBox("SHOW THE GAME WINDOW IN THE FOREGROUND", MessageType.Warning, true); | |
EditorGUILayout.Space(10); | |
if (GUILayout.Button("\nRecording\n")) { | |
Instance.StartCoroutine(RecordingTimeline()); | |
} | |
} | |
private IEnumerator RecordingTimeline() { | |
var timelineAsset = Instance.director.playableAsset as TimelineAsset; | |
var clipFrameCount = Mathf.RoundToInt((float) Instance.director.duration * (float) timelineAsset.editorSettings.frameRate); | |
int frame = 0; | |
Instance.director.time = 0; | |
yield return new WaitForSeconds(1); | |
Instance.director.Play(); | |
Instance.director.playableGraph.GetRootPlayable(0).SetSpeed(0); | |
AnimationClip clip = new AnimationClip(); | |
clip.name = Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(timelineAsset)); | |
clip.frameRate = 60; | |
Instance.m_Recorder = new GameObjectRecorder(Instance.rootBone); | |
Instance.m_Recorder.BindComponentsOfType<Transform>(Instance.rootBone, true); | |
while (frame < clipFrameCount) { | |
Instance.director.time = frame / timelineAsset.editorSettings.frameRate; | |
Instance.director.playableGraph.GetRootPlayable(0).SetSpeed(0); | |
yield return new WaitForEndOfFrame(); | |
Instance.m_Recorder.TakeSnapshot(0.01666666666666667f); | |
Debug.Log(frame + ": done"); | |
frame++; | |
} | |
Debug.Log("finished"); | |
var options = new CurveFilterOptions(); | |
options.keyframeReduction = true; | |
options.scaleError = 0.05f; | |
options.positionError = Instance.positionError; | |
options.rotationError = Instance.rotationError; | |
Instance.m_Recorder.SaveToClip(clip, 60, options); | |
var assetPath = $"{System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(timelineAsset))}/{clip.name}.anim"; | |
if (File.Exists(assetPath)) { | |
AssetDatabase.DeleteAsset(assetPath); | |
} | |
AssetDatabase.CreateAsset(clip, assetPath); | |
AssetDatabase.SaveAssets(); | |
AssetDatabase.Refresh(); | |
} | |
} | |
#endif |
Author
undefined9071
commented
Dec 13, 2023
- Require Unity2020.3^
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment