Skip to content

Commit 4b436cf

Browse files
author
Unity Technologies
committed
Unity 2023.2.0a12 C# reference source code
1 parent 18cc4f6 commit 4b436cf

File tree

190 files changed

+4614
-1816
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

190 files changed

+4614
-1816
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
// Unity C# reference source
2+
// Copyright (c) Unity Technologies. For terms of use, see
3+
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
4+
5+
using System.Collections.Generic;
6+
using UnityEditor;
7+
using UnityEngine;
8+
using System;
9+
using System.Linq;
10+
using UnityEditor.IMGUI.Controls;
11+
using Object = UnityEngine.Object;
12+
13+
namespace UnityEditorInternal
14+
{
15+
struct AddCurvesPopupHierarchyBuilder
16+
{
17+
struct KeyComparer : IComparer<Key>
18+
{
19+
static readonly Type s_GameObjectType = typeof(GameObject);
20+
static readonly Type s_TransformType = typeof(Transform);
21+
22+
public int Compare(Key x, Key y)
23+
{
24+
var result = String.Compare(x.path, y.path, StringComparison.Ordinal);
25+
if (result == 0 && x.type != y.type)
26+
{
27+
// Make sure GameObject properties appear first, then Transform.
28+
if (x.type == s_GameObjectType)
29+
return -1;
30+
if (y.type == s_GameObjectType)
31+
return 1;
32+
if (x.type == typeof(Transform))
33+
return -1;
34+
if (y.type == typeof(Transform))
35+
return 1;
36+
37+
return String.Compare(x.type.Name, y.type.Name, StringComparison.Ordinal);
38+
}
39+
40+
return result;
41+
}
42+
}
43+
44+
struct Key
45+
{
46+
public string path;
47+
public Type type;
48+
}
49+
50+
SortedDictionary<Key, List<EditorCurveBinding>> m_AccumulatedBindings;
51+
AnimationWindowState m_State;
52+
53+
public AddCurvesPopupHierarchyBuilder(AnimationWindowState state)
54+
{
55+
m_AccumulatedBindings = new SortedDictionary<Key, List<EditorCurveBinding>>(new KeyComparer());
56+
m_State = state;
57+
}
58+
59+
public void Add(EditorCurveBinding binding)
60+
{
61+
var key = new Key { path = binding.path, type = binding.type };
62+
63+
if (m_AccumulatedBindings.TryGetValue(key, out var bindings))
64+
bindings.Add(binding);
65+
else
66+
m_AccumulatedBindings[key] = new List<EditorCurveBinding>(new [] {binding});
67+
}
68+
69+
void RemoveUnnecessaryBindings(List<EditorCurveBinding> bindings)
70+
{
71+
for (int i = bindings.Count - 1; i >= 0; --i)
72+
{
73+
// Let's not add those that already have a existing curve.
74+
if (AnimationWindowUtility.IsCurveCreated(m_State.activeAnimationClip, bindings[i]))
75+
bindings.RemoveAt(i);
76+
// Remove animator enabled property which shouldn't be animated.
77+
else if (bindings[i].type == typeof(Animator) && bindings[i].propertyName == "m_Enabled")
78+
bindings.RemoveAt(i);
79+
// For RectTransform.position we only want .z
80+
else if (AnimationWindowUtility.IsRectTransformPosition(bindings[i]) && !bindings[i].propertyName.EndsWith(".z"))
81+
bindings.RemoveAt(i);
82+
// Don't show for the root go
83+
else if (bindings[i].type == typeof(GameObject) && string.IsNullOrEmpty(bindings[i].path))
84+
bindings.RemoveAt(i);
85+
}
86+
}
87+
88+
public TreeViewItem CreateTreeView()
89+
{
90+
TreeViewItem rootNode;
91+
92+
// Bindings of a single Component/ScriptableObject, skip the group node.
93+
if (m_AccumulatedBindings.Count == 1)
94+
{
95+
var bindings = m_AccumulatedBindings.First().Value;
96+
RemoveUnnecessaryBindings(bindings);
97+
98+
if (bindings.Count > 0)
99+
{
100+
rootNode = AddAnimatableObjectToHierarchy(bindings, null, "");
101+
}
102+
else
103+
{
104+
rootNode = new AddCurvesPopupObjectNode(null, string.Empty, string.Empty);
105+
}
106+
}
107+
else
108+
{
109+
var groupNodes = new Dictionary<string, TreeViewItem>();
110+
var childNodes = new Dictionary<TreeViewItem, List<TreeViewItem>>();
111+
var inheritedNodeWeights = new Dictionary<TreeViewItem, int>();
112+
113+
rootNode = new AddCurvesPopupObjectNode(null, string.Empty, string.Empty);
114+
115+
TreeViewItem groupNode = rootNode;
116+
117+
groupNodes.Add(string.Empty, (rootNode));
118+
childNodes.Add(groupNode, new List<TreeViewItem>());
119+
inheritedNodeWeights.Add(groupNode, 0);
120+
121+
string currentPath = string.Empty;
122+
foreach (var kvp in m_AccumulatedBindings)
123+
{
124+
if (!currentPath.Equals(kvp.Key.path))
125+
{
126+
TreeViewItem parentNode = rootNode;
127+
var parentPath = GetParentPath(kvp.Key.path);
128+
129+
while (parentPath != null)
130+
{
131+
if (groupNodes.TryGetValue(parentPath, out var node))
132+
{
133+
parentNode = node;
134+
break;
135+
}
136+
137+
parentPath = GetParentPath(parentPath);
138+
}
139+
140+
groupNode = new AddCurvesPopupObjectNode(parentNode, kvp.Key.path, "", GetObjectName(kvp.Key.path));
141+
groupNodes.Add(kvp.Key.path, groupNode);
142+
childNodes.Add(groupNode, new List<TreeViewItem>());
143+
inheritedNodeWeights.Add(groupNode, 0);
144+
145+
childNodes[parentNode].Add(groupNode);
146+
147+
currentPath = kvp.Key.path;
148+
}
149+
150+
var bindings = kvp.Value;
151+
RemoveUnnecessaryBindings(bindings);
152+
153+
if (bindings.Count > 0)
154+
{
155+
// Builtin GameObject attributes.
156+
if (kvp.Key.type == typeof(GameObject))
157+
{
158+
TreeViewItem newNode = CreateNode(bindings.ToArray(), groupNode, null);
159+
if (newNode != null)
160+
childNodes[groupNode].Add(newNode);
161+
}
162+
else
163+
{
164+
childNodes[groupNode].Add(AddAnimatableObjectToHierarchy(bindings, groupNode, kvp.Key.path));
165+
166+
var parentGroupNode = groupNode;
167+
while (parentGroupNode != null)
168+
{
169+
inheritedNodeWeights[parentGroupNode] += bindings.Count;
170+
parentGroupNode = parentGroupNode.parent;
171+
}
172+
}
173+
}
174+
}
175+
176+
// Remove empty leaves from tree view.
177+
foreach (var kvp in inheritedNodeWeights)
178+
{
179+
// Remove Leaves nodes without properties.
180+
if (inheritedNodeWeights[kvp.Key] == 0 && kvp.Key.parent != null)
181+
{
182+
childNodes[kvp.Key.parent].Remove(kvp.Key);
183+
kvp.Key.parent = null;
184+
}
185+
}
186+
187+
// Set child parent references.
188+
foreach (var kvp in childNodes)
189+
{
190+
TreeViewUtility.SetChildParentReferences(kvp.Value, kvp.Key);
191+
}
192+
}
193+
194+
m_AccumulatedBindings.Clear();
195+
196+
return rootNode;
197+
}
198+
199+
private string GetParentPath(string path)
200+
{
201+
if (String.IsNullOrEmpty(path))
202+
return null;
203+
204+
int index = path.LastIndexOf('/');
205+
if (index == -1)
206+
return string.Empty;
207+
208+
return path.Substring(0, index);
209+
}
210+
211+
private string GetObjectName(string path)
212+
{
213+
if (String.IsNullOrEmpty(path))
214+
return null;
215+
216+
int index = path.LastIndexOf('/');
217+
if (index == -1)
218+
return path;
219+
220+
return path.Substring(index + 1);
221+
}
222+
223+
private string GetClassName(EditorCurveBinding binding)
224+
{
225+
if (m_State.activeRootGameObject != null)
226+
{
227+
Object target = AnimationUtility.GetAnimatedObject(m_State.activeRootGameObject, binding);
228+
if (target != null)
229+
return ObjectNames.GetInspectorTitle(target);
230+
}
231+
232+
return binding.type.Name;
233+
}
234+
235+
private Texture2D GetIcon(EditorCurveBinding binding)
236+
{
237+
return AssetPreview.GetMiniTypeThumbnail(binding.type);
238+
}
239+
240+
private TreeViewItem AddAnimatableObjectToHierarchy(List<EditorCurveBinding> curveBindings, TreeViewItem parentNode, string path)
241+
{
242+
TreeViewItem node = new AddCurvesPopupObjectNode(parentNode, path, GetClassName(curveBindings[0]));
243+
node.icon = GetIcon(curveBindings[0]);
244+
245+
List<TreeViewItem> childNodes = new List<TreeViewItem>();
246+
List<EditorCurveBinding> singlePropertyBindings = new List<EditorCurveBinding>();
247+
SerializedObject so = null;
248+
249+
for (int i = 0; i < curveBindings.Count; i++)
250+
{
251+
EditorCurveBinding curveBinding = curveBindings[i];
252+
if (m_State.activeRootGameObject && curveBinding.isSerializeReferenceCurve)
253+
{
254+
var animatedObject = AnimationUtility.GetAnimatedObject(m_State.activeRootGameObject, curveBinding);
255+
if (animatedObject != null && (so == null || so.targetObject != animatedObject))
256+
so = new SerializedObject(animatedObject);
257+
}
258+
259+
singlePropertyBindings.Add(curveBinding);
260+
261+
// We expect curveBindings to come sorted by propertyname
262+
if (i == curveBindings.Count - 1 || AnimationWindowUtility.GetPropertyGroupName(curveBindings[i + 1].propertyName) != AnimationWindowUtility.GetPropertyGroupName(curveBinding.propertyName))
263+
{
264+
TreeViewItem newNode = CreateNode(singlePropertyBindings.ToArray(), node, so);
265+
if (newNode != null)
266+
childNodes.Add(newNode);
267+
singlePropertyBindings.Clear();
268+
}
269+
}
270+
271+
childNodes.Sort();
272+
273+
TreeViewUtility.SetChildParentReferences(childNodes, node);
274+
return node;
275+
}
276+
277+
private TreeViewItem CreateNode(EditorCurveBinding[] curveBindings, TreeViewItem parentNode, SerializedObject so)
278+
{
279+
var node = new AddCurvesPopupPropertyNode(parentNode, curveBindings, AnimationWindowUtility.GetNicePropertyGroupDisplayName(curveBindings[0], so));
280+
node.icon = parentNode.icon;
281+
return node;
282+
}
283+
}
284+
285+
class AddCurvesPopupObjectNode : TreeViewItem
286+
{
287+
public AddCurvesPopupObjectNode(TreeViewItem parent, string path, string className, string displayName = null)
288+
: base((path + className).GetHashCode(), parent != null ? parent.depth + 1 : -1, parent, displayName ?? className)
289+
{
290+
}
291+
}
292+
293+
class AddCurvesPopupPropertyNode : TreeViewItem
294+
{
295+
public EditorCurveBinding[] curveBindings;
296+
297+
public AddCurvesPopupPropertyNode(TreeViewItem parent, EditorCurveBinding[] curveBindings, string displayName)
298+
: base(curveBindings[0].GetHashCode(), parent.depth + 1, parent, displayName)
299+
{
300+
this.curveBindings = curveBindings;
301+
}
302+
303+
public override int CompareTo(TreeViewItem other)
304+
{
305+
AddCurvesPopupPropertyNode otherNode = other as AddCurvesPopupPropertyNode;
306+
if (otherNode != null)
307+
{
308+
if (displayName.Contains("Rotation") && otherNode.displayName.Contains("Position"))
309+
return 1;
310+
if (displayName.Contains("Position") && otherNode.displayName.Contains("Rotation"))
311+
return -1;
312+
}
313+
return base.CompareTo(other);
314+
}
315+
}
316+
}

0 commit comments

Comments
 (0)