PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/VoteMario/Library/PackageCache/com.unity.timeline@1.5.6/Editor/Utilities/AnimatedParameterUtility.cs

https://gitlab.com/Surabhi124/vote-mario
C# | 358 lines | 279 code | 64 blank | 15 comment | 81 complexity | c8539f2b2552ade361240d28bbfb93ac MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using UnityEngine;
  6. using UnityEngine.Playables;
  7. using UnityEngine.Timeline;
  8. using UnityObject = UnityEngine.Object;
  9. namespace UnityEditor.Timeline
  10. {
  11. static class AnimatedParameterUtility
  12. {
  13. static readonly Type k_DefaultAnimationType = typeof(TimelineAsset);
  14. static SerializedObject s_CachedObject;
  15. public static ICurvesOwner ToCurvesOwner(IPlayableAsset playableAsset, TimelineAsset timeline)
  16. {
  17. if (playableAsset == null)
  18. return null;
  19. var curvesOwner = playableAsset as ICurvesOwner;
  20. if (curvesOwner == null)
  21. {
  22. // If the asset is not directly an ICurvesOwner, it might be the asset for a TimelineClip
  23. curvesOwner = TimelineRecording.FindClipWithAsset(timeline, playableAsset);
  24. }
  25. return curvesOwner;
  26. }
  27. public static bool TryGetSerializedPlayableAsset(UnityObject asset, out SerializedObject serializedObject)
  28. {
  29. serializedObject = null;
  30. if (asset == null || Attribute.IsDefined(asset.GetType(), typeof(NotKeyableAttribute)) || !HasScriptPlayable(asset))
  31. return false;
  32. serializedObject = GetSerializedPlayableAsset(asset);
  33. return serializedObject != null;
  34. }
  35. public static SerializedObject GetSerializedPlayableAsset(UnityObject asset)
  36. {
  37. if (!(asset is IPlayableAsset))
  38. return null;
  39. var scriptObject = asset as ScriptableObject;
  40. if (scriptObject == null)
  41. return null;
  42. if (s_CachedObject == null || s_CachedObject.targetObject != asset)
  43. {
  44. s_CachedObject = new SerializedObject(scriptObject);
  45. }
  46. return s_CachedObject;
  47. }
  48. public static void UpdateSerializedPlayableAsset(UnityObject asset)
  49. {
  50. var so = GetSerializedPlayableAsset(asset);
  51. if (so != null)
  52. so.UpdateIfRequiredOrScript();
  53. }
  54. public static bool HasScriptPlayable(UnityObject asset)
  55. {
  56. if (asset == null)
  57. return false;
  58. var scriptPlayable = asset as IPlayableBehaviour;
  59. return scriptPlayable != null || GetScriptPlayableFields(asset as IPlayableAsset).Any();
  60. }
  61. public static FieldInfo[] GetScriptPlayableFields(IPlayableAsset asset)
  62. {
  63. if (asset == null)
  64. return new FieldInfo[0];
  65. FieldInfo[] scriptPlayableFields;
  66. if (!AnimatedParameterCache.TryGetScriptPlayableFields(asset.GetType(), out scriptPlayableFields))
  67. {
  68. scriptPlayableFields = GetScriptPlayableFields_Internal(asset);
  69. AnimatedParameterCache.SetScriptPlayableFields(asset.GetType(), scriptPlayableFields);
  70. }
  71. return scriptPlayableFields;
  72. }
  73. static FieldInfo[] GetScriptPlayableFields_Internal(IPlayableAsset asset)
  74. {
  75. return asset.GetType()
  76. .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
  77. .Where(
  78. f => typeof(IPlayableBehaviour).IsAssignableFrom(f.FieldType) && // The field is an IPlayableBehaviour
  79. (f.IsPublic || f.GetCustomAttributes(typeof(SerializeField), false).Any()) && // The field is either public or marked with [SerializeField]
  80. !f.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any() && // The field is not marked with [NotKeyable]
  81. !f.GetCustomAttributes(typeof(HideInInspector), false).Any() && // The field is not marked with [HideInInspector]
  82. !f.FieldType.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any()) // The field is not of a type marked with [NotKeyable]
  83. .ToArray();
  84. }
  85. public static bool HasAnyAnimatableParameters(UnityObject asset)
  86. {
  87. return GetAllAnimatableParameters(asset).Any();
  88. }
  89. public static IEnumerable<SerializedProperty> GetAllAnimatableParameters(UnityObject asset)
  90. {
  91. SerializedObject serializedObject;
  92. if (!TryGetSerializedPlayableAsset(asset, out serializedObject))
  93. yield break;
  94. var prop = serializedObject.GetIterator();
  95. // We need to keep this variable because prop starts invalid
  96. var outOfBounds = false;
  97. while (!outOfBounds && prop.NextVisible(true))
  98. {
  99. foreach (var property in SelectAnimatableProperty(prop))
  100. yield return property;
  101. // We can become out of bounds by calling SelectAnimatableProperty, if the last iterated property is a color.
  102. outOfBounds = !prop.isValid;
  103. }
  104. }
  105. static IEnumerable<SerializedProperty> SelectAnimatableProperty(SerializedProperty prop)
  106. {
  107. // We're only interested by animatable leaf parameters
  108. if (!prop.hasChildren && IsParameterAnimatable(prop))
  109. yield return prop.Copy();
  110. // Color type is not considered "visible" when iterating
  111. if (prop.propertyType == SerializedPropertyType.Color)
  112. {
  113. var end = prop.GetEndProperty();
  114. // For some reasons, if the last 2+ serialized properties are of type Color, prop becomes invalid and
  115. // Next() throws an exception. This is not the case when only the last serialized property is a Color.
  116. while (!SerializedProperty.EqualContents(prop, end) && prop.isValid && prop.Next(true))
  117. {
  118. foreach (var property in SelectAnimatableProperty(prop))
  119. yield return property;
  120. }
  121. }
  122. }
  123. public static bool IsParameterAnimatable(UnityObject asset, string parameterName)
  124. {
  125. SerializedObject serializedObject;
  126. if (!TryGetSerializedPlayableAsset(asset, out serializedObject))
  127. return false;
  128. var prop = serializedObject.FindProperty(parameterName);
  129. return IsParameterAnimatable(prop);
  130. }
  131. public static bool IsParameterAnimatable(SerializedProperty property)
  132. {
  133. if (property == null)
  134. return false;
  135. bool isAnimatable;
  136. if (!AnimatedParameterCache.TryGetIsPropertyAnimatable(property, out isAnimatable))
  137. {
  138. isAnimatable = IsParameterAnimatable_Internal(property);
  139. AnimatedParameterCache.SetIsPropertyAnimatable(property, isAnimatable);
  140. }
  141. return isAnimatable;
  142. }
  143. static bool IsParameterAnimatable_Internal(SerializedProperty property)
  144. {
  145. if (property == null)
  146. return false;
  147. var asset = property.serializedObject.targetObject;
  148. // Currently not supported
  149. if (asset is AnimationTrack)
  150. return false;
  151. if (IsParameterKeyable(property))
  152. return asset is IPlayableBehaviour || IsParameterAtPathAnimatable(asset, property.propertyPath);
  153. return false;
  154. }
  155. static bool IsParameterKeyable(SerializedProperty property)
  156. {
  157. return IsTypeAnimatable(property.propertyType) && IsKeyableInHierarchy(property);
  158. }
  159. static bool IsKeyableInHierarchy(SerializedProperty property)
  160. {
  161. const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
  162. var pathSegments = property.propertyPath.Split('.');
  163. var type = property.serializedObject.targetObject.GetType();
  164. foreach (var segment in pathSegments)
  165. {
  166. if (type.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any())
  167. {
  168. return false;
  169. }
  170. if (type.IsArray)
  171. return false;
  172. var fieldInfo = type.GetField(segment, bindingFlags);
  173. if (fieldInfo == null ||
  174. fieldInfo.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any() ||
  175. fieldInfo.GetCustomAttributes(typeof(HideInInspector), false).Any())
  176. {
  177. return false;
  178. }
  179. type = fieldInfo.FieldType;
  180. // only value types are supported
  181. if (!type.IsValueType && !typeof(IPlayableBehaviour).IsAssignableFrom(type))
  182. return false;
  183. }
  184. return true;
  185. }
  186. static bool IsParameterAtPathAnimatable(UnityObject asset, string path)
  187. {
  188. if (asset == null)
  189. return false;
  190. return GetScriptPlayableFields(asset as IPlayableAsset)
  191. .Any(
  192. f => path.StartsWith(f.Name, StringComparison.Ordinal) &&
  193. path.Length > f.Name.Length &&
  194. path[f.Name.Length] == '.');
  195. }
  196. public static bool IsTypeAnimatable(SerializedPropertyType type)
  197. {
  198. // Note: Integer is not currently supported by the animated property system
  199. switch (type)
  200. {
  201. case SerializedPropertyType.Boolean:
  202. case SerializedPropertyType.Float:
  203. case SerializedPropertyType.Vector2:
  204. case SerializedPropertyType.Vector3:
  205. case SerializedPropertyType.Color:
  206. case SerializedPropertyType.Quaternion:
  207. case SerializedPropertyType.Vector4:
  208. return true;
  209. default:
  210. return false;
  211. }
  212. }
  213. public static bool IsParameterAnimated(UnityObject asset, AnimationClip animationData, string parameterName)
  214. {
  215. if (asset == null || animationData == null)
  216. return false;
  217. var binding = GetCurveBinding(asset, parameterName);
  218. var bindings = AnimationClipCurveCache.Instance.GetCurveInfo(animationData).bindings;
  219. return bindings.Any(x => BindingMatchesParameterName(x, binding.propertyName));
  220. }
  221. // Retrieve an animated parameter curve. parameter name is required to include the appropriate field for vectors
  222. // e.g.: position
  223. public static AnimationCurve GetAnimatedParameter(UnityObject asset, AnimationClip animationData, string parameterName)
  224. {
  225. if (!(asset is ScriptableObject) || animationData == null)
  226. return null;
  227. var binding = GetCurveBinding(asset, parameterName);
  228. return AnimationUtility.GetEditorCurve(animationData, binding);
  229. }
  230. // get an animatable curve binding for this parameter
  231. public static EditorCurveBinding GetCurveBinding(UnityObject asset, string parameterName)
  232. {
  233. var animationName = GetAnimatedParameterBindingName(asset, parameterName);
  234. return EditorCurveBinding.FloatCurve(string.Empty, GetValidAnimationType(asset), animationName);
  235. }
  236. public static string GetAnimatedParameterBindingName(UnityObject asset, string parameterName)
  237. {
  238. if (asset == null)
  239. return parameterName;
  240. string bindingName;
  241. if (!AnimatedParameterCache.TryGetBindingName(asset.GetType(), parameterName, out bindingName))
  242. {
  243. bindingName = GetAnimatedParameterBindingName_Internal(asset, parameterName);
  244. AnimatedParameterCache.SetBindingName(asset.GetType(), parameterName, bindingName);
  245. }
  246. return bindingName;
  247. }
  248. static string GetAnimatedParameterBindingName_Internal(UnityObject asset, string parameterName)
  249. {
  250. if (asset is IPlayableBehaviour)
  251. return parameterName;
  252. // strip the IScript playable field name
  253. var fields = GetScriptPlayableFields(asset as IPlayableAsset);
  254. foreach (var f in fields)
  255. {
  256. if (parameterName.StartsWith(f.Name, StringComparison.Ordinal))
  257. {
  258. if (parameterName.Length > f.Name.Length && parameterName[f.Name.Length] == '.')
  259. return parameterName.Substring(f.Name.Length + 1);
  260. }
  261. }
  262. return parameterName;
  263. }
  264. public static bool BindingMatchesParameterName(EditorCurveBinding binding, string parameterName)
  265. {
  266. if (binding.propertyName == parameterName)
  267. return true;
  268. var indexOfDot = binding.propertyName.LastIndexOf('.');
  269. return indexOfDot > 0 && parameterName.Length == indexOfDot &&
  270. binding.propertyName.StartsWith(parameterName, StringComparison.Ordinal);
  271. }
  272. // the animated type must be a non-abstract instantiable object.
  273. public static Type GetValidAnimationType(UnityObject asset)
  274. {
  275. return asset != null ? asset.GetType() : k_DefaultAnimationType;
  276. }
  277. public static FieldInfo GetFieldInfoForProperty(SerializedProperty property)
  278. {
  279. FieldInfo fieldInfo;
  280. if (!AnimatedParameterCache.TryGetFieldInfoForProperty(property, out fieldInfo))
  281. {
  282. Type _;
  283. fieldInfo = ScriptAttributeUtility.GetFieldInfoFromProperty(property, out _);
  284. AnimatedParameterCache.SetFieldInfoForProperty(property, fieldInfo);
  285. }
  286. return fieldInfo;
  287. }
  288. public static T GetAttributeForProperty<T>(SerializedProperty property) where T : Attribute
  289. {
  290. var fieldInfo = GetFieldInfoForProperty(property);
  291. return fieldInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
  292. }
  293. }
  294. }