Brak opisu
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.

SkeletonTool.cs 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. using UnityEditor.U2D.Layout;
  2. using UnityEngine;
  3. namespace UnityEditor.U2D.Animation
  4. {
  5. internal class SkeletonTool : BaseTool
  6. {
  7. [SerializeField]
  8. SkeletonController m_SkeletonController;
  9. SkeletonToolView m_SkeletonToolView;
  10. RectBoneSelector m_RectBoneSelector = new RectBoneSelector();
  11. RectSelectionTool<BoneCache> m_RectSelectionTool = new RectSelectionTool<BoneCache>();
  12. UnselectTool<BoneCache> m_UnselectTool = new UnselectTool<BoneCache>();
  13. public bool enableBoneInspector { get; set; }
  14. public SkeletonMode mode
  15. {
  16. get => m_SkeletonController.view.mode;
  17. set => m_SkeletonController.view.mode = value;
  18. }
  19. public bool editBindPose
  20. {
  21. get => m_SkeletonController.editBindPose;
  22. set => m_SkeletonController.editBindPose = value;
  23. }
  24. public ISkeletonStyle skeletonStyle
  25. {
  26. get => m_SkeletonController.styleOverride;
  27. set => m_SkeletonController.styleOverride = value;
  28. }
  29. public override int defaultControlID => 0;
  30. public BoneCache hoveredBone => m_SkeletonController.hoveredBone;
  31. public SkeletonCache skeleton
  32. {
  33. get => m_SkeletonController.skeleton;
  34. private set => m_SkeletonController.skeleton = value;
  35. }
  36. internal override void OnCreate()
  37. {
  38. m_SkeletonController = new SkeletonController();
  39. m_SkeletonController.view = new SkeletonView(new GUIWrapper());
  40. m_SkeletonController.view.InvalidID = 0;
  41. m_SkeletonController.selection = skinningCache.skeletonSelection;
  42. m_SkeletonToolView = new SkeletonToolView();
  43. m_SkeletonToolView.onBoneNameChanged += BoneNameChanged;
  44. m_SkeletonToolView.onBoneDepthChanged += BoneDepthChanged;
  45. m_SkeletonToolView.onBonePositionChanged += BonePositionChanged;
  46. m_SkeletonToolView.onBoneRotationChanged += BoneRotationChanged;
  47. m_SkeletonToolView.onBoneColorChanged += BoneColorChanged;
  48. m_RectBoneSelector.selection = skinningCache.skeletonSelection;
  49. m_RectSelectionTool.rectSelector = m_RectBoneSelector;
  50. m_RectSelectionTool.cacheUndo = skinningCache;
  51. m_RectSelectionTool.onSelectionUpdate += () =>
  52. {
  53. skinningCache.events.boneSelectionChanged.Invoke();
  54. };
  55. m_UnselectTool.cacheUndo = skinningCache;
  56. m_UnselectTool.selection = skinningCache.skeletonSelection;
  57. m_UnselectTool.onUnselect += () =>
  58. {
  59. skinningCache.events.boneSelectionChanged.Invoke();
  60. };
  61. }
  62. public override void Initialize(LayoutOverlay layout)
  63. {
  64. m_SkeletonToolView.Initialize(layout);
  65. }
  66. protected override void OnActivate()
  67. {
  68. SetupSkeleton(skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite));
  69. UpdateBoneInspector();
  70. skinningCache.events.skeletonTopologyChanged.AddListener(SkeletonTopologyChanged);
  71. skinningCache.events.boneSelectionChanged.AddListener(BoneSelectionChanged);
  72. skinningCache.events.selectedSpriteChanged.AddListener(SelectedSpriteChanged);
  73. skinningCache.events.skinningModeChanged.AddListener(SkinningModeChanged);
  74. skinningCache.events.boneDepthChanged.AddListener(BoneDataChanged);
  75. skinningCache.events.boneNameChanged.AddListener(BoneDataChanged);
  76. skinningCache.events.boneColorChanged.AddListener(BoneDataChanged);
  77. skeletonStyle = null;
  78. }
  79. protected override void OnDeactivate()
  80. {
  81. m_SkeletonToolView.Hide();
  82. m_SkeletonController.Reset();
  83. skinningCache.events.skeletonTopologyChanged.RemoveListener(SkeletonTopologyChanged);
  84. skinningCache.events.boneSelectionChanged.RemoveListener(BoneSelectionChanged);
  85. skinningCache.events.selectedSpriteChanged.RemoveListener(SelectedSpriteChanged);
  86. skinningCache.events.skinningModeChanged.RemoveListener(SkinningModeChanged);
  87. skinningCache.events.boneDepthChanged.RemoveListener(BoneDataChanged);
  88. skinningCache.events.boneNameChanged.RemoveListener(BoneDataChanged);
  89. skinningCache.events.boneColorChanged.RemoveListener(BoneDataChanged);
  90. skeletonStyle = null;
  91. }
  92. void SkeletonTopologyChanged(SkeletonCache skeletonCache)
  93. {
  94. if (skeleton == skeletonCache && skeleton != null)
  95. m_RectBoneSelector.bones = skeleton.bones;
  96. }
  97. void BoneDataChanged(BoneCache bone)
  98. {
  99. if(m_SkeletonToolView.target == bone)
  100. m_SkeletonToolView.Update(bone.name, Mathf.RoundToInt(bone.depth), bone.position, bone.rotation.eulerAngles.z, bone.bindPoseColor);
  101. }
  102. void SelectedSpriteChanged(SpriteCache sprite)
  103. {
  104. SetupSkeleton(skinningCache.GetEffectiveSkeleton(sprite));
  105. }
  106. void BoneSelectionChanged()
  107. {
  108. UpdateBoneInspector();
  109. }
  110. void UpdateBoneInspector()
  111. {
  112. var selectedBone = skinningCache.skeletonSelection.activeElement;
  113. var selectionCount = skinningCache.skeletonSelection.Count;
  114. m_SkeletonToolView.Hide();
  115. if (enableBoneInspector && selectedBone != null && selectionCount == 1)
  116. {
  117. m_SkeletonToolView.Update(selectedBone.name, Mathf.RoundToInt(selectedBone.depth), selectedBone.position, selectedBone.rotation.eulerAngles.z, selectedBone.bindPoseColor);
  118. bool isReadOnly = skinningCache.bonesReadOnly;
  119. m_SkeletonToolView.Show(selectedBone, isReadOnly);
  120. }
  121. }
  122. void SkinningModeChanged(SkinningMode skinningMode)
  123. {
  124. SetupSkeleton(skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite));
  125. }
  126. void SetupSkeleton(SkeletonCache sk)
  127. {
  128. m_RectBoneSelector.bones = null;
  129. skeleton = sk;
  130. if (skeleton != null)
  131. m_RectBoneSelector.bones = skeleton.bones;
  132. }
  133. protected override void OnGUI()
  134. {
  135. m_SkeletonController.view.defaultControlID = 0;
  136. if (skeleton != null && mode != SkeletonMode.Disabled)
  137. {
  138. m_RectSelectionTool.OnGUI();
  139. m_SkeletonController.view.defaultControlID = m_RectSelectionTool.controlID;
  140. }
  141. m_SkeletonController.OnGUI();
  142. m_UnselectTool.OnGUI();
  143. }
  144. void BoneColorChanged(BoneCache selectedBone, Color32 color)
  145. {
  146. if (selectedBone != null)
  147. {
  148. skinningCache.BeginUndoOperation(TextContent.colorBoneChanged);
  149. selectedBone.bindPoseColor = color;
  150. skinningCache.events.boneColorChanged.Invoke(selectedBone);
  151. }
  152. }
  153. void BonePositionChanged(BoneCache selectedBone, Vector2 position)
  154. {
  155. if (selectedBone != null)
  156. {
  157. skinningCache.BeginUndoOperation(TextContent.moveBone);
  158. selectedBone.position = position;
  159. HandleUtility.Repaint();
  160. m_SkeletonController.InvokePoseChanged();
  161. }
  162. }
  163. void BoneRotationChanged(BoneCache selectedBone, float rotation)
  164. {
  165. if (selectedBone != null)
  166. {
  167. var euler = selectedBone.rotation.eulerAngles;
  168. euler.z = rotation;
  169. skinningCache.BeginUndoOperation(TextContent.rotateBone);
  170. selectedBone.rotation = Quaternion.Euler(euler);
  171. HandleUtility.Repaint();
  172. m_SkeletonController.InvokePoseChanged();
  173. }
  174. }
  175. void BoneNameChanged(BoneCache selectedBone, string name)
  176. {
  177. if (selectedBone != null)
  178. {
  179. if (string.Compare(selectedBone.name, name) == 0)
  180. return;
  181. if(string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name))
  182. m_SkeletonToolView.Update(selectedBone.name, Mathf.RoundToInt(selectedBone.depth), selectedBone.position, selectedBone.rotation.eulerAngles.z, selectedBone.bindPoseColor);
  183. else
  184. {
  185. using (skinningCache.UndoScope(TextContent.boneName))
  186. {
  187. selectedBone.name = name;
  188. skinningCache.events.boneNameChanged.Invoke(selectedBone);
  189. }
  190. }
  191. }
  192. }
  193. void BoneDepthChanged(BoneCache selectedBone, int depth)
  194. {
  195. if (selectedBone != null)
  196. {
  197. if (Mathf.RoundToInt(selectedBone.depth) == depth)
  198. return;
  199. using (skinningCache.UndoScope(TextContent.boneDepth))
  200. {
  201. selectedBone.depth = depth;
  202. skinningCache.events.boneDepthChanged.Invoke(selectedBone);
  203. }
  204. }
  205. }
  206. }
  207. }