Skip to content

Commit c215fab

Browse files
committed
add transfer animation option to recorder settings
1 parent 3f3d6de commit c215fab

File tree

3 files changed

+182
-2
lines changed

3 files changed

+182
-2
lines changed

com.unity.formats.fbx/Editor/Sources/Recorders/FbxRecorder/FbxRecorder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ protected override void EndRecording(RecordingSession session)
6262

6363
AnimationUtility.SetAnimationClips(animator, new AnimationClip[] { clip });
6464
var exportSettings = new ExportModelSettingsSerialize();
65+
exportSettings.SetAnimationSource(settings.TransferAnimationSource);
66+
exportSettings.SetAnimationDest(settings.TransferAnimationDest);
6567
var toInclude = ExportSettings.Include.ModelAndAnim;
6668
if (!settings.ExportGeometry)
6769
{

com.unity.formats.fbx/Editor/Sources/Recorders/FbxRecorder/FbxRecorderSettings.cs

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections;
1+
using System;
22
using System.Collections.Generic;
33
using UnityEngine;
44
using UnityEditor.Recorder;
@@ -7,7 +7,7 @@
77
namespace UnityEditor.Formats.Fbx.Exporter
88
{
99
[RecorderSettings(typeof(FbxRecorder), "FBX", "fbx_recorder")]
10-
public class FbxRecorderSettings : RecorderSettings
10+
internal class FbxRecorderSettings : RecorderSettings
1111
{
1212
[SerializeField] bool m_exportGeometry = true;
1313
public bool ExportGeometry
@@ -22,6 +22,167 @@ public bool ExportGeometry
2222
}
2323
}
2424

25+
[SerializeField]
26+
private string m_animSourceBindingId;
27+
[SerializeField]
28+
private string m_animDestBindingId;
29+
30+
public Transform TransferAnimationSource
31+
{
32+
get
33+
{
34+
if (string.IsNullOrEmpty(m_animSourceBindingId))
35+
return null;
36+
37+
return GetBinding(m_animSourceBindingId);
38+
}
39+
40+
set
41+
{
42+
if (!TransferAnimationSourceIsValid(value))
43+
{
44+
return;
45+
}
46+
if (string.IsNullOrEmpty(m_animSourceBindingId))
47+
m_animSourceBindingId = GenerateBindingId();
48+
49+
SetBinding(m_animSourceBindingId, value);
50+
}
51+
}
52+
53+
public Transform TransferAnimationDest
54+
{
55+
get
56+
{
57+
if (string.IsNullOrEmpty(m_animDestBindingId))
58+
return null;
59+
60+
return GetBinding(m_animDestBindingId);
61+
}
62+
63+
set
64+
{
65+
if (!TransferAnimationDestIsValid(value))
66+
{
67+
return;
68+
}
69+
if (string.IsNullOrEmpty(m_animDestBindingId))
70+
m_animDestBindingId = GenerateBindingId();
71+
72+
SetBinding(m_animDestBindingId, value);
73+
}
74+
}
75+
76+
static Transform GetBinding(string id)
77+
{
78+
// return BindingManager.Get(m_BindingId) as GameObject;
79+
var method = Type.GetType("UnityEditor.Recorder.BindingManager,Unity.Recorder.Editor").GetMethod("Get", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
80+
return method.Invoke(null, new object[] { id }) as Transform;
81+
}
82+
83+
static void SetBinding(string id, UnityEngine.Object obj)
84+
{
85+
// BindingManager.Set(m_BindingId, value);
86+
var method = Type.GetType("UnityEditor.Recorder.BindingManager,Unity.Recorder.Editor").GetMethod("Set", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
87+
method.Invoke(null, new object[] { id, obj });
88+
}
89+
90+
static string GenerateBindingId()
91+
{
92+
return GUID.Generate().ToString();
93+
}
94+
95+
/// <summary>
96+
/// Determines whether p is an ancestor to t.
97+
/// </summary>
98+
/// <returns><c>true</c> if p is ancestor to t; otherwise, <c>false</c>.</returns>
99+
/// <param name="p">P.</param>
100+
/// <param name="t">T.</param>
101+
protected bool IsAncestor(Transform p, Transform t)
102+
{
103+
var curr = t;
104+
while (curr != null)
105+
{
106+
if (curr == p)
107+
{
108+
return true;
109+
}
110+
curr = curr.parent;
111+
}
112+
return false;
113+
}
114+
115+
/// <summary>
116+
/// Determines whether t1 and t2 are in the same hierarchy.
117+
/// </summary>
118+
/// <returns><c>true</c> if t1 is in same hierarchy as t2; otherwise, <c>false</c>.</returns>
119+
/// <param name="t1">T1.</param>
120+
/// <param name="t2">T2.</param>
121+
protected bool IsInSameHierarchy(Transform t1, Transform t2)
122+
{
123+
return (IsAncestor(t1, t2) || IsAncestor(t2, t1));
124+
}
125+
126+
protected bool TransferAnimationSourceIsValid(Transform newValue)
127+
{
128+
if (!newValue)
129+
{
130+
return true;
131+
}
132+
133+
var selectedGO = m_AnimationInputSettings.gameObject;
134+
135+
if (!selectedGO)
136+
{
137+
Debug.LogWarning("FbxRecorderSettings: no Objects selected for export, can't transfer animation");
138+
return false;
139+
}
140+
141+
// source must be ancestor to dest
142+
if (TransferAnimationDest && !IsAncestor(newValue, TransferAnimationDest))
143+
{
144+
Debug.LogWarningFormat("FbxRecorderSettings: Source {0} must be an ancestor of {1}", newValue.name, TransferAnimationDest.name);
145+
return false;
146+
}
147+
// must be in same hierarchy as selected GO
148+
if (!selectedGO || !IsInSameHierarchy(newValue, selectedGO.transform))
149+
{
150+
Debug.LogWarningFormat("FbxRecorderSettings: Source {0} must be in the same hierarchy as {1}", newValue.name, selectedGO ? selectedGO.name : "the selected object");
151+
return false;
152+
}
153+
return true;
154+
}
155+
156+
protected bool TransferAnimationDestIsValid(Transform newValue)
157+
{
158+
if (!newValue)
159+
{
160+
return true;
161+
}
162+
163+
var selectedGO = m_AnimationInputSettings.gameObject;
164+
165+
if (!selectedGO)
166+
{
167+
Debug.LogWarning("FbxRecorderSettings: no Objects selected for export, can't transfer animation");
168+
return false;
169+
}
170+
171+
// source must be ancestor to dest
172+
if (TransferAnimationSource && !IsAncestor(TransferAnimationSource, newValue))
173+
{
174+
Debug.LogWarningFormat("FbxRecorderSettings: Destination {0} must be a descendant of {1}", newValue.name, TransferAnimationSource.name);
175+
return false;
176+
}
177+
// must be in same hierarchy as selected GO
178+
if (!selectedGO || !IsInSameHierarchy(newValue, selectedGO.transform))
179+
{
180+
Debug.LogWarningFormat("FbxRecorderSettings: Destination {0} must be in the same hierarchy as {1}", newValue.name, selectedGO ? selectedGO.name : "the selected object");
181+
return false;
182+
}
183+
return true;
184+
}
185+
25186
[SerializeField] AnimationInputSettings m_AnimationInputSettings = new AnimationInputSettings();
26187

27188
public AnimationInputSettings animationInputSettings

com.unity.formats.fbx/Editor/Sources/Recorders/FbxRecorder/FbxRecorderSettingsEditor.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,22 @@ protected override void FileTypeAndFormatGUI()
1717

1818
settings.ExportGeometry = EditorGUILayout.Toggle("Export Geometry", settings.ExportGeometry);
1919
}
20+
21+
protected override void OnEncodingGui()
22+
{
23+
base.OnEncodingGui();
24+
25+
DrawSeparator();
26+
27+
EditorGUILayout.LabelField(new GUIContent(
28+
"Transfer Animation",
29+
"Transfer transform animation from source to destination. Animation on objects between source and destination will also be transferred to destination."
30+
));
31+
32+
FbxRecorderSettings settings = target as FbxRecorderSettings;
33+
34+
settings.TransferAnimationSource = EditorGUILayout.ObjectField("Source", settings.TransferAnimationSource, typeof(Transform), allowSceneObjects: true) as Transform;
35+
settings.TransferAnimationDest = EditorGUILayout.ObjectField("Destination", settings.TransferAnimationDest, typeof(Transform), allowSceneObjects: true) as Transform;
36+
}
2037
}
2138
}

0 commit comments

Comments
 (0)