暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

VisibilityTool.cs 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. using System;
  2. using UnityEngine.U2D.Common;
  3. using UnityEditor.U2D.Common;
  4. using UnityEditor.U2D.Layout;
  5. using System.Collections.Generic;
  6. using UnityEngine.UIElements;
  7. namespace UnityEditor.U2D.Animation
  8. {
  9. #if ENABLE_UXML_SERIALIZED_DATA
  10. [UxmlElement]
  11. #endif
  12. internal partial class VisibilityToolWindow : VisualElement, IVisibilityToolWindow
  13. {
  14. #if ENABLE_UXML_TRAITS
  15. public class CustomUxmlFactory : UxmlFactory<VisibilityToolWindow, UxmlTraits> {}
  16. #endif
  17. VisualElement m_SelectorContainer;
  18. VisualElement m_Container;
  19. Slider m_BoneOpacitySlider;
  20. Slider m_MeshOpacitySlider;
  21. private LayoutOverlay m_Layout;
  22. List<Button> m_Tabs;
  23. int m_CurrentSelectedTab = 0;
  24. public event Action<float> onBoneOpacitySliderChange = (f) => {};
  25. public event Action<float> onMeshOpacitySliderChange = (f) => {};
  26. public event Action onBoneOpacitySliderChangeBegin = () => {};
  27. public event Action onBoneOpacitySliderChangeEnd = () => {};
  28. public event Action onMeshOpacitySliderChangeBegin = () => {};
  29. public event Action onMeshOpacitySliderChangeEnd = () => {};
  30. public static VisibilityToolWindow CreateFromUXML()
  31. {
  32. var visualTree = ResourceLoader.Load<VisualTreeAsset>("SkinningModule/VisibilityToolWindow.uxml");
  33. var ve = visualTree.CloneTree().Q("VisibilityToolWindow") as VisibilityToolWindow;
  34. var resizer = ve.Q("Resizer");
  35. resizer.AddManipulator(new VisibilityToolResizer());
  36. ve.styleSheets.Add(ResourceLoader.Load<StyleSheet>("SkinningModule/VisibilityTool.uss"));
  37. if (EditorGUIUtility.isProSkin)
  38. ve.AddToClassList("Dark");
  39. ve.LocalizeTextInChildren();
  40. ve.BindElements();
  41. return ve;
  42. }
  43. public void BindElements()
  44. {
  45. m_SelectorContainer = this.Q("VisibilityToolSelection");
  46. m_Container = this.Q("VisibilityToolContainer");
  47. m_BoneOpacitySlider = this.Q<Slider>("BoneOpacitySlider");
  48. m_BoneOpacitySlider.RegisterValueChangedCallback(OnBoneOpacitySliderValueChangd);
  49. m_MeshOpacitySlider = this.Q<Slider>("MeshOpacitySlider");
  50. m_MeshOpacitySlider.RegisterValueChangedCallback(OnMeshOpacitySliderValueChangd);
  51. RegisterCallback<MouseDownEvent>(OpacityChangeBegin, TrickleDown.TrickleDown);
  52. RegisterCallback<MouseCaptureOutEvent>(OpacityChangeEnd, TrickleDown.TrickleDown);
  53. // case 1200857 StopPropagation when bubbling up so that main IMGUI doesn't get the event
  54. RegisterCallback<MouseDownEvent>(evt => evt.StopPropagation());
  55. m_Tabs = new List<Button>();
  56. m_SelectorContainer.Clear();
  57. }
  58. public void Initialize(LayoutOverlay layout)
  59. {
  60. m_Layout = layout;
  61. layout.rightOverlay.Add(this);
  62. Hide();
  63. }
  64. public void Show()
  65. {
  66. m_Container.Clear();
  67. this.SetHiddenFromLayout(false);
  68. m_Layout.VisibilityWindowOn(true);
  69. }
  70. public void Hide()
  71. {
  72. m_Container.Clear();
  73. this.SetHiddenFromLayout(true);
  74. m_Layout.VisibilityWindowOn(false);
  75. }
  76. bool IsOpacityTarget(IEventHandler target, VisualElement opacityTarget)
  77. {
  78. var ve = target as VisualElement;
  79. while (ve != null && ve != this)
  80. {
  81. if (ve == opacityTarget)
  82. return true;
  83. ve = ve.parent;
  84. }
  85. return false;
  86. }
  87. void OpacityChangeBegin(MouseDownEvent evt)
  88. {
  89. if (IsOpacityTarget(evt.target, m_BoneOpacitySlider))
  90. onBoneOpacitySliderChangeBegin();
  91. else if (IsOpacityTarget(evt.target, m_MeshOpacitySlider))
  92. onMeshOpacitySliderChangeBegin();
  93. }
  94. void OpacityChangeEnd(MouseCaptureOutEvent evt)
  95. {
  96. if (IsOpacityTarget(evt.target, m_BoneOpacitySlider))
  97. onBoneOpacitySliderChangeEnd();
  98. else if (IsOpacityTarget(evt.target, m_MeshOpacitySlider))
  99. onMeshOpacitySliderChangeEnd();
  100. }
  101. void OnBoneOpacitySliderValueChangd(ChangeEvent<float> evt)
  102. {
  103. onBoneOpacitySliderChange(evt.newValue);
  104. }
  105. void OnMeshOpacitySliderValueChangd(ChangeEvent<float> evt)
  106. {
  107. onMeshOpacitySliderChange(evt.newValue);
  108. }
  109. public void SetBoneOpacitySliderValue(float value)
  110. {
  111. m_BoneOpacitySlider.value = value;
  112. m_BoneOpacitySlider.MarkDirtyRepaint();
  113. }
  114. public void SetMeshOpacitySliderValue(float value)
  115. {
  116. m_MeshOpacitySlider.value = value;
  117. m_MeshOpacitySlider.MarkDirtyRepaint();
  118. }
  119. public void AddToolTab(string name, Action onClick)
  120. {
  121. var tab = new Button()
  122. {
  123. text = name
  124. };
  125. tab.AddToClassList("visibilityToolTab");
  126. if (EditorGUIUtility.isProSkin)
  127. tab.AddToClassList("visibilityToolTabDark");
  128. m_SelectorContainer.Add(tab);
  129. m_Tabs.Add(tab);
  130. tab.clickable.clicked += onClick;
  131. }
  132. public void SetActiveTab(int toolIndex)
  133. {
  134. if (m_Tabs.Count > toolIndex && toolIndex >= 0)
  135. {
  136. m_Tabs[m_CurrentSelectedTab].SetChecked(false);
  137. m_Tabs[toolIndex].SetChecked(true);
  138. m_CurrentSelectedTab = toolIndex;
  139. }
  140. }
  141. public void SetContent(VisualElement content)
  142. {
  143. m_Container.Clear();
  144. m_Container.Add(content);
  145. }
  146. public void SetToolAvailable(int toolIndex, bool available)
  147. {
  148. if (m_Tabs.Count > toolIndex && toolIndex >= 0)
  149. {
  150. m_Tabs[toolIndex].SetHiddenFromLayout(!available);
  151. if (available == false && toolIndex == m_CurrentSelectedTab)
  152. m_Container.Clear();
  153. }
  154. }
  155. }
  156. internal class VisibilityTool : BaseTool, IVisibilityToolModel
  157. {
  158. private VisibilityToolWindow m_ToolView;
  159. private MeshPreviewBehaviour m_MeshPreviewBehaviour = new MeshPreviewBehaviour();
  160. public SkeletonTool skeletonTool { set; private get; }
  161. VisibilityToolController m_Controller;
  162. internal override void OnCreate()
  163. {
  164. m_ToolView = VisibilityToolWindow.CreateFromUXML();
  165. m_Controller = new VisibilityToolController(this, new IVisibilityTool[]
  166. {
  167. new BoneVisibilityTool(skinningCache),
  168. new SpriteVisibilityTool(skinningCache)
  169. },
  170. () => skeletonTool,
  171. () => previewBehaviour);
  172. }
  173. public override IMeshPreviewBehaviour previewBehaviour
  174. {
  175. get { return m_MeshPreviewBehaviour; }
  176. }
  177. public override void Initialize(LayoutOverlay layout)
  178. {
  179. m_ToolView.Initialize(layout);
  180. }
  181. protected override void OnGUI()
  182. {
  183. skeletonTool.skeletonStyle = SkeletonStyles.WeightMap;
  184. skeletonTool.mode = SkeletonMode.EditPose;
  185. skeletonTool.editBindPose = false;
  186. skeletonTool.DoGUI();
  187. }
  188. protected override void OnActivate()
  189. {
  190. m_MeshPreviewBehaviour.showWeightMap = true;
  191. m_Controller.Activate();
  192. }
  193. protected override void OnDeactivate()
  194. {
  195. m_Controller.Deactivate();
  196. }
  197. int IVisibilityToolModel.currentToolIndex
  198. {
  199. get
  200. {
  201. return skinningCache.visibilityToolIndex;
  202. }
  203. set
  204. {
  205. skinningCache.visibilityToolIndex = value;
  206. }
  207. }
  208. float IVisibilityToolModel.boneOpacityValue
  209. {
  210. get
  211. {
  212. return VisibilityToolSettings.boneOpacity;
  213. }
  214. set
  215. {
  216. VisibilityToolSettings.boneOpacity = value;
  217. }
  218. }
  219. float IVisibilityToolModel.meshOpacityValue
  220. {
  221. get
  222. {
  223. return VisibilityToolSettings.meshOpacity;
  224. }
  225. set
  226. {
  227. VisibilityToolSettings.meshOpacity = value;
  228. }
  229. }
  230. UndoScope IVisibilityToolModel.UndoScope(string value)
  231. {
  232. return skinningCache.UndoScope(value);
  233. }
  234. void IVisibilityToolModel.BeginUndoOperation(string value)
  235. {
  236. skinningCache.BeginUndoOperation(value);
  237. }
  238. IVisibilityToolWindow IVisibilityToolModel.view { get { return m_ToolView;} }
  239. SkinningCache IVisibilityToolModel.skinningCache { get { return skinningCache;} }
  240. }
  241. internal interface IVisibilityToolModel
  242. {
  243. int currentToolIndex { get; set; }
  244. float meshOpacityValue { get; set; }
  245. float boneOpacityValue { get; set; }
  246. UndoScope UndoScope(string value);
  247. void BeginUndoOperation(string value);
  248. IVisibilityToolWindow view { get; }
  249. SkinningCache skinningCache { get; }
  250. }
  251. internal interface IVisibilityToolWindow
  252. {
  253. void AddToolTab(string name, Action callback);
  254. void SetToolAvailable(int i, bool available);
  255. void SetBoneOpacitySliderValue(float value);
  256. void SetMeshOpacitySliderValue(float value);
  257. event Action<float> onBoneOpacitySliderChange;
  258. event Action<float> onMeshOpacitySliderChange;
  259. event Action onBoneOpacitySliderChangeBegin;
  260. event Action onBoneOpacitySliderChangeEnd;
  261. event Action onMeshOpacitySliderChangeBegin;
  262. event Action onMeshOpacitySliderChangeEnd;
  263. void Show();
  264. void Hide();
  265. void SetActiveTab(int index);
  266. void SetContent(VisualElement content);
  267. }
  268. internal class VisibilityToolController
  269. {
  270. IVisibilityTool[] m_Tools;
  271. IVisibilityToolModel m_Model;
  272. Func<SkeletonTool> m_SkeletonTool;
  273. Func<IMeshPreviewBehaviour> m_MeshPreviewBehaviour;
  274. bool m_DeactivateBoneaTool = false;
  275. private IVisibilityTool currentTool
  276. {
  277. get { return m_Model.currentToolIndex == -1 ? null : m_Tools[m_Model.currentToolIndex]; }
  278. set { m_Model.currentToolIndex = value == null ? -1 : Array.FindIndex(m_Tools, x => x == value); }
  279. }
  280. private IVisibilityTool defaultTool
  281. {
  282. get { return Array.Find(m_Tools, t => t.isAvailable); }
  283. }
  284. public VisibilityToolController(IVisibilityToolModel model, IVisibilityTool[] tools, Func<SkeletonTool> skeletonTool = null, Func<IMeshPreviewBehaviour> meshPreviewBehaviour = null)
  285. {
  286. m_Model = model;
  287. m_Tools = tools;
  288. for (int i = 0; i < m_Tools.Length; ++i)
  289. {
  290. int index = i;
  291. var tool = m_Tools[i];
  292. tool.SetAvailabilityChangeCallback(() => OnToolAvailabilityChange(index));
  293. tool.Setup();
  294. model.view.AddToolTab(tool.name, () => ActivateToolWithUndo(tool));
  295. model.view.SetToolAvailable(i, tool.isAvailable);
  296. }
  297. m_SkeletonTool = skeletonTool;
  298. m_MeshPreviewBehaviour = meshPreviewBehaviour;
  299. }
  300. public void Activate()
  301. {
  302. m_Model.view.Show();
  303. if (currentTool == null)
  304. currentTool = defaultTool;
  305. ActivateTool(currentTool);
  306. m_Model.view.SetBoneOpacitySliderValue(m_Model.boneOpacityValue);
  307. m_Model.view.SetMeshOpacitySliderValue(m_Model.meshOpacityValue);
  308. m_Model.view.onBoneOpacitySliderChange -= OnBoneOpacityChange;
  309. m_Model.view.onMeshOpacitySliderChange -= OnMeshOpacityChange;
  310. m_Model.view.onBoneOpacitySliderChange += OnBoneOpacityChange;
  311. m_Model.view.onMeshOpacitySliderChange += OnMeshOpacityChange;
  312. m_Model.view.onBoneOpacitySliderChangeBegin -= OnBoneOpacityChangeBegin;
  313. m_Model.view.onBoneOpacitySliderChangeBegin += OnBoneOpacityChangeBegin;
  314. m_Model.view.onBoneOpacitySliderChangeEnd -= OnBoneOpacityChangeEnd;
  315. m_Model.view.onBoneOpacitySliderChangeEnd += OnBoneOpacityChangeEnd;
  316. m_Model.view.onMeshOpacitySliderChangeBegin -= OnMeshOpacityChangeBegin;
  317. m_Model.view.onMeshOpacitySliderChangeBegin += OnMeshOpacityChangeBegin;
  318. m_Model.view.onMeshOpacitySliderChangeEnd -= OnMeshOpacityChangeEnd;
  319. m_Model.view.onMeshOpacitySliderChangeEnd += OnMeshOpacityChangeEnd;
  320. }
  321. public void Deactivate()
  322. {
  323. m_Model.view.Hide();
  324. if (currentTool != null)
  325. currentTool.Deactivate();
  326. m_Model.view.onBoneOpacitySliderChange -= OnBoneOpacityChange;
  327. m_Model.view.onMeshOpacitySliderChange -= OnMeshOpacityChange;
  328. m_Model.view.onBoneOpacitySliderChangeBegin -= OnBoneOpacityChangeBegin;
  329. m_Model.view.onBoneOpacitySliderChangeEnd -= OnBoneOpacityChangeEnd;
  330. m_Model.view.onMeshOpacitySliderChangeBegin -= OnMeshOpacityChangeBegin;
  331. m_Model.view.onMeshOpacitySliderChangeEnd -= OnMeshOpacityChangeEnd;
  332. }
  333. void OnBoneOpacityChangeBegin()
  334. {
  335. if (m_SkeletonTool != null && m_SkeletonTool() != null && !m_SkeletonTool().isActive)
  336. {
  337. m_SkeletonTool().Activate();
  338. m_DeactivateBoneaTool = true;
  339. }
  340. }
  341. void OnBoneOpacityChangeEnd()
  342. {
  343. if (m_SkeletonTool != null && m_SkeletonTool() != null && m_SkeletonTool().isActive && m_DeactivateBoneaTool)
  344. m_SkeletonTool().Deactivate();
  345. }
  346. void OnMeshOpacityChangeBegin()
  347. {
  348. m_Model.skinningCache.events.meshPreviewBehaviourChange.Invoke(m_MeshPreviewBehaviour());
  349. }
  350. void OnMeshOpacityChangeEnd()
  351. {
  352. m_Model.skinningCache.events.meshPreviewBehaviourChange.Invoke(null);
  353. }
  354. private void OnBoneOpacityChange(float value)
  355. {
  356. m_Model.boneOpacityValue = value;
  357. }
  358. private void OnMeshOpacityChange(float value)
  359. {
  360. m_Model.meshOpacityValue = value;
  361. }
  362. private void OnToolAvailabilityChange(int toolIndex)
  363. {
  364. var toolChanged = m_Tools[toolIndex];
  365. m_Model.view.SetToolAvailable(toolIndex, toolChanged.isAvailable);
  366. if (toolChanged == currentTool && toolChanged.isAvailable == false)
  367. ActivateTool(defaultTool);
  368. }
  369. private void ActivateToolWithUndo(IVisibilityTool tool)
  370. {
  371. if (currentTool != tool && tool.isAvailable)
  372. {
  373. m_Model.BeginUndoOperation(TextContent.visibilityTab);
  374. ActivateTool(tool);
  375. }
  376. }
  377. private void ActivateTool(IVisibilityTool tool)
  378. {
  379. if (tool.isAvailable == false)
  380. return;
  381. if (currentTool != null)
  382. currentTool.Deactivate();
  383. currentTool = tool;
  384. currentTool.Activate();
  385. m_Model.view.SetActiveTab(m_Model.currentToolIndex);
  386. m_Model.view.SetContent(currentTool.view);
  387. }
  388. }
  389. }