mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[unity] SkeletonBakingWindow and various editor fixes.
This commit is contained in:
parent
7570c69aa2
commit
439c8e8e22
@ -82,6 +82,7 @@
|
||||
* **[SpineAttribute(includeNone:false)]** SpineAttributes now have an `includeNone` optional parameter to specify if you want to include or exclude a none ("") value option in the dropdown menu. Default is `includeNone:true`.
|
||||
* **[SpineAttachment(skinField:"mySkin")]** The SpineAttachment attribute now has a skinField optional parameter to limit the dropdown items to attachments in a specific skin instead of the just default skin or all the skins in SkeletonData.
|
||||
* **SkeletonDebugWindow**. Debugging tools have been moved from the SkeletonRenderer and SkeletonUtility component inspectors into its own utility window. You can access "Skeleton Debug" under the `Advanced...` foldout in the SkeletonRenderer inspector, or in SkeletonRenderer's right-click/context menu.
|
||||
* **Skeleton Baking Window** The old Skeleton Baking feature is also now accessible through the SkeletonDataAsset's right-click/context menu.
|
||||
* **AttachmentTools source material**. `AttachmentTools` methods can now accept a `sourceMaterial` argument to copy material properties from.
|
||||
* **AttachmentTools Skin Extensions**. Using AttachmentTools, you can now add entries by slot name by also providing a skeleton argument. Also `Append(Skin)`, `RemoveAttachment` and `Clear` have been added.
|
||||
* **BoneFollower and SkeletonUtilityBone Add RigidBody Button**. The BoneFollower and SkeletonUtilityBone component inspectors will now offer to add a `Rigidbody` or `Rigidbody2D` if it detects a collider of the appropriate type. Having a rigidbody on a moving transform with a collider fits better with the Unity physics systems and prevents excess calculations. It will not detect colliders on child objects so you have to add Rigidbody components manually accordingly.
|
||||
|
||||
@ -287,73 +287,6 @@ namespace Spine.Unity.Editor {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SPINE_BAKING
|
||||
bool pre = isBakingExpanded;
|
||||
isBakingExpanded = EditorGUILayout.Foldout(isBakingExpanded, new GUIContent("Baking", Icons.unityIcon));
|
||||
if (pre != isBakingExpanded)
|
||||
EditorPrefs.SetBool(ShowBakingPrefsKey, isBakingExpanded);
|
||||
|
||||
if (isBakingExpanded) {
|
||||
EditorGUI.indentLevel++;
|
||||
const string BakingWarningMessage =
|
||||
// "WARNING!" +
|
||||
// "\nBaking is NOT the same as SkeletonAnimator!" +
|
||||
// "\n\n" +
|
||||
"The main use of Baking is to export Spine projects to be used without the Spine Runtime (ie: for sale on the Asset Store, or background objects that are animated only with a wind noise generator)" +
|
||||
|
||||
"\n\nBaking does not support the following:" +
|
||||
"\n\tDisabled transform inheritance" +
|
||||
"\n\tShear" +
|
||||
"\n\tColor Keys" +
|
||||
"\n\tDraw Order Keys" +
|
||||
"\n\tAll Constraint types" +
|
||||
|
||||
"\n\nCurves are sampled at 60fps and are not realtime." +
|
||||
"\nPlease read SkeletonBaker.cs comments for full details.";
|
||||
EditorGUILayout.HelpBox(BakingWarningMessage, MessageType.Info, true);
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
bakeAnimations = EditorGUILayout.Toggle("Bake Animations", bakeAnimations);
|
||||
using (new EditorGUI.DisabledGroupScope(!bakeAnimations)) {
|
||||
EditorGUI.indentLevel++;
|
||||
bakeIK = EditorGUILayout.Toggle("Bake IK", bakeIK);
|
||||
bakeEventOptions = (SendMessageOptions)EditorGUILayout.EnumPopup("Event Options", bakeEventOptions);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// Bake Skin buttons.
|
||||
using (new GUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(new GUIContent("Bake All Skins", Icons.unityIcon), GUILayout.Height(32), GUILayout.Width(150)))
|
||||
SkeletonBaker.BakeToPrefab(m_skeletonDataAsset, m_skeletonData.Skins, "", bakeAnimations, bakeIK, bakeEventOptions);
|
||||
|
||||
if (m_skeletonAnimation != null && m_skeletonAnimation.skeleton != null) {
|
||||
Skin bakeSkin = m_skeletonAnimation.skeleton.Skin;
|
||||
|
||||
string skinName = "<No Skin>";
|
||||
if (bakeSkin == null) {
|
||||
skinName = "Default";
|
||||
bakeSkin = m_skeletonData.Skins.Items[0];
|
||||
} else
|
||||
skinName = m_skeletonAnimation.skeleton.Skin.Name;
|
||||
|
||||
using (new GUILayout.VerticalScope()) {
|
||||
if (GUILayout.Button(new GUIContent("Bake \"" + skinName + "\"", Icons.unityIcon), GUILayout.Height(32), GUILayout.Width(250)))
|
||||
SkeletonBaker.BakeToPrefab(m_skeletonDataAsset, new ExposedList<Skin>(new [] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions);
|
||||
using (new GUILayout.HorizontalScope()) {
|
||||
GUILayout.Label(new GUIContent("Skins", Icons.skinsRoot), GUILayout.Width(50));
|
||||
if (GUILayout.Button(skinName, EditorStyles.popup, GUILayout.Width(196))) {
|
||||
DrawSkinDropdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DoReimport () {
|
||||
|
||||
@ -42,36 +42,35 @@ using System.Reflection;
|
||||
using System.IO;
|
||||
using Spine;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// [SUPPORTS]
|
||||
/// Linear, Constant, and Bezier Curves*
|
||||
/// Inverse Kinematics*
|
||||
/// Inherit Rotation
|
||||
/// Translate Timeline
|
||||
/// Rotate Timeline
|
||||
/// Scale Timeline**
|
||||
/// Event Timeline***
|
||||
/// Attachment Timeline
|
||||
///
|
||||
/// RegionAttachment
|
||||
/// MeshAttachment
|
||||
/// SkinnedMeshAttachment
|
||||
///
|
||||
/// [LIMITATIONS]
|
||||
/// *Inverse Kinematics & Bezier Curves are baked into the animation at 60fps and are not realtime. Use bakeIncrement constant to adjust key density if desired.
|
||||
/// **Non-uniform Scale Keys (ie: if ScaleX and ScaleY are not equal to eachother, it will not be accurate to Spine source)
|
||||
/// ***Events may only fire 1 type of data per event in Unity safely so priority to String data if present in Spine key, otherwise a Float is sent whether the Spine key was Int or Float with priority given to Int.
|
||||
///
|
||||
/// [DOES NOT SUPPORT]
|
||||
/// FlipX or FlipY (Maybe one day)
|
||||
/// FFD (Unity does not provide access to BlendShapes with code)
|
||||
/// Color Keys (Maybe one day when Unity supports full FBX standard and provides access with code)
|
||||
/// InheritScale (Never. Unity and Spine do scaling very differently)
|
||||
/// Draw Order Keyframes
|
||||
/// </summary>
|
||||
///
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
/// <summary>
|
||||
/// [SUPPORTS]
|
||||
/// Linear, Constant, and Bezier Curves*
|
||||
/// Inverse Kinematics*
|
||||
/// Inherit Rotation
|
||||
/// Translate Timeline
|
||||
/// Rotate Timeline
|
||||
/// Scale Timeline**
|
||||
/// Event Timeline***
|
||||
/// Attachment Timeline
|
||||
///
|
||||
/// RegionAttachment
|
||||
/// MeshAttachment
|
||||
/// SkinnedMeshAttachment
|
||||
///
|
||||
/// [LIMITATIONS]
|
||||
/// *Inverse Kinematics & Bezier Curves are baked into the animation at 60fps and are not realtime. Use bakeIncrement constant to adjust key density if desired.
|
||||
/// **Non-uniform Scale Keys (ie: if ScaleX and ScaleY are not equal to eachother, it will not be accurate to Spine source)
|
||||
/// ***Events may only fire 1 type of data per event in Unity safely so priority to String data if present in Spine key, otherwise a Float is sent whether the Spine key was Int or Float with priority given to Int.
|
||||
///
|
||||
/// [DOES NOT SUPPORT]
|
||||
/// FlipX or FlipY (Maybe one day)
|
||||
/// FFD (Unity does not provide access to BlendShapes with code)
|
||||
/// Color Keys (Maybe one day when Unity supports full FBX standard and provides access with code)
|
||||
/// InheritScale (Never. Unity and Spine do scaling very differently)
|
||||
/// Draw Order Keyframes
|
||||
/// </summary>
|
||||
public static class SkeletonBaker {
|
||||
|
||||
#region SkeletonAnimator's Mecanim Clips
|
||||
|
||||
121
spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs
Normal file
121
spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs
Normal file
@ -0,0 +1,121 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
using Editor = UnityEditor.Editor;
|
||||
using Icons = SpineEditorUtilities.Icons;
|
||||
|
||||
public class SkeletonBakingWindow : EditorWindow {
|
||||
const bool IsUtilityWindow = true;
|
||||
|
||||
[MenuItem("CONTEXT/SkeletonDataAsset/Skeleton Baking", false, 5000)]
|
||||
public static void Init (MenuCommand command) {
|
||||
var window = EditorWindow.GetWindow<SkeletonBakingWindow>(IsUtilityWindow);
|
||||
window.minSize = new Vector2(330f, 530f);
|
||||
window.maxSize = new Vector2(600f, 1000f);
|
||||
window.titleContent = new GUIContent("Skeleton Baking", Icons.spine);
|
||||
window.skeletonDataAsset = command.context as SkeletonDataAsset;
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public SkeletonDataAsset skeletonDataAsset;
|
||||
[SpineSkin(dataField:"skeletonDataAsset")]
|
||||
public string skinToBake = "default";
|
||||
|
||||
// Settings
|
||||
bool bakeAnimations = false;
|
||||
bool bakeIK = true;
|
||||
SendMessageOptions bakeEventOptions;
|
||||
|
||||
SerializedObject so;
|
||||
Skin bakeSkin;
|
||||
|
||||
|
||||
void DataAssetChanged () {
|
||||
bakeSkin = null;
|
||||
}
|
||||
|
||||
void OnGUI () {
|
||||
so = so ?? new SerializedObject(this);
|
||||
|
||||
EditorGUIUtility.wideMode = true;
|
||||
EditorGUILayout.LabelField("Spine Skeleton Prefab Baking", EditorStyles.boldLabel);
|
||||
|
||||
const string BakingWarningMessage = "\nThe main use of Baking is to export Spine projects to be used without the Spine Runtime (ie: for sale on the Asset Store, or background objects that are animated only with a wind noise generator)" +
|
||||
|
||||
"\n\nBaking does not support the following:" +
|
||||
"\n\tDisabled transform inheritance" +
|
||||
"\n\tShear" +
|
||||
"\n\tColor Keys" +
|
||||
"\n\tDraw Order Keys" +
|
||||
"\n\tAll Constraint types" +
|
||||
|
||||
"\n\nCurves are sampled at 60fps and are not realtime." +
|
||||
"\nPlease read SkeletonBaker.cs comments for full details.\n";
|
||||
EditorGUILayout.HelpBox(BakingWarningMessage, MessageType.Info, true);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var skeletonDataAssetProperty = so.FindProperty("skeletonDataAsset");
|
||||
EditorGUILayout.PropertyField(skeletonDataAssetProperty, SpineInspectorUtility.TempContent("SkeletonDataAsset", Icons.spine));
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
so.ApplyModifiedProperties();
|
||||
DataAssetChanged();
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (skeletonDataAsset == null) return;
|
||||
var skeletonData = skeletonDataAsset.GetSkeletonData(false);
|
||||
if (skeletonData == null) return;
|
||||
|
||||
using (new SpineInspectorUtility.BoxScope(false)) {
|
||||
EditorGUILayout.LabelField(skeletonDataAsset.name, EditorStyles.boldLabel);
|
||||
using (new SpineInspectorUtility.IndentScope()) {
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Bones: " + skeletonData.Bones.Count, Icons.bone));
|
||||
|
||||
int totalAttachments = 0;
|
||||
foreach (var s in skeletonData.Skins) totalAttachments += s.Attachments.Count;
|
||||
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Total Attachments: " + totalAttachments, Icons.genericAttachment));
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Current skin attachments: " + (bakeSkin == null ? 0 : bakeSkin.Attachments.Count), Icons.skinPlaceholder));
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Animations: " + skeletonData.Animations.Count, Icons.animation));
|
||||
}
|
||||
}
|
||||
using (new SpineInspectorUtility.BoxScope(false)) {
|
||||
EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
|
||||
using (new SpineInspectorUtility.IndentScope()) {
|
||||
bakeAnimations = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake Animations", Icons.animationRoot), bakeAnimations);
|
||||
bakeIK = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake IK", Icons.constraintIK), bakeIK);
|
||||
bakeEventOptions = (SendMessageOptions)EditorGUILayout.EnumPopup(SpineInspectorUtility.TempContent("Event Options", Icons.userEvent), bakeEventOptions);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(so.FindProperty("skinToBake"));
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
so.ApplyModifiedProperties();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(skinToBake) && UnityEngine.Event.current.type == EventType.Repaint)
|
||||
bakeSkin = skeletonData.FindSkin(skinToBake) ?? skeletonData.DefaultSkin;
|
||||
|
||||
var prefabIcon = EditorGUIUtility.FindTexture("PrefabModel Icon");
|
||||
|
||||
if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake Skin ({0})", (bakeSkin == null ? "default" : bakeSkin.Name)), prefabIcon))) {
|
||||
SkeletonBaker.BakeToPrefab(skeletonDataAsset, new ExposedList<Skin>(new [] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions);
|
||||
}
|
||||
|
||||
|
||||
if (skeletonData.Skins.Count > 1) {
|
||||
if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake All ({0} skins)", skeletonData.Skins.Count), prefabIcon))) {
|
||||
SkeletonBaker.BakeToPrefab(skeletonDataAsset, skeletonData.Skins, "", bakeAnimations, bakeIK, bakeEventOptions);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 868b0caae5b3e65408ece1ab400c4a99
|
||||
timeCreated: 1495203966
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -305,7 +305,7 @@ namespace Spine.Unity.Editor {
|
||||
prefix = skinPrefix;
|
||||
|
||||
for (int i = 0; i < data.Slots.Count; i++) {
|
||||
if (slotMatch.Length > 0 && !(data.Slots.Items[i].Name.ToLower().Contains(slotMatch)))
|
||||
if (slotMatch.Length > 0 && !(data.Slots.Items[i].Name.Equals(slotMatch, StringComparison.OrdinalIgnoreCase)))
|
||||
continue;
|
||||
|
||||
attachmentNames.Clear();
|
||||
|
||||
@ -200,7 +200,7 @@ namespace Spine.Unity.Editor {
|
||||
string buttonLabel = box.IsWeighted() ? box.Name + " (!)" : box.Name;
|
||||
if (GUILayout.Button(buttonLabel, GUILayout.Width(200))) {
|
||||
utilityBone.bone.Skeleton.UpdateWorldTransform();
|
||||
var bbTransform = utilityBone.transform.FindChild("[BoundingBox]" + box.Name);
|
||||
var bbTransform = utilityBone.transform.Find("[BoundingBox]" + box.Name); // Use FindChild in older versions of Unity.
|
||||
if (bbTransform != null) {
|
||||
var originalCollider = bbTransform.GetComponent<PolygonCollider2D>();
|
||||
if (originalCollider != null)
|
||||
|
||||
@ -166,7 +166,6 @@ namespace Spine.Unity {
|
||||
bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha);
|
||||
}
|
||||
|
||||
// MITCH
|
||||
if (rotation) {
|
||||
float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha);
|
||||
bone.Rotation = angle;
|
||||
|
||||
@ -144,10 +144,7 @@ namespace Spine.Unity {
|
||||
|
||||
public static Spine.Attachment GetAttachment (string attachmentPath, Spine.SkeletonData skeletonData) {
|
||||
var hierarchy = SpineAttachment.GetHierarchy(attachmentPath);
|
||||
if (hierarchy.name == "")
|
||||
return null;
|
||||
|
||||
return skeletonData.FindSkin(hierarchy.skin).GetAttachment(skeletonData.FindSlotIndex(hierarchy.slot), hierarchy.name);
|
||||
return string.IsNullOrEmpty(hierarchy.name) ? null : skeletonData.FindSkin(hierarchy.skin).GetAttachment(skeletonData.FindSlotIndex(hierarchy.slot), hierarchy.name);
|
||||
}
|
||||
|
||||
public static Spine.Attachment GetAttachment (string attachmentPath, SkeletonDataAsset skeletonDataAsset) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user