Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AnimClipUpgrader.cs 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.U2D.Animation;
  5. using UnityEngine.U2D.Common;
  6. namespace UnityEditor.U2D.Animation.Upgrading
  7. {
  8. internal class AnimClipUpgrader : BaseUpgrader
  9. {
  10. static class Contents
  11. {
  12. public static readonly string ProgressBarTitle = L10n.Tr("Upgrading Animation Clips");
  13. public static readonly string VerifyingSelection = L10n.Tr("Verifying the selection");
  14. public static readonly string UpgradingSpriteKeys = L10n.Tr("Upgrading Sprite Keys");
  15. public static readonly string UpgradingCategoryLabelHash = L10n.Tr("Upgrading Category and Label hashes");
  16. }
  17. enum HashType
  18. {
  19. Label,
  20. Category,
  21. SpriteKey,
  22. SpriteHash
  23. }
  24. class BindingData
  25. {
  26. public string BindingPath;
  27. public System.Type BindingType;
  28. public List<KeyData> RawKeys;
  29. public List<ConvertedKeyData> ConvertedKeys;
  30. }
  31. class KeyData
  32. {
  33. public HashType HashType;
  34. public float Time;
  35. public float Value;
  36. }
  37. class ConvertedKeyData
  38. {
  39. public float Time;
  40. public float Value;
  41. public string Category;
  42. public string Label;
  43. }
  44. const string k_LabelHashId = "m_labelHash";
  45. const string k_CategoryHashId = "m_CategoryHash";
  46. const string k_SpriteKeyId = "m_SpriteKey";
  47. const string k_SpriteHashId = "m_SpriteHash";
  48. const string k_AnimClipTypeId = "t:AnimationClip";
  49. static bool IsSpriteHashBinding(EditorCurveBinding b) =>
  50. b.type == typeof(SpriteResolver)
  51. && !string.IsNullOrEmpty(b.propertyName)
  52. && b.propertyName == k_SpriteHashId;
  53. static bool IsSpriteKeyBinding(EditorCurveBinding b) =>
  54. b.type == typeof(SpriteResolver)
  55. && !string.IsNullOrEmpty(b.propertyName)
  56. && b.propertyName == k_SpriteKeyId;
  57. static bool IsSpriteCategoryBinding(EditorCurveBinding b) =>
  58. b.type == typeof(SpriteResolver)
  59. && !string.IsNullOrEmpty(b.propertyName)
  60. && b.propertyName == k_CategoryHashId;
  61. static bool IsSpriteLabelBinding(EditorCurveBinding b) =>
  62. b.type == typeof(SpriteResolver)
  63. && !string.IsNullOrEmpty(b.propertyName)
  64. && b.propertyName == k_LabelHashId;
  65. static SpriteLibUpgrader s_SpriteLibUpgrader = new SpriteLibUpgrader(false, false);
  66. internal override List<Object> GetUpgradableAssets()
  67. {
  68. var assets = AssetDatabase.FindAssets(k_AnimClipTypeId, new [] {"Assets"})
  69. .Select(AssetDatabase.GUIDToAssetPath)
  70. .Select(AssetDatabase.LoadAssetAtPath<Object>)
  71. .ToArray();
  72. var clips = assets
  73. .Select(x => x as AnimationClip)
  74. .Where(clip => clip != null)
  75. .Where(clip =>
  76. {
  77. var bindings = AnimationUtility.GetCurveBindings(clip)
  78. .Where(m => IsSpriteKeyBinding(m) || IsSpriteCategoryBinding(m) || IsSpriteLabelBinding(m))
  79. .ToArray();
  80. return bindings.Length > 0;
  81. }).ToArray();
  82. var assetList = new List<Object>(clips);
  83. return assetList;
  84. }
  85. internal override UpgradeReport UpgradeSelection(List<ObjectIndexPair> objects)
  86. {
  87. var entries = new List<UpgradeEntry>();
  88. AssetDatabase.StartAssetEditing();
  89. string msg;
  90. foreach (var obj in objects)
  91. {
  92. m_Logger.Add($"Verifying if the asset {obj.Target} is an AnimationClip.");
  93. EditorUtility.DisplayProgressBar(
  94. Contents.ProgressBarTitle,
  95. Contents.VerifyingSelection,
  96. GetUpgradeProgress(entries, objects));
  97. if (obj.Target == null)
  98. {
  99. msg = "The upgrade failed. Invalid selection.";
  100. m_Logger.Add(msg);
  101. m_Logger.AddLineBreak();
  102. entries.Add(new UpgradeEntry()
  103. {
  104. Result = UpgradeResult.Error,
  105. Target = obj.Target,
  106. Index = obj.Index,
  107. Message = msg
  108. });
  109. continue;
  110. }
  111. var clip = obj.Target as AnimationClip;
  112. if (clip == null)
  113. {
  114. msg = $"The upgrade failed. The asset {obj.Target.name} is not an AnimationClip.";
  115. m_Logger.Add(msg);
  116. m_Logger.AddLineBreak();
  117. entries.Add(new UpgradeEntry()
  118. {
  119. Result = UpgradeResult.Error,
  120. Target = obj.Target,
  121. Index = obj.Index,
  122. Message = msg
  123. });
  124. continue;
  125. }
  126. var extractedData = ExtractDataFromClip(clip);
  127. ConvertData(ref extractedData);
  128. var wasCleanupSuccessful = CleanupData(ref extractedData);
  129. if (!wasCleanupSuccessful)
  130. {
  131. msg = $"The upgrade of the clip {obj.Target.name} failed. Some keyframes could not be converted in the animation clip.";
  132. m_Logger.Add(msg);
  133. m_Logger.AddLineBreak();
  134. entries.Add(new UpgradeEntry()
  135. {
  136. Result = UpgradeResult.Error,
  137. Target = obj.Target,
  138. Index = obj.Index,
  139. Message = msg
  140. });
  141. continue;
  142. }
  143. var isDataValid = ValidateConvertedData(extractedData, obj, entries);
  144. if(!isDataValid)
  145. continue;
  146. UpdateClipWithConvertedData(clip, extractedData);
  147. RemoveOldData(clip, extractedData);
  148. msg = $"Upgrade successful. The clip {obj.Target.name} now uses the latest SpriteResolver data format.";
  149. m_Logger.Add(msg);
  150. m_Logger.AddLineBreak();
  151. entries.Add(new UpgradeEntry()
  152. {
  153. Result = UpgradeResult.Successful,
  154. Target = obj.Target,
  155. Index = obj.Index,
  156. Message = msg
  157. });
  158. }
  159. AssetDatabase.SaveAssets();
  160. AssetDatabase.StopAssetEditing();
  161. EditorUtility.ClearProgressBar();
  162. var report = new UpgradeReport()
  163. {
  164. UpgradeEntries = entries,
  165. Log = m_Logger.GetLog()
  166. };
  167. m_Logger.Clear();
  168. return report;
  169. }
  170. bool ValidateConvertedData(List<BindingData> extractedData, ObjectIndexPair upgradingObject, List<UpgradeEntry> entries)
  171. {
  172. var isDataValid = extractedData.All(data => data.ConvertedKeys.Count != 0);
  173. if (!isDataValid)
  174. {
  175. var msg = $"The upgrade of the clip {upgradingObject.Target.name} failed. One or more bindings could not convert its keyframes to the latest data format.";
  176. m_Logger.Add(msg);
  177. m_Logger.AddLineBreak();
  178. entries.Add(new UpgradeEntry()
  179. {
  180. Result = UpgradeResult.Error,
  181. Target = upgradingObject.Target,
  182. Index = upgradingObject.Index,
  183. Message = msg
  184. });
  185. }
  186. return isDataValid;
  187. }
  188. List<BindingData> ExtractDataFromClip(AnimationClip clip)
  189. {
  190. var spriteHashBindings = ExtractBindingsFromClip(clip, HashType.SpriteHash, IsSpriteHashBinding);
  191. var spriteKeyBindings = ExtractBindingsFromClip(clip, HashType.SpriteKey, IsSpriteKeyBinding);
  192. var categoryBindings = ExtractBindingsFromClip(clip, HashType.Category, IsSpriteCategoryBinding);
  193. var labelBindings = ExtractBindingsFromClip(clip, HashType.Label, IsSpriteLabelBinding);
  194. var bindings = new List<BindingData>();
  195. bindings.AddRange(spriteHashBindings);
  196. bindings.AddRange(spriteKeyBindings);
  197. bindings.AddRange(categoryBindings);
  198. bindings.AddRange(labelBindings);
  199. bindings = MergeBindingData(bindings);
  200. for (var i = 0; i < bindings.Count; ++i)
  201. SortKeyData(bindings[i]);
  202. return bindings;
  203. }
  204. BindingData[] ExtractBindingsFromClip(AnimationClip clip, HashType hashType, System.Func<EditorCurveBinding, bool> isBindingFunc)
  205. {
  206. var spriteHashBindings = AnimationUtility.GetCurveBindings(clip)
  207. .Where(isBindingFunc.Invoke)
  208. .ToArray();
  209. var bindingData = new BindingData[spriteHashBindings.Length];
  210. for (var i = 0; i < spriteHashBindings.Length; ++i)
  211. bindingData[i] = ExtractKeyframesFromClip(clip, spriteHashBindings[i], hashType);
  212. m_Logger.Add($"Extracting {hashType} bindings from clip. Found {bindingData.Length} bindings.");
  213. return bindingData;
  214. }
  215. BindingData ExtractKeyframesFromClip(AnimationClip clip, EditorCurveBinding curveBinding, HashType hashType)
  216. {
  217. var bindingPath = curveBinding.path;
  218. var bindingType = curveBinding.type;
  219. var curves = AnimationUtility.GetEditorCurve(clip, curveBinding);
  220. var keys = curves.keys;
  221. var keyData = new List<KeyData>(keys.Length);
  222. keyData.AddRange(keys
  223. .Select(t => new KeyData() { Time = t.time, Value = t.value, HashType = hashType }));
  224. var data = new BindingData()
  225. {
  226. BindingPath = bindingPath,
  227. BindingType = bindingType,
  228. RawKeys = keyData
  229. };
  230. m_Logger.Add($"Extracting {hashType} keyframes from clip. Found {keyData.Count} keyframes.");
  231. return data;
  232. }
  233. List<BindingData> MergeBindingData(List<BindingData> bindingData)
  234. {
  235. var mergedData = new List<BindingData>();
  236. for (var i = 0; i < bindingData.Count; i++)
  237. {
  238. var index = mergedData.FindIndex(x =>
  239. x.BindingPath == bindingData[i].BindingPath &&
  240. x.BindingType == bindingData[i].BindingType);
  241. if (index != -1)
  242. mergedData[index].RawKeys.AddRange(bindingData[i].RawKeys);
  243. else
  244. mergedData.Add(bindingData[i]);
  245. }
  246. m_Logger.Add($"Merging different types keyframes from the same bindings, into the same binding list. We now have {mergedData.Count} binding lists.");
  247. return mergedData;
  248. }
  249. void SortKeyData(BindingData bindingData)
  250. {
  251. bindingData.RawKeys.Sort((a, b) => a.Time.CompareTo(b.Time));
  252. m_Logger.Add($"Order the keyframe data in binding={bindingData.BindingPath} by time.");
  253. }
  254. void ConvertData(ref List<BindingData> bindingData)
  255. {
  256. for (var i = 0; i < bindingData.Count; ++i)
  257. {
  258. bindingData[i].ConvertedKeys = ConvertKeyData(bindingData[i]);
  259. MergeKeyData(bindingData[i]);
  260. RepairMissingKeyData(bindingData[i]);
  261. }
  262. }
  263. List<ConvertedKeyData> ConvertKeyData(BindingData bindingData)
  264. {
  265. var keyData = bindingData.RawKeys;
  266. var convertedData = new List<ConvertedKeyData>();
  267. for (var i = 0; i < keyData.Count; ++i)
  268. {
  269. switch (keyData[i].HashType)
  270. {
  271. case HashType.SpriteHash:
  272. convertedData.Add(ConvertSpriteHash(keyData[i]));
  273. break;
  274. case HashType.SpriteKey:
  275. convertedData.Add(ConvertSpriteKey(keyData[i]));
  276. break;
  277. case HashType.Category:
  278. convertedData.Add(ConvertSpriteCategory(keyData[i]));
  279. break;
  280. case HashType.Label:
  281. convertedData.Add(ConvertSpriteLabel(keyData[i]));
  282. break;
  283. }
  284. if(convertedData[i].Category == string.Empty && convertedData[i].Label == string.Empty)
  285. m_Logger.Add($"Conversion of key={i} of type={keyData[i].HashType} for binding={bindingData.BindingPath} failed to resolve Category and Label values from the Sprite Libraries in the project.");
  286. }
  287. m_Logger.Add($"Converting keyframes into uniformed format for binding={bindingData.BindingPath}");
  288. return convertedData;
  289. }
  290. static ConvertedKeyData ConvertSpriteHash(KeyData keyData)
  291. {
  292. var spriteHash = InternalEngineBridge.ConvertFloatToInt(keyData.Value);
  293. SpriteHashToCategoryAndLabelName(spriteHash, out var categoryName, out var labelName);
  294. var convertedData = new ConvertedKeyData()
  295. {
  296. Time = keyData.Time,
  297. Value = keyData.Value,
  298. Category = categoryName,
  299. Label = labelName
  300. };
  301. return convertedData;
  302. }
  303. static ConvertedKeyData ConvertSpriteKey(KeyData keyData)
  304. {
  305. var newHash = InternalEngineBridge.ConvertFloatToInt(keyData.Value);
  306. var spriteHash = SpriteLibraryUtility.Convert32BitTo30BitHash(newHash);
  307. SpriteHashToCategoryAndLabelName(spriteHash, out var categoryName, out var labelName);
  308. var convertedData = new ConvertedKeyData()
  309. {
  310. Time = keyData.Time,
  311. Value = InternalEngineBridge.ConvertIntToFloat(spriteHash),
  312. Category = categoryName,
  313. Label = labelName
  314. };
  315. return convertedData;
  316. }
  317. static ConvertedKeyData ConvertSpriteCategory(KeyData keyData)
  318. {
  319. var newHash = InternalEngineBridge.ConvertFloatToInt(keyData.Value);
  320. var categoryHash = SpriteLibraryUtility.Convert32BitTo30BitHash(newHash);
  321. CategoryHashToCategoryName(categoryHash, out var categoryName);
  322. var convertedData = new ConvertedKeyData()
  323. {
  324. Time = keyData.Time,
  325. Value = 0f,
  326. Category = categoryName,
  327. Label = string.Empty
  328. };
  329. return convertedData;
  330. }
  331. static ConvertedKeyData ConvertSpriteLabel(KeyData keyData)
  332. {
  333. var newHash = InternalEngineBridge.ConvertFloatToInt(keyData.Value);
  334. var labelHash = SpriteLibraryUtility.Convert32BitTo30BitHash(newHash);
  335. LabelHashToLabelName(labelHash, out var labelName);
  336. var convertedData = new ConvertedKeyData()
  337. {
  338. Time = keyData.Time,
  339. Value = 0f,
  340. Category = string.Empty,
  341. Label = labelName
  342. };
  343. return convertedData;
  344. }
  345. static void SpriteHashToCategoryAndLabelName(int spriteHash, out string categoryName, out string labelName)
  346. {
  347. var spriteLibraryAssets = s_SpriteLibUpgrader.GetUpgradableAssets()
  348. .Cast<SpriteLibraryAsset>().ToArray();
  349. categoryName = string.Empty;
  350. labelName = string.Empty;
  351. foreach (var spriteLib in spriteLibraryAssets)
  352. {
  353. foreach (var category in spriteLib.categories)
  354. {
  355. foreach (var label in category.categoryList)
  356. {
  357. var combinedHash = SpriteLibrary.GetHashForCategoryAndEntry(category.name, label.name);
  358. if (combinedHash == spriteHash)
  359. {
  360. categoryName = category.name;
  361. labelName = label.name;
  362. return;
  363. }
  364. }
  365. }
  366. }
  367. }
  368. static void CategoryHashToCategoryName(int categoryHash, out string categoryName)
  369. {
  370. var spriteLibraryAssets = s_SpriteLibUpgrader.GetUpgradableAssets()
  371. .Cast<SpriteLibraryAsset>().ToArray();
  372. categoryName = string.Empty;
  373. foreach (var spriteLib in spriteLibraryAssets)
  374. {
  375. foreach (var category in spriteLib.categories)
  376. {
  377. if (category.hash == categoryHash)
  378. {
  379. categoryName = category.name;
  380. return;
  381. }
  382. }
  383. }
  384. }
  385. static void LabelHashToLabelName(int labelHash, out string labelName)
  386. {
  387. var spriteLibraryAssets = s_SpriteLibUpgrader.GetUpgradableAssets()
  388. .Cast<SpriteLibraryAsset>().ToArray();
  389. labelName = string.Empty;
  390. foreach (var spriteLib in spriteLibraryAssets)
  391. {
  392. foreach (var category in spriteLib.categories)
  393. {
  394. foreach (var label in category.categoryList)
  395. {
  396. if (label.hash == labelHash)
  397. {
  398. labelName = label.name;
  399. return;
  400. }
  401. }
  402. }
  403. }
  404. }
  405. void MergeKeyData(BindingData bindingData)
  406. {
  407. var keys = bindingData.ConvertedKeys;
  408. for (var i = 0; i < keys.Count; ++i)
  409. {
  410. var categoryName = keys[i].Category;
  411. if(categoryName == string.Empty)
  412. continue;
  413. var labelName = keys[i].Label;
  414. if (labelName != string.Empty)
  415. continue;
  416. for (var m = 0; m < keys.Count; ++m)
  417. {
  418. labelName = keys[m].Label;
  419. if(labelName == string.Empty)
  420. continue;
  421. if (Mathf.Abs(keys[i].Time - keys[m].Time) > Mathf.Epsilon)
  422. continue;
  423. keys[m].Category = categoryName;
  424. keys[i].Label = labelName;
  425. m_Logger.Add($"Merged Category={categoryName} and Label={labelName} at time={keys[i].Time} in binding={bindingData.BindingPath}.");
  426. }
  427. }
  428. }
  429. void RepairMissingKeyData(BindingData bindingData)
  430. {
  431. var keys = bindingData.ConvertedKeys;
  432. var categoryName = string.Empty;
  433. var labelName = string.Empty;
  434. for (var i = 0; i < keys.Count; ++i)
  435. {
  436. if (keys[i].Category != string.Empty)
  437. categoryName = keys[i].Category;
  438. if (keys[i].Label != string.Empty)
  439. labelName = keys[i].Label;
  440. if (keys[i].Value == 0f && categoryName == string.Empty)
  441. {
  442. m_Logger.Add($"Cannot find a category for keyframe at time={keys[i].Time} in binding={bindingData.BindingPath}.");
  443. continue;
  444. }
  445. if (keys[i].Value == 0f && labelName == string.Empty)
  446. {
  447. m_Logger.Add($"Cannot find a label for keyframe at time={keys[i].Time} in binding={bindingData.BindingPath}.");
  448. continue;
  449. }
  450. if (keys[i].Value == 0f)
  451. {
  452. var spriteHash = SpriteLibrary.GetHashForCategoryAndEntry(categoryName, labelName);
  453. keys[i].Value = InternalEngineBridge.ConvertIntToFloat(spriteHash);
  454. if (keys[i].Value != 0f)
  455. m_Logger.Add($"Combining categoryName={categoryName} labelName={labelName} into spriteHash={spriteHash}.");
  456. else
  457. m_Logger.Add($"Could not repair keyframe at time={keys[i].Time} for binding={bindingData.BindingPath}. The Sprite Library Asset might be missing.");
  458. }
  459. }
  460. }
  461. bool CleanupData(ref List<BindingData> bindingData)
  462. {
  463. foreach (var data in bindingData)
  464. {
  465. var keys = data.ConvertedKeys;
  466. var keyTimes = new List<float>();
  467. for (var i = 0; i < keys.Count; ++i)
  468. {
  469. var time = keys[i].Time;
  470. if(i == 0 || (time - keyTimes[keyTimes.Count - 1]) > Mathf.Epsilon)
  471. keyTimes.Add(time);
  472. }
  473. for (var m = keys.Count - 1; m >= 0; --m)
  474. {
  475. if(keys[m].Value == 0f)
  476. keys.RemoveAt(m);
  477. }
  478. for (var m = keys.Count - 1; m > 0; --m)
  479. {
  480. if (Mathf.Abs(keys[m].Time - keys[m - 1].Time) < Mathf.Epsilon)
  481. keys.RemoveAt(m);
  482. }
  483. if (keyTimes.Count == keys.Count)
  484. m_Logger.Add($"Cleaned up keyframes for binding={data.BindingPath}. It now has {keys.Count} keyframes.");
  485. else
  486. {
  487. m_Logger.Add($"Expected {keyTimes.Count} keyframes after cleanup for binding={data.BindingPath}, but ended up with {keys.Count}.");
  488. return false;
  489. }
  490. }
  491. return true;
  492. }
  493. void UpdateClipWithConvertedData(AnimationClip clip, List<BindingData> convertedBindings)
  494. {
  495. var destData = new EditorCurveBinding[convertedBindings.Count];
  496. for (var i = 0; i < convertedBindings.Count; ++i)
  497. destData[i] = EditorCurveBinding.DiscreteCurve(convertedBindings[i].BindingPath, convertedBindings[i].BindingType, k_SpriteHashId);
  498. var curves = new AnimationCurve[destData.Length];
  499. for (var i = 0; i < curves.Length; ++i)
  500. {
  501. var convertedKeys = convertedBindings[i].ConvertedKeys;
  502. var keyFrames = new Keyframe[convertedKeys.Count];
  503. for (var m = 0; m < keyFrames.Length; ++m)
  504. {
  505. keyFrames[m].inTangent = float.PositiveInfinity;
  506. keyFrames[m].outTangent = float.PositiveInfinity;
  507. keyFrames[m].time = convertedKeys[m].Time;
  508. keyFrames[m].value = convertedKeys[m].Value;
  509. }
  510. curves[i] = new AnimationCurve(keyFrames);
  511. }
  512. AnimationUtility.SetEditorCurves(clip, destData, curves);
  513. m_Logger.Add($"Injected updated bindings into AnimationClip={clip.name}.");
  514. }
  515. void RemoveOldData(AnimationClip clip, List<BindingData> bindingData)
  516. {
  517. var spriteKeyCurves = new EditorCurveBinding[bindingData.Count];
  518. var spriteCategoryCurves = new EditorCurveBinding[bindingData.Count];
  519. var spriteLabelCurves = new EditorCurveBinding[bindingData.Count];
  520. for (var i = 0; i < bindingData.Count; ++i)
  521. {
  522. spriteKeyCurves[i] = EditorCurveBinding.DiscreteCurve(bindingData[i].BindingPath, bindingData[i].BindingType, k_SpriteKeyId);
  523. spriteCategoryCurves[i] = EditorCurveBinding.DiscreteCurve(bindingData[i].BindingPath, bindingData[i].BindingType, k_CategoryHashId);
  524. spriteLabelCurves[i] = EditorCurveBinding.DiscreteCurve(bindingData[i].BindingPath, bindingData[i].BindingType, k_LabelHashId);
  525. }
  526. AnimationUtility.SetEditorCurves(clip, spriteKeyCurves, new AnimationCurve[spriteKeyCurves.Length]);
  527. AnimationUtility.SetEditorCurves(clip, spriteCategoryCurves, new AnimationCurve[spriteCategoryCurves.Length]);
  528. AnimationUtility.SetEditorCurves(clip, spriteLabelCurves, new AnimationCurve[spriteLabelCurves.Length]);
  529. m_Logger.Add($"Removed old bindings in AnimationClip={clip.name}.");
  530. }
  531. static float GetUpgradeProgress(List<UpgradeEntry> reports, List<ObjectIndexPair> totalNoOfObjects)
  532. {
  533. return reports.Count / (float)totalNoOfObjects.Count;
  534. }
  535. }
  536. }