NodeEditorAssetModProcessor.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using UnityEditor;
  2. using UnityEngine;
  3. using System.IO;
  4. namespace XNodeEditor {
  5. /// <summary> Deals with modified assets </summary>
  6. class NodeEditorAssetModProcessor : UnityEditor.AssetModificationProcessor {
  7. /// <summary> Automatically delete Node sub-assets before deleting their script.
  8. /// This is important to do, because you can't delete null sub assets.
  9. /// <para/> For another workaround, see: https://gitlab.com/RotaryHeart-UnityShare/subassetmissingscriptdelete </summary>
  10. private static AssetDeleteResult OnWillDeleteAsset (string path, RemoveAssetOptions options) {
  11. // Skip processing anything without the .cs extension
  12. if (Path.GetExtension(path) != ".cs") return AssetDeleteResult.DidNotDelete;
  13. // Get the object that is requested for deletion
  14. UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object> (path);
  15. // If we aren't deleting a script, return
  16. if (!(obj is UnityEditor.MonoScript)) return AssetDeleteResult.DidNotDelete;
  17. // Check script type. Return if deleting a non-node script
  18. UnityEditor.MonoScript script = obj as UnityEditor.MonoScript;
  19. System.Type scriptType = script.GetClass ();
  20. if (scriptType == null || (scriptType != typeof (XNode.Node) && !scriptType.IsSubclassOf (typeof (XNode.Node)))) return AssetDeleteResult.DidNotDelete;
  21. // Find all ScriptableObjects using this script
  22. string[] guids = AssetDatabase.FindAssets ("t:" + scriptType);
  23. for (int i = 0; i < guids.Length; i++) {
  24. string assetpath = AssetDatabase.GUIDToAssetPath (guids[i]);
  25. Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath (assetpath);
  26. for (int k = 0; k < objs.Length; k++) {
  27. XNode.Node node = objs[k] as XNode.Node;
  28. if (node.GetType () == scriptType) {
  29. if (node != null && node.graph != null) {
  30. // Delete the node and notify the user
  31. Debug.LogWarning (node.name + " of " + node.graph + " depended on deleted script and has been removed automatically.", node.graph);
  32. node.graph.RemoveNode (node);
  33. }
  34. }
  35. }
  36. }
  37. // We didn't actually delete the script. Tell the internal system to carry on with normal deletion procedure
  38. return AssetDeleteResult.DidNotDelete;
  39. }
  40. /// <summary> Automatically re-add loose node assets to the Graph node list </summary>
  41. [InitializeOnLoadMethod]
  42. private static void OnReloadEditor () {
  43. // Find all NodeGraph assets
  44. string[] guids = AssetDatabase.FindAssets ("t:" + typeof (XNode.NodeGraph));
  45. for (int i = 0; i < guids.Length; i++) {
  46. string assetpath = AssetDatabase.GUIDToAssetPath (guids[i]);
  47. XNode.NodeGraph graph = AssetDatabase.LoadAssetAtPath (assetpath, typeof (XNode.NodeGraph)) as XNode.NodeGraph;
  48. graph.nodes.RemoveAll(x => x == null); //Remove null items
  49. Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath (assetpath);
  50. // Ensure that all sub node assets are present in the graph node list
  51. for (int u = 0; u < objs.Length; u++) {
  52. // Ignore null sub assets
  53. if (objs[u] == null) continue;
  54. if (!graph.nodes.Contains (objs[u] as XNode.Node)) graph.nodes.Add(objs[u] as XNode.Node);
  55. }
  56. }
  57. }
  58. }
  59. }