No Description
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.

ShaderGraphAssetPostProcessor.cs 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using UnityEngine;
  2. using System;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor;
  6. using UnityEditor.ShaderGraph.Drawing;
  7. namespace UnityEditor.ShaderGraph
  8. {
  9. class ShaderGraphAssetPostProcessor : AssetPostprocessor
  10. {
  11. static void RegisterShaders(string[] paths)
  12. {
  13. foreach (var path in paths)
  14. {
  15. if (!path.EndsWith(ShaderGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase))
  16. continue;
  17. var mainObj = AssetDatabase.LoadMainAssetAtPath(path);
  18. if (mainObj is Shader)
  19. ShaderUtil.RegisterShader((Shader)mainObj);
  20. var objs = AssetDatabase.LoadAllAssetRepresentationsAtPath(path);
  21. foreach (var obj in objs)
  22. {
  23. if (obj is Shader)
  24. ShaderUtil.RegisterShader((Shader)obj);
  25. }
  26. }
  27. }
  28. static void UpdateAfterAssetChange(string[] newNames)
  29. {
  30. // This will change the title of the window.
  31. MaterialGraphEditWindow[] windows = Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>();
  32. foreach (var matGraphEditWindow in windows)
  33. {
  34. for (int i = 0; i < newNames.Length; ++i)
  35. {
  36. if (matGraphEditWindow.selectedGuid == AssetDatabase.AssetPathToGUID(newNames[i]))
  37. matGraphEditWindow.UpdateTitle();
  38. }
  39. }
  40. }
  41. static void DisplayDeletionDialog(string[] deletedAssets)
  42. {
  43. MaterialGraphEditWindow[] windows = Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>();
  44. foreach (var matGraphEditWindow in windows)
  45. {
  46. for (int i = 0; i < deletedAssets.Length; ++i)
  47. {
  48. if (matGraphEditWindow.selectedGuid == AssetDatabase.AssetPathToGUID(deletedAssets[i]))
  49. matGraphEditWindow.AssetWasDeleted();
  50. }
  51. }
  52. }
  53. void OnPreprocessAsset()
  54. {
  55. ShaderGraphImporter sgImporter = assetImporter as ShaderGraphImporter;
  56. if (sgImporter != null)
  57. {
  58. // Before importing, clear shader messages for any existing old shaders, if any.
  59. // This is a terrible way to do it, but currently how the shader message system works at the moment.
  60. // to workaround a bug with LoadAllAssetsAtPath(), which crashes if the asset has not yet been imported
  61. // we first call LoadAssetAtPath<>, which handles assets not yet imported by returning null
  62. if (AssetDatabase.LoadAssetAtPath<Shader>(assetPath) != null)
  63. {
  64. var oldArtifacts = AssetDatabase.LoadAllAssetsAtPath(assetPath);
  65. foreach (var artifact in oldArtifacts)
  66. {
  67. if ((artifact != null) && (artifact is Shader oldShader))
  68. {
  69. ShaderUtil.ClearShaderMessages(oldShader);
  70. }
  71. }
  72. }
  73. }
  74. }
  75. static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
  76. {
  77. RegisterShaders(importedAssets);
  78. // Moved assets
  79. bool anyMovedShaders = movedAssets.Any(val => val.EndsWith(ShaderGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase));
  80. anyMovedShaders |= movedAssets.Any(val => val.EndsWith(ShaderSubGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase));
  81. if (anyMovedShaders)
  82. UpdateAfterAssetChange(movedAssets);
  83. // Deleted assets
  84. bool anyRemovedShaders = deletedAssets.Any(val => val.EndsWith(ShaderGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase));
  85. anyRemovedShaders |= deletedAssets.Any(val => val.EndsWith(ShaderSubGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase));
  86. if (anyRemovedShaders)
  87. DisplayDeletionDialog(deletedAssets);
  88. var changedGraphGuids = importedAssets
  89. .Where(x => x.EndsWith(ShaderGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase)
  90. || x.EndsWith(ShaderSubGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase))
  91. .Select(AssetDatabase.AssetPathToGUID)
  92. .ToList();
  93. MaterialGraphEditWindow[] windows = null;
  94. if (changedGraphGuids.Count > 0)
  95. {
  96. windows = Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>();
  97. foreach (var window in windows)
  98. {
  99. if (changedGraphGuids.Contains(window.selectedGuid))
  100. {
  101. window.CheckForChanges();
  102. }
  103. }
  104. }
  105. // moved or imported subgraphs or HLSL files should notify open shadergraphs that they need to handle them
  106. var changedFileGUIDs = movedAssets.Concat(importedAssets).Concat(deletedAssets)
  107. .Where(x =>
  108. {
  109. if (x.EndsWith(ShaderSubGraphImporter.Extension, StringComparison.InvariantCultureIgnoreCase) || CustomFunctionNode.s_ValidExtensions.Contains(Path.GetExtension(x)))
  110. {
  111. return true;
  112. }
  113. else
  114. {
  115. var asset = AssetDatabase.GetMainAssetTypeAtPath(x);
  116. return asset is null || asset.IsSubclassOf(typeof(Texture));
  117. }
  118. })
  119. .Select(AssetDatabase.AssetPathToGUID)
  120. .Distinct()
  121. .ToList();
  122. if (changedFileGUIDs.Count > 0)
  123. {
  124. if (windows == null)
  125. {
  126. windows = Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>();
  127. }
  128. foreach (var window in windows)
  129. {
  130. window.ReloadSubGraphsOnNextUpdate(changedFileGUIDs);
  131. }
  132. }
  133. }
  134. }
  135. }