RendererDataPatcher.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using System.Linq;
  2. using UnityEngine;
  3. namespace UnityEditor.Rendering.Universal
  4. {
  5. [InitializeOnLoad]
  6. class RendererDataPatcher
  7. {
  8. #region Universal Renderer Patcher Params
  9. static bool firstTimeUpgrade = true;
  10. static int editedAssetsCount = 0;
  11. static string fwdRendererScriptFilePath = AssetDatabase.GUIDToAssetPath("f971995892640ec4f807ef396269e91e"); //ForwardRendererData.cs
  12. static Object fwdRendererScriptObj;
  13. static string universalRendererScriptFilePath = AssetDatabase.GUIDToAssetPath("de640fe3d0db1804a85f9fc8f5cadab6"); //UniversalRendererData.cs
  14. static Object universalRendererScriptObj;
  15. #endregion
  16. static RendererDataPatcher()
  17. {
  18. UniversalRendererPatcher();
  19. }
  20. #region Universal Renderer Patcher
  21. /// <summary>
  22. /// Patcher for fixing UniversalRendererData Scriptable Objects that were made in Unity 2021.2 Alpha & Beta
  23. /// </summary>
  24. static void UniversalRendererPatcher()
  25. {
  26. string[] allRenderers = AssetDatabase.FindAssets("t:ForwardRendererData glob:\"**/*.asset\"", null);
  27. foreach (var t in allRenderers)
  28. {
  29. string rendererDataPath = AssetDatabase.GUIDToAssetPath(t);
  30. var assetType = AssetDatabase.GetMainAssetTypeAtPath(rendererDataPath);
  31. if (assetType == null) continue;
  32. if (assetType.ToString().Contains("Universal.ForwardRendererData"))
  33. {
  34. IterateSubAssets(rendererDataPath);
  35. }
  36. }
  37. //Putting in delayCall will make sure AssetDatabase is ready for the FindAssets search below
  38. EditorApplication.delayCall += () =>
  39. {
  40. //This helps to scan the RendererData Assets which are subAssets caused by case 1214779
  41. if (firstTimeUpgrade)
  42. {
  43. string[] allRenderers = AssetDatabase.FindAssets("t:ForwardRendererData glob:\"**/*.asset\"", null);
  44. foreach (var t in allRenderers)
  45. {
  46. string rendererDataPath = AssetDatabase.GUIDToAssetPath(t);
  47. IterateSubAssets(rendererDataPath);
  48. }
  49. firstTimeUpgrade = false;
  50. }
  51. //If there is no asset upgraded then we don't need to do the following
  52. if (editedAssetsCount == 0) return;
  53. //Gets all the UniversalRenderPipeline Assets in project
  54. string[] allURPassets =
  55. AssetDatabase.FindAssets("t:UniversalRenderPipelineAsset glob:\"**/*.asset\"", null);
  56. foreach (var t in allURPassets)
  57. {
  58. string pipelineAssetPath = AssetDatabase.GUIDToAssetPath(t);
  59. Object pipelineAsset = AssetDatabase.LoadAssetAtPath(pipelineAssetPath, typeof(Object));
  60. SerializedObject soAsset = new SerializedObject(pipelineAsset);
  61. //Make some changes on the Pipeline assets
  62. //If we don't do this, the pipeline assets won't recognise the changed renderer "type", so will give "no Default Renderer asset" error and nothing will render
  63. SerializedProperty scriptPropertyAsset = soAsset.FindProperty("m_RequireDepthTexture");
  64. soAsset.Update();
  65. if (scriptPropertyAsset == null) continue;
  66. bool tmp = scriptPropertyAsset.boolValue;
  67. scriptPropertyAsset.boolValue = !scriptPropertyAsset.boolValue; //make the changes
  68. soAsset.ApplyModifiedProperties();
  69. scriptPropertyAsset.boolValue = tmp; //revert the changes
  70. soAsset.ApplyModifiedProperties();
  71. EditorUtility.SetDirty(pipelineAsset);
  72. }
  73. //Reset counter and register state
  74. Debug.LogWarning($"URP Renderer(s) have been upgraded, please remember to save your project to write the upgrade to disk.");
  75. editedAssetsCount = 0;
  76. };
  77. }
  78. static bool UpgradeAsset(Object rendererData, string rendererDataPath)
  79. {
  80. if (rendererData == null) return false;
  81. //Gets the script file objects
  82. if (!fwdRendererScriptObj) fwdRendererScriptObj = AssetDatabase.LoadAssetAtPath(fwdRendererScriptFilePath, typeof(Object));
  83. if (!universalRendererScriptObj) universalRendererScriptObj = AssetDatabase.LoadAssetAtPath(universalRendererScriptFilePath, typeof(Object));
  84. //Double check to see if it's using ForwardRendererData
  85. SerializedObject so = new SerializedObject(rendererData);
  86. SerializedProperty scriptProperty = so.FindProperty("m_Script");
  87. if (scriptProperty == null || scriptProperty.objectReferenceValue != fwdRendererScriptObj) return false;
  88. //Write debug warning out before renderer is switched and data is nullified
  89. Debug.LogWarning($"Upgraded renderer {rendererData.name} at {rendererDataPath}.\nYou should only see this if you are upgrading from 2021.2 Alpha/Beta cycle.");
  90. //Change the script to use UniversalRendererData
  91. so.Update();
  92. scriptProperty.objectReferenceValue = universalRendererScriptObj;
  93. so.ApplyModifiedProperties();
  94. //Re-import asset
  95. //This prevents the "Importer(NativeFormatImporter) generated inconsistent result" warning
  96. AssetDatabase.ImportAsset(rendererDataPath);
  97. editedAssetsCount++;
  98. return true;
  99. }
  100. static void IterateSubAssets(string assetPath)
  101. {
  102. //To prevent infinite importing loop caused by corrupted assets which are created from old bugs e.g. case 1214779
  103. Object[] subAssets = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
  104. if (subAssets.Any(t => UpgradeAsset(t, assetPath))) return;
  105. //Upgrade the main Asset
  106. Object rendererData = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object));
  107. UpgradeAsset(rendererData, assetPath);
  108. }
  109. #endregion
  110. }
  111. }