VFXBlockProvider.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. namespace UnityEditor.VFX.UI
  6. {
  7. abstract class VFXAbstractProvider<T> : VFXFilterWindow.IProvider
  8. {
  9. Action<T, Vector2> m_onSpawnDesc;
  10. protected class VFXBlockElement : VFXFilterWindow.Element
  11. {
  12. public T descriptor { get; private set; }
  13. public VFXBlockElement(int level, T desc, string category, string name)
  14. {
  15. this.level = level;
  16. var str = name;
  17. if (!string.IsNullOrEmpty(category))
  18. str += " (" + category.Replace("/", " ") + ") ";
  19. content = new GUIContent(str /*, VFXEditor.styles.GetIcon(desc.Icon)*/);
  20. descriptor = desc;
  21. }
  22. }
  23. protected VFXAbstractProvider(Action<T, Vector2> onSpawnDesc)
  24. {
  25. m_onSpawnDesc = onSpawnDesc;
  26. }
  27. protected abstract IEnumerable<T> GetDescriptors();
  28. protected abstract string GetName(T desc);
  29. protected abstract string GetCategory(T desc);
  30. protected abstract string title
  31. {
  32. get;
  33. }
  34. public void CreateComponentTree(List<VFXFilterWindow.Element> tree)
  35. {
  36. tree.Add(new VFXFilterWindow.GroupElement(0, title));
  37. var descriptors = GetDescriptors();
  38. var depth = 1;
  39. string prevCategory = "";
  40. var prevSplit = new string[0];
  41. var noCategory = new List<T>();
  42. foreach (var desc in descriptors)
  43. {
  44. var category = GetCategory(desc);
  45. if (string.IsNullOrEmpty(category))
  46. {
  47. noCategory.Add(desc);
  48. continue;
  49. }
  50. if (category != prevCategory)
  51. {
  52. var split = category.Split('/').Where(o => o != "").ToArray();
  53. for (int i = 0; i < split.Length; i++)
  54. {
  55. if (i >= prevSplit.Length || (i < prevSplit.Length && split[i] != prevSplit[i]))
  56. {
  57. depth = i + 1;
  58. tree.Add(new VFXFilterWindow.GroupElement(depth, split[i]));
  59. }
  60. }
  61. prevCategory = category;
  62. prevSplit = split;
  63. }
  64. tree.Add(new VFXBlockElement(depth + 1, desc, category, GetName(desc)));
  65. }
  66. noCategory.ForEach(x => tree.Add(new VFXBlockElement(1, x, string.Empty, GetName(x))));
  67. }
  68. public bool GoToChild(VFXFilterWindow.Element element, bool addIfComponent)
  69. {
  70. if (element is VFXBlockElement)
  71. {
  72. var blockElem = element as VFXBlockElement;
  73. m_onSpawnDesc(blockElem.descriptor, position);
  74. return true;
  75. }
  76. return false;
  77. }
  78. public Vector2 position
  79. {
  80. get; set;
  81. }
  82. }
  83. class VFXBlockProvider : VFXAbstractProvider<VFXBlockProvider.Descriptor>
  84. {
  85. public abstract class Descriptor
  86. {
  87. public abstract string category { get; }
  88. public abstract string name { get; }
  89. }
  90. public class NewBlockDescriptor : Descriptor
  91. {
  92. public readonly VFXModelDescriptor<VFXBlock> newBlock;
  93. public NewBlockDescriptor(VFXModelDescriptor<VFXBlock> newBlock)
  94. {
  95. this.newBlock = newBlock;
  96. }
  97. public override string category { get { return newBlock.info.category; } }
  98. public override string name { get { return newBlock.name; } }
  99. }
  100. public class SubgraphBlockDescriptor : Descriptor
  101. {
  102. public readonly SubGraphCache.Item item;
  103. public SubgraphBlockDescriptor(SubGraphCache.Item item)
  104. {
  105. this.item = item;
  106. }
  107. public override string category { get { return item.category; } }
  108. public override string name { get { return item.name; } }
  109. }
  110. VFXContextController m_ContextController;
  111. public VFXBlockProvider(VFXContextController context, Action<Descriptor, Vector2> onAddBlock) : base(onAddBlock)
  112. {
  113. m_ContextController = context;
  114. }
  115. protected override string GetCategory(VFXBlockProvider.Descriptor desc)
  116. {
  117. return desc.category;
  118. }
  119. protected override string GetName(VFXBlockProvider.Descriptor desc)
  120. {
  121. return desc.name;
  122. }
  123. protected override string title
  124. {
  125. get { return "Block"; }
  126. }
  127. protected override IEnumerable<VFXBlockProvider.Descriptor> GetDescriptors()
  128. {
  129. return VFXLibrary.GetBlocks()
  130. .Where(b => b.AcceptParent(m_ContextController.model))
  131. .Select(t => (Descriptor)new NewBlockDescriptor(t))
  132. .Concat(SubGraphCache.GetItems(typeof(VisualEffectSubgraphBlock))
  133. .Where(t =>
  134. (((SubGraphCache.AdditionalBlockInfo)t.additionalInfos).compatibleType &
  135. m_ContextController.model.contextType) != 0 &&
  136. (((SubGraphCache.AdditionalBlockInfo)t.additionalInfos).compatibleData &
  137. m_ContextController.model.ownedType) != 0)
  138. .Select(t => (Descriptor)new SubgraphBlockDescriptor(t)))
  139. .OrderBy(x => x.category)
  140. .ThenBy(x => x.name);
  141. }
  142. }
  143. }