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