A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3#if UNITY_EDITOR
4using UnityEditor;
5#endif
6
7namespace UnityEngine.Timeline
8{
9 static class TimelineCreateUtilities
10 {
11 // based off of ObjectNames.GetUniqueName, but can exist in runtime
12 public static string GenerateUniqueActorName(List<ScriptableObject> tracks, string name)
13 {
14 if (!tracks.Exists(x => ((object)x) != null && x.name == name))
15 return name;
16
17 int numberInParentheses = 0;
18 string baseName = name;
19
20 if (!string.IsNullOrEmpty(name) && name[name.Length - 1] == ')')
21 {
22 int index = name.LastIndexOf('(');
23 if (index > 0)
24 {
25 string numberString = name.Substring(index + 1, name.Length - index - 2);
26 if (int.TryParse(numberString, out numberInParentheses))
27 {
28 numberInParentheses++;
29 baseName = name.Substring(0, index);
30 }
31 }
32 }
33
34 baseName = baseName.TrimEnd();
35
36 for (int i = numberInParentheses; i < numberInParentheses + 5000; i++)
37 {
38 if (i > 0)
39 {
40 string result = string.Format("{0} ({1})", baseName, i);
41 if (!tracks.Exists(x => ((object)x) != null && x.name == result))
42 return result;
43 }
44 }
45
46 // Fallback
47 return name;
48 }
49
50 public static void SaveAssetIntoObject(Object childAsset, Object masterAsset)
51 {
52 if (childAsset == null || masterAsset == null)
53 return;
54
55 if ((masterAsset.hideFlags & HideFlags.DontSave) != 0)
56 {
57 childAsset.hideFlags |= HideFlags.DontSave;
58 }
59 else
60 {
61 childAsset.hideFlags |= HideFlags.HideInHierarchy;
62#if UNITY_EDITOR
63 if (!AssetDatabase.Contains(childAsset) && AssetDatabase.Contains(masterAsset))
64 AssetDatabase.AddObjectToAsset(childAsset, masterAsset);
65#endif
66 }
67 }
68
69 public static void RemoveAssetFromObject(Object childAsset, Object masterAsset)
70 {
71 if (childAsset == null || masterAsset == null)
72 return;
73
74#if UNITY_EDITOR
75 if (AssetDatabase.Contains(childAsset) && AssetDatabase.Contains(masterAsset))
76 AssetDatabase.RemoveObjectFromAsset(childAsset);
77#endif
78 }
79
80 public static AnimationClip CreateAnimationClipForTrack(string name, TrackAsset track, bool isLegacy)
81 {
82 var timelineAsset = track != null ? track.timelineAsset : null;
83 var trackFlags = track != null ? track.hideFlags : HideFlags.None;
84
85 var curves = new AnimationClip
86 {
87 legacy = isLegacy,
88
89 name = name,
90
91 frameRate = timelineAsset == null
92 ? (float)TimelineAsset.EditorSettings.kDefaultFrameRate
93 : (float)timelineAsset.editorSettings.frameRate
94 };
95
96 SaveAssetIntoObject(curves, timelineAsset);
97 curves.hideFlags = trackFlags & ~HideFlags.HideInHierarchy; // Never hide in hierarchy
98
99 TimelineUndo.RegisterCreatedObjectUndo(curves, "Create Curves");
100
101 return curves;
102 }
103
104 public static bool ValidateParentTrack(TrackAsset parent, Type childType)
105 {
106 if (childType == null || !typeof(TrackAsset).IsAssignableFrom(childType))
107 return false;
108
109 // no parent is valid for any type
110 if (parent == null)
111 return true;
112
113 // A track supports layers if it implements ILayerable. Only supported for parents that are
114 // the same exact type as the child class, and 1 level of nesting only
115 if (parent is ILayerable && !parent.isSubTrack && parent.GetType() == childType)
116 return true;
117
118 var attr = Attribute.GetCustomAttribute(parent.GetType(), typeof(SupportsChildTracksAttribute)) as SupportsChildTracksAttribute;
119 if (attr == null)
120 return false;
121
122 // group track case, accepts all
123 if (attr.childType == null)
124 return true;
125
126 // specific case. Specifies nesting level
127 if (childType == attr.childType)
128 {
129 int nestCount = 0;
130 var p = parent;
131 while (p != null && p.isSubTrack)
132 {
133 nestCount++;
134 p = p.parent as TrackAsset;
135 }
136
137 return nestCount < attr.levels;
138 }
139 return false;
140 }
141 }
142}