Net-Game/Library/PackageCache/com.unity.2d.animation@494a3b4e73a9/Editor/SkinningModule/SkeletonTool/SkeletonTool.cs
2025-03-28 08:33:16 -04:00

240 lines
9.1 KiB
C#

using UnityEditor.U2D.Layout;
using UnityEngine;
namespace UnityEditor.U2D.Animation
{
internal class SkeletonTool : BaseTool
{
[SerializeField]
SkeletonController m_SkeletonController;
SkeletonToolView m_SkeletonToolView;
RectBoneSelector m_RectBoneSelector = new RectBoneSelector();
RectSelectionTool<BoneCache> m_RectSelectionTool = new RectSelectionTool<BoneCache>();
UnselectTool<BoneCache> m_UnselectTool = new UnselectTool<BoneCache>();
public bool enableBoneInspector { get; set; }
public SkeletonMode mode
{
get => m_SkeletonController.view.mode;
set => m_SkeletonController.view.mode = value;
}
public bool editBindPose
{
get => m_SkeletonController.editBindPose;
set => m_SkeletonController.editBindPose = value;
}
public ISkeletonStyle skeletonStyle
{
get => m_SkeletonController.styleOverride;
set => m_SkeletonController.styleOverride = value;
}
public override int defaultControlID => 0;
public BoneCache hoveredBone => m_SkeletonController.hoveredBone;
public SkeletonCache skeleton
{
get => m_SkeletonController.skeleton;
private set => m_SkeletonController.skeleton = value;
}
internal override void OnCreate()
{
m_SkeletonController = new SkeletonController();
m_SkeletonController.view = new SkeletonView(new GUIWrapper());
m_SkeletonController.view.InvalidID = 0;
m_SkeletonController.selection = skinningCache.skeletonSelection;
m_SkeletonToolView = new SkeletonToolView();
m_SkeletonToolView.onBoneNameChanged += BoneNameChanged;
m_SkeletonToolView.onBoneDepthChanged += BoneDepthChanged;
m_SkeletonToolView.onBonePositionChanged += BonePositionChanged;
m_SkeletonToolView.onBoneRotationChanged += BoneRotationChanged;
m_SkeletonToolView.onBoneColorChanged += BoneColorChanged;
m_RectBoneSelector.selection = skinningCache.skeletonSelection;
m_RectSelectionTool.rectSelector = m_RectBoneSelector;
m_RectSelectionTool.cacheUndo = skinningCache;
m_RectSelectionTool.onSelectionUpdate += () =>
{
skinningCache.events.boneSelectionChanged.Invoke();
};
m_UnselectTool.cacheUndo = skinningCache;
m_UnselectTool.selection = skinningCache.skeletonSelection;
m_UnselectTool.onUnselect += () =>
{
skinningCache.events.boneSelectionChanged.Invoke();
};
}
public override void Initialize(LayoutOverlay layout)
{
m_SkeletonToolView.Initialize(layout);
}
protected override void OnActivate()
{
SetupSkeleton(skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite));
UpdateBoneInspector();
skinningCache.events.skeletonTopologyChanged.AddListener(SkeletonTopologyChanged);
skinningCache.events.boneSelectionChanged.AddListener(BoneSelectionChanged);
skinningCache.events.selectedSpriteChanged.AddListener(SelectedSpriteChanged);
skinningCache.events.skinningModeChanged.AddListener(SkinningModeChanged);
skinningCache.events.boneDepthChanged.AddListener(BoneDataChanged);
skinningCache.events.boneNameChanged.AddListener(BoneDataChanged);
skinningCache.events.boneColorChanged.AddListener(BoneDataChanged);
skeletonStyle = null;
}
protected override void OnDeactivate()
{
m_SkeletonToolView.Hide();
m_SkeletonController.Reset();
skinningCache.events.skeletonTopologyChanged.RemoveListener(SkeletonTopologyChanged);
skinningCache.events.boneSelectionChanged.RemoveListener(BoneSelectionChanged);
skinningCache.events.selectedSpriteChanged.RemoveListener(SelectedSpriteChanged);
skinningCache.events.skinningModeChanged.RemoveListener(SkinningModeChanged);
skinningCache.events.boneDepthChanged.RemoveListener(BoneDataChanged);
skinningCache.events.boneNameChanged.RemoveListener(BoneDataChanged);
skinningCache.events.boneColorChanged.RemoveListener(BoneDataChanged);
skeletonStyle = null;
}
void SkeletonTopologyChanged(SkeletonCache skeletonCache)
{
if (skeleton == skeletonCache && skeleton != null)
m_RectBoneSelector.bones = skeleton.bones;
}
void BoneDataChanged(BoneCache bone)
{
if (m_SkeletonToolView.target == bone)
m_SkeletonToolView.Update(bone.name, Mathf.RoundToInt(bone.depth), bone.position, bone.rotation.eulerAngles.z, bone.bindPoseColor);
}
void SelectedSpriteChanged(SpriteCache sprite)
{
SetupSkeleton(skinningCache.GetEffectiveSkeleton(sprite));
}
void BoneSelectionChanged()
{
UpdateBoneInspector();
}
void UpdateBoneInspector()
{
var selectedBone = skinningCache.skeletonSelection.activeElement;
var selectionCount = skinningCache.skeletonSelection.Count;
m_SkeletonToolView.Hide();
if (enableBoneInspector && selectedBone != null && selectionCount == 1)
{
m_SkeletonToolView.Update(selectedBone.name, Mathf.RoundToInt(selectedBone.depth), selectedBone.position, selectedBone.rotation.eulerAngles.z, selectedBone.bindPoseColor);
bool isReadOnly = skinningCache.bonesReadOnly;
m_SkeletonToolView.Show(selectedBone, isReadOnly);
}
}
void SkinningModeChanged(SkinningMode skinningMode)
{
SetupSkeleton(skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite));
}
void SetupSkeleton(SkeletonCache sk)
{
m_RectBoneSelector.bones = null;
skeleton = sk;
if (skeleton != null)
m_RectBoneSelector.bones = skeleton.bones;
}
protected override void OnGUI()
{
m_SkeletonController.view.defaultControlID = 0;
if (skeleton != null && mode != SkeletonMode.Disabled)
{
m_RectSelectionTool.OnGUI();
m_SkeletonController.view.defaultControlID = m_RectSelectionTool.controlID;
}
m_SkeletonController.OnGUI();
m_UnselectTool.OnGUI();
}
void BoneColorChanged(BoneCache selectedBone, Color32 color)
{
if (selectedBone != null)
{
skinningCache.BeginUndoOperation(TextContent.colorBoneChanged);
selectedBone.bindPoseColor = color;
skinningCache.events.boneColorChanged.Invoke(selectedBone);
}
}
void BonePositionChanged(BoneCache selectedBone, Vector2 position)
{
if (selectedBone != null)
{
skinningCache.BeginUndoOperation(TextContent.moveBone);
selectedBone.position = position;
HandleUtility.Repaint();
m_SkeletonController.InvokePoseChanged();
}
}
void BoneRotationChanged(BoneCache selectedBone, float rotation)
{
if (selectedBone != null)
{
var euler = selectedBone.rotation.eulerAngles;
euler.z = rotation;
skinningCache.BeginUndoOperation(TextContent.rotateBone);
selectedBone.rotation = Quaternion.Euler(euler);
HandleUtility.Repaint();
m_SkeletonController.InvokePoseChanged();
}
}
void BoneNameChanged(BoneCache selectedBone, string name)
{
if (selectedBone != null)
{
if (string.Compare(selectedBone.name, name) == 0)
return;
if (string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name))
m_SkeletonToolView.Update(selectedBone.name, Mathf.RoundToInt(selectedBone.depth), selectedBone.position, selectedBone.rotation.eulerAngles.z, selectedBone.bindPoseColor);
else
{
using (skinningCache.UndoScope(TextContent.boneName))
{
selectedBone.name = name;
skinningCache.events.boneNameChanged.Invoke(selectedBone);
}
}
}
}
void BoneDepthChanged(BoneCache selectedBone, int depth)
{
if (selectedBone != null)
{
if (Mathf.RoundToInt(selectedBone.depth) == depth)
return;
using (skinningCache.UndoScope(TextContent.boneDepth))
{
selectedBone.depth = depth;
skinningCache.events.boneDepthChanged.Invoke(selectedBone);
}
}
}
}
}