1
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb646ac6e394e534b80d5cac61478488
|
||||
folderAsset: yes
|
||||
timeCreated: 1563305058
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,185 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Reflection;
|
||||
using System;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
using Editor = UnityEditor.Editor;
|
||||
|
||||
[CustomEditor(typeof(AnimationReferenceAsset))]
|
||||
public class AnimationReferenceAssetEditor : Editor {
|
||||
|
||||
const string InspectorHelpText = "This is a Spine-Unity Animation Reference Asset. It serializes a reference to a SkeletonDataAsset and an animationName. It does not contain actual animation data. At runtime, it stores a reference to a Spine.Animation.\n\n" +
|
||||
"You can use this in your AnimationState calls instead of a string animation name or a Spine.Animation reference. Use its implicit conversion into Spine.Animation or its .Animation property.\n\n" +
|
||||
"Use AnimationReferenceAssets as an alternative to storing strings or finding animations and caching per component. This only does the lookup by string once, and allows you to store and manage animations via asset references.";
|
||||
|
||||
readonly SkeletonInspectorPreview preview = new SkeletonInspectorPreview();
|
||||
FieldInfo skeletonDataAssetField = typeof(AnimationReferenceAsset).GetField("skeletonDataAsset", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
FieldInfo nameField = typeof(AnimationReferenceAsset).GetField("animationName", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
AnimationReferenceAsset ThisAnimationReferenceAsset { get { return target as AnimationReferenceAsset; } }
|
||||
SkeletonDataAsset ThisSkeletonDataAsset { get { return skeletonDataAssetField.GetValue(ThisAnimationReferenceAsset) as SkeletonDataAsset; } }
|
||||
string ThisAnimationName { get { return nameField.GetValue(ThisAnimationReferenceAsset) as string; } }
|
||||
|
||||
bool changeNextFrame = false;
|
||||
SerializedProperty animationNameProperty;
|
||||
SkeletonDataAsset lastSkeletonDataAsset;
|
||||
SkeletonData lastSkeletonData;
|
||||
|
||||
void OnEnable () { HandleOnEnablePreview(); }
|
||||
void OnDestroy () {
|
||||
HandleOnDestroyPreview();
|
||||
AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload;
|
||||
EditorApplication.update -= preview.HandleEditorUpdate;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
animationNameProperty = animationNameProperty ?? serializedObject.FindProperty("animationName");
|
||||
string animationName = animationNameProperty.stringValue;
|
||||
|
||||
Animation animation = null;
|
||||
if (ThisSkeletonDataAsset != null) {
|
||||
var skeletonData = ThisSkeletonDataAsset.GetSkeletonData(true);
|
||||
if (skeletonData != null) {
|
||||
animation = skeletonData.FindAnimation(animationName);
|
||||
}
|
||||
}
|
||||
bool animationNotFound = (animation == null);
|
||||
|
||||
if (changeNextFrame) {
|
||||
changeNextFrame = false;
|
||||
|
||||
if (ThisSkeletonDataAsset != lastSkeletonDataAsset || ThisSkeletonDataAsset.GetSkeletonData(true) != lastSkeletonData) {
|
||||
preview.Clear();
|
||||
preview.Initialize(Repaint, ThisSkeletonDataAsset, LastSkinName);
|
||||
|
||||
if (animationNotFound) {
|
||||
animationNameProperty.stringValue = "";
|
||||
preview.ClearAnimationSetupPose();
|
||||
}
|
||||
}
|
||||
|
||||
preview.ClearAnimationSetupPose();
|
||||
|
||||
if (!string.IsNullOrEmpty(animationNameProperty.stringValue))
|
||||
preview.PlayPauseAnimation(animationNameProperty.stringValue, true);
|
||||
}
|
||||
|
||||
lastSkeletonDataAsset = ThisSkeletonDataAsset;
|
||||
lastSkeletonData = ThisSkeletonDataAsset.GetSkeletonData(true);
|
||||
|
||||
//EditorGUILayout.HelpBox(AnimationReferenceAssetEditor.InspectorHelpText, MessageType.Info, true);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawDefaultInspector();
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
changeNextFrame = true;
|
||||
}
|
||||
|
||||
// Draw extra info below default inspector.
|
||||
EditorGUILayout.Space();
|
||||
if (ThisSkeletonDataAsset == null) {
|
||||
EditorGUILayout.HelpBox("SkeletonDataAsset is missing.", MessageType.Error);
|
||||
} else if (string.IsNullOrEmpty(animationName)) {
|
||||
EditorGUILayout.HelpBox("No animation selected.", MessageType.Warning);
|
||||
} else if (animationNotFound) {
|
||||
EditorGUILayout.HelpBox(string.Format("Animation named {0} was not found for this Skeleton.", animationNameProperty.stringValue), MessageType.Warning);
|
||||
} else {
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
if (!string.Equals(AssetUtility.GetPathSafeName(animationName), ThisAnimationReferenceAsset.name, System.StringComparison.OrdinalIgnoreCase))
|
||||
EditorGUILayout.HelpBox("Animation name value does not match this asset's name. Inspectors using this asset may be misleading.", MessageType.None);
|
||||
|
||||
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(animationName, SpineEditorUtilities.Icons.animation));
|
||||
if (animation != null) {
|
||||
EditorGUILayout.LabelField(string.Format("Timelines: {0}", animation.Timelines.Count));
|
||||
EditorGUILayout.LabelField(string.Format("Duration: {0} sec", animation.Duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Preview Handlers
|
||||
string TargetAssetGUID { get { return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(ThisSkeletonDataAsset)); } }
|
||||
string LastSkinKey { get { return TargetAssetGUID + "_lastSkin"; } }
|
||||
string LastSkinName { get { return EditorPrefs.GetString(LastSkinKey, ""); } }
|
||||
|
||||
void HandleOnEnablePreview () {
|
||||
if (ThisSkeletonDataAsset != null && ThisSkeletonDataAsset.skeletonJSON == null)
|
||||
return;
|
||||
SpineEditorUtilities.ConfirmInitialization();
|
||||
|
||||
// This handles the case where the managed editor assembly is unloaded before recompilation when code changes.
|
||||
AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload;
|
||||
AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;
|
||||
|
||||
preview.Initialize(this.Repaint, ThisSkeletonDataAsset, LastSkinName);
|
||||
preview.PlayPauseAnimation(ThisAnimationName, true);
|
||||
preview.OnSkinChanged -= HandleOnSkinChanged;
|
||||
preview.OnSkinChanged += HandleOnSkinChanged;
|
||||
EditorApplication.update -= preview.HandleEditorUpdate;
|
||||
EditorApplication.update += preview.HandleEditorUpdate;
|
||||
}
|
||||
|
||||
private void OnDomainUnload (object sender, EventArgs e) {
|
||||
OnDestroy();
|
||||
}
|
||||
|
||||
private void HandleOnSkinChanged (string skinName) {
|
||||
EditorPrefs.SetString(LastSkinKey, skinName);
|
||||
preview.PlayPauseAnimation(ThisAnimationName, true);
|
||||
}
|
||||
|
||||
void HandleOnDestroyPreview () {
|
||||
EditorApplication.update -= preview.HandleEditorUpdate;
|
||||
preview.OnDestroy();
|
||||
}
|
||||
|
||||
override public bool HasPreviewGUI () {
|
||||
if (serializedObject.isEditingMultipleObjects) return false;
|
||||
return ThisSkeletonDataAsset != null && ThisSkeletonDataAsset.GetSkeletonData(true) != null;
|
||||
}
|
||||
|
||||
override public void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
|
||||
preview.Initialize(this.Repaint, ThisSkeletonDataAsset);
|
||||
preview.HandleInteractivePreviewGUI(r, background);
|
||||
}
|
||||
|
||||
public override GUIContent GetPreviewTitle () { return SpineInspectorUtility.TempContent("Preview"); }
|
||||
public override void OnPreviewSettings () { preview.HandleDrawSettings(); }
|
||||
public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) { return preview.GetStaticPreview(width, height); }
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9511532e80feed24881a5863f5485446
|
||||
timeCreated: 1523316585
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0134640f881c8d24d812a6f9af9d0761
|
||||
folderAsset: yes
|
||||
timeCreated: 1563304704
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,207 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Spine.Unity;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
using Editor = UnityEditor.Editor;
|
||||
using Event = UnityEngine.Event;
|
||||
|
||||
[CustomEditor(typeof(BoneFollowerGraphic)), CanEditMultipleObjects]
|
||||
public class BoneFollowerGraphicInspector : Editor {
|
||||
|
||||
SerializedProperty boneName, skeletonGraphic, followXYPosition, followZPosition, followBoneRotation,
|
||||
followLocalScale, followSkeletonFlip, maintainedAxisOrientation;
|
||||
BoneFollowerGraphic targetBoneFollower;
|
||||
bool needsReset;
|
||||
|
||||
#region Context Menu Item
|
||||
[MenuItem ("CONTEXT/SkeletonGraphic/Add BoneFollower GameObject")]
|
||||
static void AddBoneFollowerGameObject (MenuCommand cmd) {
|
||||
var skeletonGraphic = cmd.context as SkeletonGraphic;
|
||||
var go = EditorInstantiation.NewGameObject("BoneFollower", true, typeof(RectTransform));
|
||||
var t = go.transform;
|
||||
t.SetParent(skeletonGraphic.transform);
|
||||
t.localPosition = Vector3.zero;
|
||||
|
||||
var f = go.AddComponent<BoneFollowerGraphic>();
|
||||
f.skeletonGraphic = skeletonGraphic;
|
||||
f.SetBone(skeletonGraphic.Skeleton.RootBone.Data.Name);
|
||||
|
||||
EditorGUIUtility.PingObject(t);
|
||||
|
||||
Undo.RegisterCreatedObjectUndo(go, "Add BoneFollowerGraphic");
|
||||
}
|
||||
|
||||
// Validate
|
||||
[MenuItem ("CONTEXT/SkeletonGraphic/Add BoneFollower GameObject", true)]
|
||||
static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) {
|
||||
var skeletonGraphic = cmd.context as SkeletonGraphic;
|
||||
return skeletonGraphic.IsValid;
|
||||
}
|
||||
#endregion
|
||||
|
||||
void OnEnable () {
|
||||
skeletonGraphic = serializedObject.FindProperty("skeletonGraphic");
|
||||
boneName = serializedObject.FindProperty("boneName");
|
||||
followBoneRotation = serializedObject.FindProperty("followBoneRotation");
|
||||
followXYPosition = serializedObject.FindProperty("followXYPosition");
|
||||
followZPosition = serializedObject.FindProperty("followZPosition");
|
||||
followLocalScale = serializedObject.FindProperty("followLocalScale");
|
||||
followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip");
|
||||
maintainedAxisOrientation = serializedObject.FindProperty("maintainedAxisOrientation");
|
||||
|
||||
targetBoneFollower = (BoneFollowerGraphic)target;
|
||||
if (targetBoneFollower.SkeletonGraphic != null)
|
||||
targetBoneFollower.SkeletonGraphic.Initialize(false);
|
||||
|
||||
if (!targetBoneFollower.valid || needsReset) {
|
||||
targetBoneFollower.Initialize();
|
||||
targetBoneFollower.LateUpdate();
|
||||
needsReset = false;
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSceneGUI () {
|
||||
var tbf = target as BoneFollowerGraphic;
|
||||
var skeletonGraphicComponent = tbf.SkeletonGraphic;
|
||||
if (skeletonGraphicComponent == null) return;
|
||||
|
||||
var transform = skeletonGraphicComponent.transform;
|
||||
var skeleton = skeletonGraphicComponent.Skeleton;
|
||||
var canvas = skeletonGraphicComponent.canvas;
|
||||
float positionScale = canvas == null ? 1f : skeletonGraphicComponent.canvas.referencePixelsPerUnit;
|
||||
|
||||
if (string.IsNullOrEmpty(boneName.stringValue)) {
|
||||
SpineHandles.DrawBones(transform, skeleton, positionScale);
|
||||
SpineHandles.DrawBoneNames(transform, skeleton, positionScale);
|
||||
Handles.Label(tbf.transform.position, "No bone selected", EditorStyles.helpBox);
|
||||
} else {
|
||||
var targetBone = tbf.bone;
|
||||
if (targetBone == null) return;
|
||||
|
||||
SpineHandles.DrawBoneWireframe(transform, targetBone, SpineHandles.TransformContraintColor, positionScale);
|
||||
Handles.Label(targetBone.GetWorldPosition(transform, positionScale), targetBone.Data.Name, SpineHandles.BoneNameStyle);
|
||||
}
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
if (serializedObject.isEditingMultipleObjects) {
|
||||
if (needsReset) {
|
||||
needsReset = false;
|
||||
foreach (var o in targets) {
|
||||
var bf = (BoneFollower)o;
|
||||
bf.Initialize();
|
||||
bf.LateUpdate();
|
||||
}
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawDefaultInspector();
|
||||
needsReset |= EditorGUI.EndChangeCheck();
|
||||
return;
|
||||
}
|
||||
|
||||
if (needsReset && Event.current.type == EventType.Layout) {
|
||||
targetBoneFollower.Initialize();
|
||||
targetBoneFollower.LateUpdate();
|
||||
needsReset = false;
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
serializedObject.Update();
|
||||
|
||||
// Find Renderer
|
||||
if (skeletonGraphic.objectReferenceValue == null) {
|
||||
SkeletonGraphic parentRenderer = targetBoneFollower.GetComponentInParent<SkeletonGraphic>();
|
||||
if (parentRenderer != null && parentRenderer.gameObject != targetBoneFollower.gameObject) {
|
||||
skeletonGraphic.objectReferenceValue = parentRenderer;
|
||||
Debug.Log("Inspector automatically assigned BoneFollowerGraphic.SkeletonGraphic");
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonGraphic);
|
||||
var skeletonGraphicComponent = skeletonGraphic.objectReferenceValue as SkeletonGraphic;
|
||||
if (skeletonGraphicComponent != null) {
|
||||
if (skeletonGraphicComponent.gameObject == targetBoneFollower.gameObject) {
|
||||
skeletonGraphic.objectReferenceValue = null;
|
||||
EditorUtility.DisplayDialog("Invalid assignment.", "BoneFollowerGraphic can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your BoneFollower, or choose a SkeletonGraphic from a different GameObject.", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
if (!targetBoneFollower.valid) {
|
||||
needsReset = true;
|
||||
}
|
||||
|
||||
if (targetBoneFollower.valid) {
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(boneName);
|
||||
needsReset |= EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(followBoneRotation);
|
||||
EditorGUILayout.PropertyField(followXYPosition);
|
||||
EditorGUILayout.PropertyField(followZPosition);
|
||||
EditorGUILayout.PropertyField(followLocalScale);
|
||||
EditorGUILayout.PropertyField(followSkeletonFlip);
|
||||
if ((followSkeletonFlip.hasMultipleDifferentValues || followSkeletonFlip.boolValue == false) &&
|
||||
(followBoneRotation.hasMultipleDifferentValues || followBoneRotation.boolValue == true)) {
|
||||
using (new SpineInspectorUtility.IndentScope())
|
||||
EditorGUILayout.PropertyField(maintainedAxisOrientation);
|
||||
}
|
||||
|
||||
//BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower);
|
||||
} else {
|
||||
var boneFollowerSkeletonGraphic = targetBoneFollower.skeletonGraphic;
|
||||
if (boneFollowerSkeletonGraphic == null) {
|
||||
EditorGUILayout.HelpBox("SkeletonGraphic is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonMecanim).", MessageType.Warning);
|
||||
} else {
|
||||
boneFollowerSkeletonGraphic.Initialize(false);
|
||||
|
||||
if (boneFollowerSkeletonGraphic.skeletonDataAsset == null)
|
||||
EditorGUILayout.HelpBox("Assigned SkeletonGraphic does not have SkeletonData assigned to it.", MessageType.Warning);
|
||||
|
||||
if (!boneFollowerSkeletonGraphic.IsValid)
|
||||
EditorGUILayout.HelpBox("Assigned SkeletonGraphic is invalid. Check target SkeletonGraphic, its SkeletonDataAsset or the console for other errors.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
var current = Event.current;
|
||||
bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed");
|
||||
if (wasUndo)
|
||||
targetBoneFollower.Initialize();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da44a8561fd243c43a1f77bda36de0eb
|
||||
timeCreated: 1499279157
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,228 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
using Editor = UnityEditor.Editor;
|
||||
using Event = UnityEngine.Event;
|
||||
|
||||
[CustomEditor(typeof(BoneFollower)), CanEditMultipleObjects]
|
||||
public class BoneFollowerInspector : Editor {
|
||||
SerializedProperty boneName, skeletonRenderer, followXYPosition, followZPosition, followBoneRotation,
|
||||
followLocalScale, followSkeletonFlip, maintainedAxisOrientation;
|
||||
BoneFollower targetBoneFollower;
|
||||
bool needsReset;
|
||||
|
||||
#region Context Menu Item
|
||||
[MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject")]
|
||||
static void AddBoneFollowerGameObject (MenuCommand cmd) {
|
||||
var skeletonRenderer = cmd.context as SkeletonRenderer;
|
||||
var go = EditorInstantiation.NewGameObject("New BoneFollower", true);
|
||||
var t = go.transform;
|
||||
t.SetParent(skeletonRenderer.transform);
|
||||
t.localPosition = Vector3.zero;
|
||||
|
||||
var f = go.AddComponent<BoneFollower>();
|
||||
f.skeletonRenderer = skeletonRenderer;
|
||||
|
||||
EditorGUIUtility.PingObject(t);
|
||||
|
||||
Undo.RegisterCreatedObjectUndo(go, "Add BoneFollower");
|
||||
}
|
||||
|
||||
// Validate
|
||||
[MenuItem ("CONTEXT/SkeletonRenderer/Add BoneFollower GameObject", true)]
|
||||
static bool ValidateAddBoneFollowerGameObject (MenuCommand cmd) {
|
||||
var skeletonRenderer = cmd.context as SkeletonRenderer;
|
||||
return skeletonRenderer.valid;
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/BoneFollower/Rename BoneFollower GameObject")]
|
||||
static void RenameGameObject (MenuCommand cmd) {
|
||||
AutonameGameObject(cmd.context as BoneFollower);
|
||||
}
|
||||
#endregion
|
||||
|
||||
static void AutonameGameObject (BoneFollower boneFollower) {
|
||||
if (boneFollower == null) return;
|
||||
|
||||
string boneName = boneFollower.boneName;
|
||||
boneFollower.gameObject.name = string.IsNullOrEmpty(boneName) ? "BoneFollower" : string.Format("{0} (BoneFollower)", boneName);
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
|
||||
boneName = serializedObject.FindProperty("boneName");
|
||||
followBoneRotation = serializedObject.FindProperty("followBoneRotation");
|
||||
followXYPosition = serializedObject.FindProperty("followXYPosition");
|
||||
followZPosition = serializedObject.FindProperty("followZPosition");
|
||||
followLocalScale = serializedObject.FindProperty("followLocalScale");
|
||||
followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip");
|
||||
maintainedAxisOrientation = serializedObject.FindProperty("maintainedAxisOrientation");
|
||||
|
||||
targetBoneFollower = (BoneFollower)target;
|
||||
if (targetBoneFollower.SkeletonRenderer != null)
|
||||
targetBoneFollower.SkeletonRenderer.Initialize(false);
|
||||
|
||||
if (!targetBoneFollower.valid || needsReset) {
|
||||
targetBoneFollower.Initialize();
|
||||
targetBoneFollower.LateUpdate();
|
||||
needsReset = false;
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSceneGUI () {
|
||||
var tbf = target as BoneFollower;
|
||||
var skeletonRendererComponent = tbf.skeletonRenderer;
|
||||
if (skeletonRendererComponent == null) return;
|
||||
|
||||
var transform = skeletonRendererComponent.transform;
|
||||
var skeleton = skeletonRendererComponent.skeleton;
|
||||
|
||||
if (string.IsNullOrEmpty(boneName.stringValue)) {
|
||||
SpineHandles.DrawBones(transform, skeleton);
|
||||
SpineHandles.DrawBoneNames(transform, skeleton);
|
||||
Handles.Label(tbf.transform.position, "No bone selected", EditorStyles.helpBox);
|
||||
} else {
|
||||
var targetBone = tbf.bone;
|
||||
if (targetBone == null) return;
|
||||
SpineHandles.DrawBoneWireframe(transform, targetBone, SpineHandles.TransformContraintColor);
|
||||
Handles.Label(targetBone.GetWorldPosition(transform), targetBone.Data.Name, SpineHandles.BoneNameStyle);
|
||||
}
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
if (serializedObject.isEditingMultipleObjects) {
|
||||
if (needsReset) {
|
||||
needsReset = false;
|
||||
foreach (var o in targets) {
|
||||
var bf = (BoneFollower)o;
|
||||
bf.Initialize();
|
||||
bf.LateUpdate();
|
||||
}
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawDefaultInspector();
|
||||
needsReset |= EditorGUI.EndChangeCheck();
|
||||
return;
|
||||
}
|
||||
|
||||
if (needsReset && Event.current.type == EventType.Layout) {
|
||||
targetBoneFollower.Initialize();
|
||||
targetBoneFollower.LateUpdate();
|
||||
needsReset = false;
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
serializedObject.Update();
|
||||
|
||||
// Find Renderer
|
||||
if (skeletonRenderer.objectReferenceValue == null) {
|
||||
SkeletonRenderer parentRenderer = targetBoneFollower.GetComponentInParent<SkeletonRenderer>();
|
||||
if (parentRenderer != null && parentRenderer.gameObject != targetBoneFollower.gameObject) {
|
||||
skeletonRenderer.objectReferenceValue = parentRenderer;
|
||||
Debug.Log("Inspector automatically assigned BoneFollower.SkeletonRenderer");
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(skeletonRenderer);
|
||||
var skeletonRendererReference = skeletonRenderer.objectReferenceValue as SkeletonRenderer;
|
||||
if (skeletonRendererReference != null) {
|
||||
if (skeletonRendererReference.gameObject == targetBoneFollower.gameObject) {
|
||||
skeletonRenderer.objectReferenceValue = null;
|
||||
EditorUtility.DisplayDialog("Invalid assignment.", "BoneFollower can only follow a skeleton on a separate GameObject.\n\nCreate a new GameObject for your BoneFollower, or choose a SkeletonRenderer from a different GameObject.", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
if (!targetBoneFollower.valid) {
|
||||
needsReset = true;
|
||||
}
|
||||
|
||||
if (targetBoneFollower.valid) {
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(boneName);
|
||||
needsReset |= EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(followBoneRotation);
|
||||
EditorGUILayout.PropertyField(followXYPosition);
|
||||
EditorGUILayout.PropertyField(followZPosition);
|
||||
EditorGUILayout.PropertyField(followLocalScale);
|
||||
EditorGUILayout.PropertyField(followSkeletonFlip);
|
||||
if ((followSkeletonFlip.hasMultipleDifferentValues || followSkeletonFlip.boolValue == false) &&
|
||||
(followBoneRotation.hasMultipleDifferentValues || followBoneRotation.boolValue == true)) {
|
||||
using (new SpineInspectorUtility.IndentScope())
|
||||
EditorGUILayout.PropertyField(maintainedAxisOrientation);
|
||||
}
|
||||
|
||||
BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower);
|
||||
} else {
|
||||
var boneFollowerSkeletonRenderer = targetBoneFollower.skeletonRenderer;
|
||||
if (boneFollowerSkeletonRenderer == null) {
|
||||
EditorGUILayout.HelpBox("SkeletonRenderer is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonMecanim).", MessageType.Warning);
|
||||
} else {
|
||||
boneFollowerSkeletonRenderer.Initialize(false);
|
||||
|
||||
if (boneFollowerSkeletonRenderer.skeletonDataAsset == null)
|
||||
EditorGUILayout.HelpBox("Assigned SkeletonRenderer does not have SkeletonData assigned to it.", MessageType.Warning);
|
||||
|
||||
if (!boneFollowerSkeletonRenderer.valid)
|
||||
EditorGUILayout.HelpBox("Assigned SkeletonRenderer is invalid. Check target SkeletonRenderer, its SkeletonDataAsset or the console for other errors.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
var current = Event.current;
|
||||
bool wasUndo = (current.type == EventType.ValidateCommand && current.commandName == "UndoRedoPerformed");
|
||||
if (wasUndo)
|
||||
targetBoneFollower.Initialize();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
internal static void RecommendRigidbodyButton (Component component) {
|
||||
bool hasCollider2D = component.GetComponent<Collider2D>() != null || component.GetComponent<BoundingBoxFollower>() != null;
|
||||
bool hasCollider3D = !hasCollider2D && component.GetComponent<Collider>();
|
||||
bool missingRigidBody = (hasCollider2D && component.GetComponent<Rigidbody2D>() == null) || (hasCollider3D && component.GetComponent<Rigidbody>() == null);
|
||||
if (missingRigidBody) {
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
EditorGUILayout.HelpBox("Collider detected. Unity recommends adding a Rigidbody to the Transforms of any colliders that are intended to be dynamically repositioned and rotated.", MessageType.Warning);
|
||||
var rbType = hasCollider2D ? typeof(Rigidbody2D) : typeof(Rigidbody);
|
||||
string rbLabel = string.Format("Add {0}", rbType.Name);
|
||||
var rbContent = SpineInspectorUtility.TempContent(rbLabel, SpineInspectorUtility.UnityIcon(rbType), "Add a rigidbody to this GameObject to be the Physics body parent of the attached collider.");
|
||||
if (SpineInspectorUtility.CenteredButton(rbContent)) component.gameObject.AddComponent(rbType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c71ca35fd6241cb49a0b0756a664fcf7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,261 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
using Event = UnityEngine.Event;
|
||||
using Icons = SpineEditorUtilities.Icons;
|
||||
|
||||
[CustomEditor(typeof(BoundingBoxFollowerGraphic))]
|
||||
public class BoundingBoxFollowerGraphicInspector : UnityEditor.Editor {
|
||||
SerializedProperty skeletonGraphic, slotName, isTrigger, clearStateOnDisable;
|
||||
BoundingBoxFollowerGraphic follower;
|
||||
bool rebuildRequired = false;
|
||||
bool addBoneFollower = false;
|
||||
bool sceneRepaintRequired = false;
|
||||
bool debugIsExpanded;
|
||||
|
||||
GUIContent addBoneFollowerLabel;
|
||||
GUIContent AddBoneFollowerLabel {
|
||||
get {
|
||||
if (addBoneFollowerLabel == null) addBoneFollowerLabel = new GUIContent("Add Bone Follower", Icons.bone);
|
||||
return addBoneFollowerLabel;
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeEditor () {
|
||||
skeletonGraphic = serializedObject.FindProperty("skeletonGraphic");
|
||||
slotName = serializedObject.FindProperty("slotName");
|
||||
isTrigger = serializedObject.FindProperty("isTrigger");
|
||||
clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable");
|
||||
follower = (BoundingBoxFollowerGraphic)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
|
||||
#if !NEW_PREFAB_SYSTEM
|
||||
bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab);
|
||||
#else
|
||||
bool isInspectingPrefab = false;
|
||||
#endif
|
||||
|
||||
// Note: when calling InitializeEditor() in OnEnable, it throws exception
|
||||
// "SerializedObjectNotCreatableException: Object at index 0 is null".
|
||||
InitializeEditor();
|
||||
|
||||
// Try to auto-assign SkeletonGraphic field.
|
||||
if (skeletonGraphic.objectReferenceValue == null) {
|
||||
var foundSkeletonGraphic = follower.GetComponentInParent<SkeletonGraphic>();
|
||||
if (foundSkeletonGraphic != null)
|
||||
Debug.Log("BoundingBoxFollowerGraphic automatically assigned: " + foundSkeletonGraphic.gameObject.name);
|
||||
else if (Event.current.type == EventType.Repaint)
|
||||
Debug.Log("No Spine GameObject detected. Make sure to set this GameObject as a child of the Spine GameObject; or set BoundingBoxFollowerGraphic's 'Skeleton Graphic' field in the inspector.");
|
||||
|
||||
skeletonGraphic.objectReferenceValue = foundSkeletonGraphic;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
InitializeEditor();
|
||||
}
|
||||
|
||||
var skeletonGraphicValue = skeletonGraphic.objectReferenceValue as SkeletonGraphic;
|
||||
if (skeletonGraphicValue != null && skeletonGraphicValue.gameObject == follower.gameObject) {
|
||||
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
|
||||
EditorGUILayout.HelpBox("It's ideal to add BoundingBoxFollowerGraphic to a separate child GameObject of the Spine GameObject.", MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Move BoundingBoxFollowerGraphic to new GameObject", Icons.boundingBox), GUILayout.Height(30f))) {
|
||||
AddBoundingBoxFollowerGraphicChild(skeletonGraphicValue, follower);
|
||||
DestroyImmediate(follower);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(skeletonGraphic);
|
||||
EditorGUILayout.PropertyField(slotName, new GUIContent("Slot"));
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
InitializeEditor();
|
||||
#if !NEW_PREFAB_SYSTEM
|
||||
if (!isInspectingPrefab)
|
||||
rebuildRequired = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
using (new SpineInspectorUtility.LabelWidthScope(150f)) {
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(isTrigger);
|
||||
bool triggerChanged = EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject"));
|
||||
bool clearStateChanged = EditorGUI.EndChangeCheck();
|
||||
|
||||
if (clearStateChanged || triggerChanged) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
InitializeEditor();
|
||||
if (triggerChanged)
|
||||
foreach (var col in follower.colliderTable.Values)
|
||||
col.isTrigger = isTrigger.boolValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInspectingPrefab) {
|
||||
follower.colliderTable.Clear();
|
||||
follower.nameTable.Clear();
|
||||
EditorGUILayout.HelpBox("BoundingBoxAttachments cannot be previewed in prefabs.", MessageType.Info);
|
||||
|
||||
// How do you prevent components from being saved into the prefab? No such HideFlag. DontSaveInEditor | DontSaveInBuild does not work. DestroyImmediate does not work.
|
||||
var collider = follower.GetComponent<PolygonCollider2D>();
|
||||
if (collider != null) Debug.LogWarning("Found BoundingBoxFollowerGraphic collider components in prefab. These are disposed and regenerated at runtime.");
|
||||
|
||||
} else {
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
if (debugIsExpanded = EditorGUILayout.Foldout(debugIsExpanded, "Debug Colliders")) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.LabelField(string.Format("Attachment Names ({0} PolygonCollider2D)", follower.colliderTable.Count));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
foreach (var kp in follower.nameTable) {
|
||||
string attachmentName = kp.Value;
|
||||
var collider = follower.colliderTable[kp.Key];
|
||||
bool isPlaceholder = attachmentName != kp.Key.Name;
|
||||
collider.enabled = EditorGUILayout.ToggleLeft(new GUIContent(!isPlaceholder ? attachmentName : string.Format("{0} [{1}]", attachmentName, kp.Key.Name), isPlaceholder ? Icons.skinPlaceholder : Icons.boundingBox), collider.enabled);
|
||||
}
|
||||
sceneRepaintRequired |= EditorGUI.EndChangeCheck();
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (follower.Slot == null)
|
||||
follower.Initialize(false);
|
||||
bool hasBoneFollower = follower.GetComponent<BoneFollowerGraphic>() != null;
|
||||
if (!hasBoneFollower) {
|
||||
bool buttonDisabled = follower.Slot == null;
|
||||
using (new EditorGUI.DisabledGroupScope(buttonDisabled)) {
|
||||
addBoneFollower |= SpineInspectorUtility.LargeCenteredButton(AddBoneFollowerLabel, true);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Event.current.type == EventType.Repaint) {
|
||||
if (addBoneFollower) {
|
||||
var boneFollower = follower.gameObject.AddComponent<BoneFollowerGraphic>();
|
||||
boneFollower.skeletonGraphic = skeletonGraphicValue;
|
||||
boneFollower.SetBone(follower.Slot.Data.BoneData.Name);
|
||||
addBoneFollower = false;
|
||||
}
|
||||
|
||||
if (sceneRepaintRequired) {
|
||||
SceneView.RepaintAll();
|
||||
sceneRepaintRequired = false;
|
||||
}
|
||||
|
||||
if (rebuildRequired) {
|
||||
follower.Initialize();
|
||||
rebuildRequired = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Menus
|
||||
[MenuItem("CONTEXT/SkeletonGraphic/Add BoundingBoxFollowerGraphic GameObject")]
|
||||
static void AddBoundingBoxFollowerGraphicChild (MenuCommand command) {
|
||||
var go = AddBoundingBoxFollowerGraphicChild((SkeletonGraphic)command.context);
|
||||
Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollowerGraphic");
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/SkeletonGraphic/Add all BoundingBoxFollowerGraphic GameObjects")]
|
||||
static void AddAllBoundingBoxFollowerGraphicChildren (MenuCommand command) {
|
||||
var objects = AddAllBoundingBoxFollowerGraphicChildren((SkeletonGraphic)command.context);
|
||||
foreach (var go in objects)
|
||||
Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollowerGraphic");
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static GameObject AddBoundingBoxFollowerGraphicChild (SkeletonGraphic skeletonGraphic,
|
||||
BoundingBoxFollowerGraphic original = null, string name = "BoundingBoxFollowerGraphic",
|
||||
string slotName = null) {
|
||||
|
||||
var go = EditorInstantiation.NewGameObject(name, true);
|
||||
go.transform.SetParent(skeletonGraphic.transform, false);
|
||||
go.AddComponent<RectTransform>();
|
||||
var newFollower = go.AddComponent<BoundingBoxFollowerGraphic>();
|
||||
|
||||
if (original != null) {
|
||||
newFollower.slotName = original.slotName;
|
||||
newFollower.isTrigger = original.isTrigger;
|
||||
newFollower.clearStateOnDisable = original.clearStateOnDisable;
|
||||
}
|
||||
if (slotName != null)
|
||||
newFollower.slotName = slotName;
|
||||
|
||||
newFollower.skeletonGraphic = skeletonGraphic;
|
||||
newFollower.Initialize();
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
EditorGUIUtility.PingObject(go);
|
||||
return go;
|
||||
}
|
||||
|
||||
public static List<GameObject> AddAllBoundingBoxFollowerGraphicChildren (
|
||||
SkeletonGraphic skeletonGraphic, BoundingBoxFollowerGraphic original = null) {
|
||||
|
||||
List<GameObject> createdGameObjects = new List<GameObject>();
|
||||
foreach (var skin in skeletonGraphic.Skeleton.Data.Skins) {
|
||||
var attachments = skin.Attachments;
|
||||
foreach (var entry in attachments) {
|
||||
var boundingBoxAttachment = entry.Value as BoundingBoxAttachment;
|
||||
if (boundingBoxAttachment == null)
|
||||
continue;
|
||||
int slotIndex = entry.Key.SlotIndex;
|
||||
var slot = skeletonGraphic.Skeleton.Slots.Items[slotIndex];
|
||||
string slotName = slot.Data.Name;
|
||||
GameObject go = AddBoundingBoxFollowerGraphicChild(skeletonGraphic,
|
||||
original, boundingBoxAttachment.Name, slotName);
|
||||
var boneFollower = go.AddComponent<BoneFollowerGraphic>();
|
||||
boneFollower.skeletonGraphic = skeletonGraphic;
|
||||
boneFollower.SetBone(slot.Data.BoneData.Name);
|
||||
createdGameObjects.Add(go);
|
||||
}
|
||||
}
|
||||
return createdGameObjects;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c4f5b276299bc048ad00f3cd2d1ea09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,260 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
using Event = UnityEngine.Event;
|
||||
using Icons = SpineEditorUtilities.Icons;
|
||||
|
||||
[CustomEditor(typeof(BoundingBoxFollower))]
|
||||
public class BoundingBoxFollowerInspector : UnityEditor.Editor {
|
||||
SerializedProperty skeletonRenderer, slotName, isTrigger, clearStateOnDisable;
|
||||
BoundingBoxFollower follower;
|
||||
bool rebuildRequired = false;
|
||||
bool addBoneFollower = false;
|
||||
bool sceneRepaintRequired = false;
|
||||
bool debugIsExpanded;
|
||||
|
||||
GUIContent addBoneFollowerLabel;
|
||||
GUIContent AddBoneFollowerLabel {
|
||||
get {
|
||||
if (addBoneFollowerLabel == null) addBoneFollowerLabel = new GUIContent("Add Bone Follower", Icons.bone);
|
||||
return addBoneFollowerLabel;
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeEditor () {
|
||||
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
|
||||
slotName = serializedObject.FindProperty("slotName");
|
||||
isTrigger = serializedObject.FindProperty("isTrigger");
|
||||
clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable");
|
||||
follower = (BoundingBoxFollower)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
|
||||
#if !NEW_PREFAB_SYSTEM
|
||||
bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab);
|
||||
#else
|
||||
bool isInspectingPrefab = false;
|
||||
#endif
|
||||
|
||||
// Note: when calling InitializeEditor() in OnEnable, it throws exception
|
||||
// "SerializedObjectNotCreatableException: Object at index 0 is null".
|
||||
InitializeEditor();
|
||||
|
||||
// Try to auto-assign SkeletonRenderer field.
|
||||
if (skeletonRenderer.objectReferenceValue == null) {
|
||||
var foundSkeletonRenderer = follower.GetComponentInParent<SkeletonRenderer>();
|
||||
if (foundSkeletonRenderer != null)
|
||||
Debug.Log("BoundingBoxFollower automatically assigned: " + foundSkeletonRenderer.gameObject.name);
|
||||
else if (Event.current.type == EventType.Repaint)
|
||||
Debug.Log("No Spine GameObject detected. Make sure to set this GameObject as a child of the Spine GameObject; or set BoundingBoxFollower's 'Skeleton Renderer' field in the inspector.");
|
||||
|
||||
skeletonRenderer.objectReferenceValue = foundSkeletonRenderer;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
InitializeEditor();
|
||||
}
|
||||
|
||||
var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer;
|
||||
if (skeletonRendererValue != null && skeletonRendererValue.gameObject == follower.gameObject) {
|
||||
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) {
|
||||
EditorGUILayout.HelpBox("It's ideal to add BoundingBoxFollower to a separate child GameObject of the Spine GameObject.", MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Move BoundingBoxFollower to new GameObject", Icons.boundingBox), GUILayout.Height(30f))) {
|
||||
AddBoundingBoxFollowerChild(skeletonRendererValue, follower);
|
||||
DestroyImmediate(follower);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(skeletonRenderer);
|
||||
EditorGUILayout.PropertyField(slotName, new GUIContent("Slot"));
|
||||
if (EditorGUI.EndChangeCheck()) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
InitializeEditor();
|
||||
#if !NEW_PREFAB_SYSTEM
|
||||
if (!isInspectingPrefab)
|
||||
rebuildRequired = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
using (new SpineInspectorUtility.LabelWidthScope(150f)) {
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(isTrigger);
|
||||
bool triggerChanged = EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject"));
|
||||
bool clearStateChanged = EditorGUI.EndChangeCheck();
|
||||
|
||||
if (clearStateChanged || triggerChanged) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
InitializeEditor();
|
||||
if (triggerChanged)
|
||||
foreach (var col in follower.colliderTable.Values)
|
||||
col.isTrigger = isTrigger.boolValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInspectingPrefab) {
|
||||
follower.colliderTable.Clear();
|
||||
follower.nameTable.Clear();
|
||||
EditorGUILayout.HelpBox("BoundingBoxAttachments cannot be previewed in prefabs.", MessageType.Info);
|
||||
|
||||
// How do you prevent components from being saved into the prefab? No such HideFlag. DontSaveInEditor | DontSaveInBuild does not work. DestroyImmediate does not work.
|
||||
var collider = follower.GetComponent<PolygonCollider2D>();
|
||||
if (collider != null) Debug.LogWarning("Found BoundingBoxFollower collider components in prefab. These are disposed and regenerated at runtime.");
|
||||
|
||||
} else {
|
||||
using (new SpineInspectorUtility.BoxScope()) {
|
||||
if (debugIsExpanded = EditorGUILayout.Foldout(debugIsExpanded, "Debug Colliders")) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.LabelField(string.Format("Attachment Names ({0} PolygonCollider2D)", follower.colliderTable.Count));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
foreach (var kp in follower.nameTable) {
|
||||
string attachmentName = kp.Value;
|
||||
var collider = follower.colliderTable[kp.Key];
|
||||
bool isPlaceholder = attachmentName != kp.Key.Name;
|
||||
collider.enabled = EditorGUILayout.ToggleLeft(new GUIContent(!isPlaceholder ? attachmentName : string.Format("{0} [{1}]", attachmentName, kp.Key.Name), isPlaceholder ? Icons.skinPlaceholder : Icons.boundingBox), collider.enabled);
|
||||
}
|
||||
sceneRepaintRequired |= EditorGUI.EndChangeCheck();
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (follower.Slot == null)
|
||||
follower.Initialize(false);
|
||||
bool hasBoneFollower = follower.GetComponent<BoneFollower>() != null;
|
||||
if (!hasBoneFollower) {
|
||||
bool buttonDisabled = follower.Slot == null;
|
||||
using (new EditorGUI.DisabledGroupScope(buttonDisabled)) {
|
||||
addBoneFollower |= SpineInspectorUtility.LargeCenteredButton(AddBoneFollowerLabel, true);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Event.current.type == EventType.Repaint) {
|
||||
if (addBoneFollower) {
|
||||
var boneFollower = follower.gameObject.AddComponent<BoneFollower>();
|
||||
boneFollower.skeletonRenderer = skeletonRendererValue;
|
||||
boneFollower.SetBone(follower.Slot.Data.BoneData.Name);
|
||||
addBoneFollower = false;
|
||||
}
|
||||
|
||||
if (sceneRepaintRequired) {
|
||||
SceneView.RepaintAll();
|
||||
sceneRepaintRequired = false;
|
||||
}
|
||||
|
||||
if (rebuildRequired) {
|
||||
follower.Initialize();
|
||||
rebuildRequired = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Menus
|
||||
[MenuItem("CONTEXT/SkeletonRenderer/Add BoundingBoxFollower GameObject")]
|
||||
static void AddBoundingBoxFollowerChild (MenuCommand command) {
|
||||
var go = AddBoundingBoxFollowerChild((SkeletonRenderer)command.context);
|
||||
Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollower");
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/SkeletonRenderer/Add all BoundingBoxFollower GameObjects")]
|
||||
static void AddAllBoundingBoxFollowerChildren (MenuCommand command) {
|
||||
var objects = AddAllBoundingBoxFollowerChildren((SkeletonRenderer)command.context);
|
||||
foreach (var go in objects)
|
||||
Undo.RegisterCreatedObjectUndo(go, "Add BoundingBoxFollower");
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static GameObject AddBoundingBoxFollowerChild (SkeletonRenderer skeletonRenderer,
|
||||
BoundingBoxFollower original = null, string name = "BoundingBoxFollower",
|
||||
string slotName = null) {
|
||||
|
||||
var go = EditorInstantiation.NewGameObject(name, true);
|
||||
go.transform.SetParent(skeletonRenderer.transform, false);
|
||||
var newFollower = go.AddComponent<BoundingBoxFollower>();
|
||||
|
||||
if (original != null) {
|
||||
newFollower.slotName = original.slotName;
|
||||
newFollower.isTrigger = original.isTrigger;
|
||||
newFollower.clearStateOnDisable = original.clearStateOnDisable;
|
||||
}
|
||||
if (slotName != null)
|
||||
newFollower.slotName = slotName;
|
||||
|
||||
newFollower.skeletonRenderer = skeletonRenderer;
|
||||
newFollower.Initialize();
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
EditorGUIUtility.PingObject(go);
|
||||
return go;
|
||||
}
|
||||
|
||||
public static List<GameObject> AddAllBoundingBoxFollowerChildren (
|
||||
SkeletonRenderer skeletonRenderer, BoundingBoxFollower original = null) {
|
||||
|
||||
List<GameObject> createdGameObjects = new List<GameObject>();
|
||||
foreach (var skin in skeletonRenderer.Skeleton.Data.Skins) {
|
||||
var attachments = skin.Attachments;
|
||||
foreach (var entry in attachments) {
|
||||
var boundingBoxAttachment = entry.Value as BoundingBoxAttachment;
|
||||
if (boundingBoxAttachment == null)
|
||||
continue;
|
||||
int slotIndex = entry.Key.SlotIndex;
|
||||
var slot = skeletonRenderer.Skeleton.Slots.Items[slotIndex];
|
||||
string slotName = slot.Data.Name;
|
||||
GameObject go = AddBoundingBoxFollowerChild(skeletonRenderer,
|
||||
original, boundingBoxAttachment.Name, slotName);
|
||||
var boneFollower = go.AddComponent<BoneFollower>();
|
||||
boneFollower.skeletonRenderer = skeletonRenderer;
|
||||
boneFollower.SetBone(slot.Data.BoneData.Name);
|
||||
createdGameObjects.Add(go);
|
||||
}
|
||||
}
|
||||
return createdGameObjects;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 670a3cefa3853bd48b5da53a424fd542
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 591 B |
@@ -1,92 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fc714a0dc1cf6b4b959e073fff2844e
|
||||
timeCreated: 1508165143
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,50 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
public static class AssetDatabaseAvailabilityDetector {
|
||||
const string MarkerResourceName = "SpineAssetDatabaseMarker";
|
||||
private static bool isMarkerLoaded;
|
||||
|
||||
public static bool IsAssetDatabaseAvailable (bool forceCheck = false) {
|
||||
if (!forceCheck && isMarkerLoaded)
|
||||
return true;
|
||||
|
||||
TextAsset markerTextAsset = Resources.Load<TextAsset>(AssetDatabaseAvailabilityDetector.MarkerResourceName);
|
||||
isMarkerLoaded = markerTextAsset != null;
|
||||
if (markerTextAsset != null) {
|
||||
Resources.UnloadAsset(markerTextAsset);
|
||||
}
|
||||
|
||||
return isMarkerLoaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25086cd81e3158b439761b73d7366c47
|
||||
timeCreated: 1444587791
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49377c72c37e2c149b106c260a241f3c
|
||||
timeCreated: 1563311043
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,282 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
#define UPGRADE_ALL_BLEND_MODE_MATERIALS
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
public class BlendModeMaterialsUtility {
|
||||
|
||||
public const string MATERIAL_SUFFIX_MULTIPLY = "-Multiply";
|
||||
public const string MATERIAL_SUFFIX_SCREEN = "-Screen";
|
||||
public const string MATERIAL_SUFFIX_ADDITIVE = "-Additive";
|
||||
|
||||
#if UPGRADE_ALL_BLEND_MODE_MATERIALS
|
||||
public const bool ShallUpgradeBlendModeMaterials = true;
|
||||
#else
|
||||
public const bool ShallUpgradeBlendModeMaterials = false;
|
||||
#endif
|
||||
|
||||
protected class TemplateMaterials {
|
||||
public Material multiplyTemplate;
|
||||
public Material screenTemplate;
|
||||
public Material additiveTemplate;
|
||||
};
|
||||
|
||||
public static void UpgradeBlendModeMaterials (SkeletonDataAsset skeletonDataAsset) {
|
||||
var skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
||||
if (skeletonData == null)
|
||||
return;
|
||||
UpdateBlendModeMaterials(skeletonDataAsset, ref skeletonData, true);
|
||||
}
|
||||
|
||||
public static void UpdateBlendModeMaterials (SkeletonDataAsset skeletonDataAsset) {
|
||||
var skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
||||
if (skeletonData == null)
|
||||
return;
|
||||
UpdateBlendModeMaterials(skeletonDataAsset, ref skeletonData, false);
|
||||
}
|
||||
|
||||
public static void UpdateBlendModeMaterials (SkeletonDataAsset skeletonDataAsset, ref SkeletonData skeletonData,
|
||||
bool upgradeFromModifierAssets = ShallUpgradeBlendModeMaterials) {
|
||||
|
||||
TemplateMaterials templateMaterials = new TemplateMaterials();
|
||||
bool anyMaterialsChanged = ClearUndesiredMaterialEntries(skeletonDataAsset);
|
||||
|
||||
var blendModesModifierAsset = FindBlendModeMaterialsModifierAsset(skeletonDataAsset);
|
||||
if (blendModesModifierAsset) {
|
||||
if (upgradeFromModifierAssets) {
|
||||
TransferSettingsFromModifierAsset(blendModesModifierAsset,
|
||||
skeletonDataAsset, templateMaterials);
|
||||
UpdateBlendmodeMaterialsRequiredState(skeletonDataAsset, skeletonData);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (!UpdateBlendmodeMaterialsRequiredState(skeletonDataAsset, skeletonData))
|
||||
return;
|
||||
AssignPreferencesTemplateMaterials(templateMaterials);
|
||||
}
|
||||
bool success = CreateAndAssignMaterials(skeletonDataAsset, templateMaterials, ref anyMaterialsChanged);
|
||||
if (success) {
|
||||
if (blendModesModifierAsset != null) {
|
||||
RemoveObsoleteModifierAsset(blendModesModifierAsset, skeletonDataAsset);
|
||||
}
|
||||
}
|
||||
|
||||
skeletonDataAsset.Clear();
|
||||
skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
||||
if (anyMaterialsChanged)
|
||||
ReloadSceneSkeletons(skeletonDataAsset);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
protected static bool ClearUndesiredMaterialEntries (SkeletonDataAsset skeletonDataAsset) {
|
||||
Predicate<BlendModeMaterials.ReplacementMaterial> ifMaterialMissing = r => r.material == null;
|
||||
|
||||
bool anyMaterialsChanged = false;
|
||||
if (!skeletonDataAsset.blendModeMaterials.applyAdditiveMaterial) {
|
||||
anyMaterialsChanged |= skeletonDataAsset.blendModeMaterials.additiveMaterials.Count > 0;
|
||||
skeletonDataAsset.blendModeMaterials.additiveMaterials.Clear();
|
||||
}
|
||||
else
|
||||
anyMaterialsChanged |= skeletonDataAsset.blendModeMaterials.additiveMaterials.RemoveAll(ifMaterialMissing) != 0;
|
||||
anyMaterialsChanged |= skeletonDataAsset.blendModeMaterials.multiplyMaterials.RemoveAll(ifMaterialMissing) != 0;
|
||||
anyMaterialsChanged |= skeletonDataAsset.blendModeMaterials.screenMaterials.RemoveAll(ifMaterialMissing) != 0;
|
||||
return anyMaterialsChanged;
|
||||
}
|
||||
|
||||
protected static BlendModeMaterialsAsset FindBlendModeMaterialsModifierAsset (SkeletonDataAsset skeletonDataAsset) {
|
||||
foreach (var modifierAsset in skeletonDataAsset.skeletonDataModifiers) {
|
||||
if (modifierAsset is BlendModeMaterialsAsset)
|
||||
return (BlendModeMaterialsAsset)modifierAsset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static bool UpdateBlendmodeMaterialsRequiredState (SkeletonDataAsset skeletonDataAsset, SkeletonData skeletonData) {
|
||||
return skeletonDataAsset.blendModeMaterials.UpdateBlendmodeMaterialsRequiredState(skeletonData);
|
||||
}
|
||||
|
||||
protected static void TransferSettingsFromModifierAsset (BlendModeMaterialsAsset modifierAsset,
|
||||
SkeletonDataAsset skeletonDataAsset, TemplateMaterials templateMaterials) {
|
||||
|
||||
skeletonDataAsset.blendModeMaterials.TransferSettingsFrom(modifierAsset);
|
||||
|
||||
templateMaterials.multiplyTemplate = modifierAsset.multiplyMaterialTemplate;
|
||||
templateMaterials.screenTemplate = modifierAsset.screenMaterialTemplate;
|
||||
templateMaterials.additiveTemplate = modifierAsset.additiveMaterialTemplate;
|
||||
}
|
||||
|
||||
protected static void RemoveObsoleteModifierAsset (BlendModeMaterialsAsset modifierAsset,
|
||||
SkeletonDataAsset skeletonDataAsset) {
|
||||
|
||||
skeletonDataAsset.skeletonDataModifiers.Remove(modifierAsset);
|
||||
Debug.Log(string.Format("BlendModeMaterialsAsset upgraded to built-in BlendModeMaterials at SkeletonDataAsset '{0}'.",
|
||||
skeletonDataAsset.name), skeletonDataAsset);
|
||||
EditorUtility.SetDirty(skeletonDataAsset);
|
||||
}
|
||||
|
||||
protected static void AssignPreferencesTemplateMaterials (TemplateMaterials templateMaterials) {
|
||||
|
||||
templateMaterials.multiplyTemplate = SpineEditorUtilities.Preferences.BlendModeMaterialMultiply;
|
||||
templateMaterials.screenTemplate = SpineEditorUtilities.Preferences.BlendModeMaterialScreen;
|
||||
templateMaterials.additiveTemplate = SpineEditorUtilities.Preferences.BlendModeMaterialAdditive;
|
||||
}
|
||||
|
||||
protected static bool CreateAndAssignMaterials (SkeletonDataAsset skeletonDataAsset,
|
||||
TemplateMaterials templateMaterials, ref bool anyReplacementMaterialsChanged) {
|
||||
|
||||
bool anyCreationFailed = false;
|
||||
var blendModeMaterials = skeletonDataAsset.blendModeMaterials;
|
||||
bool applyAdditiveMaterial = blendModeMaterials.applyAdditiveMaterial;
|
||||
|
||||
var skinEntries = new List<Skin.SkinEntry>();
|
||||
|
||||
skeletonDataAsset.Clear();
|
||||
skeletonDataAsset.isUpgradingBlendModeMaterials = true;
|
||||
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);
|
||||
|
||||
var slotsItems = skeletonData.Slots.Items;
|
||||
for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) {
|
||||
var slot = slotsItems[slotIndex];
|
||||
if (slot.BlendMode == BlendMode.Normal) continue;
|
||||
if (!applyAdditiveMaterial && slot.BlendMode == BlendMode.Additive) continue;
|
||||
|
||||
List<BlendModeMaterials.ReplacementMaterial> replacementMaterials = null;
|
||||
Material materialTemplate = null;
|
||||
string materialSuffix = null;
|
||||
switch (slot.BlendMode) {
|
||||
case BlendMode.Multiply:
|
||||
replacementMaterials = blendModeMaterials.multiplyMaterials;
|
||||
materialTemplate = templateMaterials.multiplyTemplate;
|
||||
materialSuffix = MATERIAL_SUFFIX_MULTIPLY;
|
||||
break;
|
||||
case BlendMode.Screen:
|
||||
replacementMaterials = blendModeMaterials.screenMaterials;
|
||||
materialTemplate = templateMaterials.screenTemplate;
|
||||
materialSuffix = MATERIAL_SUFFIX_SCREEN;
|
||||
break;
|
||||
case BlendMode.Additive:
|
||||
replacementMaterials = blendModeMaterials.additiveMaterials;
|
||||
materialTemplate = templateMaterials.additiveTemplate;
|
||||
materialSuffix = MATERIAL_SUFFIX_ADDITIVE;
|
||||
break;
|
||||
}
|
||||
|
||||
skinEntries.Clear();
|
||||
foreach (var skin in skeletonData.Skins)
|
||||
skin.GetAttachments(slotIndex, skinEntries);
|
||||
|
||||
foreach (var entry in skinEntries) {
|
||||
var renderableAttachment = entry.Attachment as IHasRendererObject;
|
||||
if (renderableAttachment != null) {
|
||||
var originalRegion = (AtlasRegion)renderableAttachment.RendererObject;
|
||||
bool replacementExists = replacementMaterials.Exists(
|
||||
replacement => replacement.pageName == originalRegion.page.name);
|
||||
if (!replacementExists) {
|
||||
bool createdNewMaterial;
|
||||
var replacement = CreateOrLoadReplacementMaterial(originalRegion, materialTemplate, materialSuffix, out createdNewMaterial);
|
||||
if (replacement != null) {
|
||||
replacementMaterials.Add(replacement);
|
||||
anyReplacementMaterialsChanged = true;
|
||||
if (createdNewMaterial) {
|
||||
Debug.Log(string.Format("Created blend mode Material '{0}' for SkeletonDataAsset '{1}'.",
|
||||
replacement.material.name, skeletonDataAsset), replacement.material);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Debug.LogError(string.Format("Failed creating blend mode Material for SkeletonDataAsset '{0}',"+
|
||||
" atlas page '{1}', template '{2}'.",
|
||||
skeletonDataAsset.name, originalRegion.page.name, materialTemplate.name),
|
||||
skeletonDataAsset);
|
||||
anyCreationFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skeletonDataAsset.isUpgradingBlendModeMaterials = false;
|
||||
EditorUtility.SetDirty(skeletonDataAsset);
|
||||
return !anyCreationFailed;
|
||||
}
|
||||
|
||||
protected static string GetBlendModeMaterialPath(AtlasPage originalPage, string materialSuffix) {
|
||||
var originalMaterial = originalPage.rendererObject as Material;
|
||||
var originalPath = AssetDatabase.GetAssetPath(originalMaterial);
|
||||
return originalPath.Replace(".mat", materialSuffix + ".mat");
|
||||
}
|
||||
|
||||
protected static BlendModeMaterials.ReplacementMaterial CreateOrLoadReplacementMaterial (
|
||||
AtlasRegion originalRegion, Material materialTemplate, string materialSuffix, out bool createdNewMaterial) {
|
||||
|
||||
createdNewMaterial = false;
|
||||
var newReplacement = new BlendModeMaterials.ReplacementMaterial();
|
||||
var originalPage = originalRegion.page;
|
||||
var originalMaterial = originalPage.rendererObject as Material;
|
||||
var blendMaterialPath = GetBlendModeMaterialPath(originalPage, materialSuffix);
|
||||
|
||||
newReplacement.pageName = originalPage.name;
|
||||
if (File.Exists(blendMaterialPath)) {
|
||||
newReplacement.material = AssetDatabase.LoadAssetAtPath<Material>(blendMaterialPath);
|
||||
}
|
||||
else {
|
||||
var blendModeMaterial = new Material(materialTemplate) {
|
||||
name = originalMaterial.name + " " + materialTemplate.name,
|
||||
mainTexture = originalMaterial.mainTexture
|
||||
};
|
||||
newReplacement.material = blendModeMaterial;
|
||||
|
||||
AssetDatabase.CreateAsset(blendModeMaterial, blendMaterialPath);
|
||||
EditorUtility.SetDirty(blendModeMaterial);
|
||||
createdNewMaterial = true;
|
||||
}
|
||||
|
||||
if (newReplacement.material)
|
||||
return newReplacement;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static void ReloadSceneSkeletons (SkeletonDataAsset skeletonDataAsset) {
|
||||
if (SpineEditorUtilities.Preferences.autoReloadSceneSkeletons)
|
||||
SpineEditorUtilities.DataReloadHandler.ReloadSceneSkeletonComponents(skeletonDataAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8094f8aedb33b7744b109c2c1294d37a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,182 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma warning disable 0219
|
||||
|
||||
#define SPINE_SKELETONMECANIM
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEW_PREFAB_SYSTEM
|
||||
#endif
|
||||
|
||||
#if UNITY_2018 || UNITY_2019 || UNITY_2018_3_OR_NEWER
|
||||
#define NEWHIERARCHYWINDOWCALLBACKS
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
public partial class SpineEditorUtilities {
|
||||
public static class SpineTK2DEditorUtility {
|
||||
const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
|
||||
|
||||
internal static bool IsTK2DInstalled () {
|
||||
return (Shader.Find("tk2d/SolidVertexColor") != null ||
|
||||
Shader.Find("tk2d/AdditiveVertexColor") != null);
|
||||
}
|
||||
|
||||
internal static bool IsTK2DAllowed {
|
||||
get {
|
||||
return false; // replace with "return true;" to allow TK2D support
|
||||
}
|
||||
}
|
||||
|
||||
internal static void EnableTK2D () {
|
||||
if (!IsTK2DAllowed)
|
||||
return;
|
||||
SpineBuildEnvUtility.DisableSpineAsmdefFiles();
|
||||
SpineBuildEnvUtility.EnableBuildDefine(SPINE_TK2D_DEFINE);
|
||||
}
|
||||
|
||||
internal static void DisableTK2D () {
|
||||
SpineBuildEnvUtility.EnableSpineAsmdefFiles();
|
||||
SpineBuildEnvUtility.DisableBuildDefine(SPINE_TK2D_DEFINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpineBuildEnvUtility
|
||||
{
|
||||
static bool IsInvalidGroup (BuildTargetGroup group) {
|
||||
int gi = (int)group;
|
||||
return
|
||||
gi == 15 || gi == 16
|
||||
||
|
||||
group == BuildTargetGroup.Unknown;
|
||||
}
|
||||
|
||||
public static bool EnableBuildDefine (string define) {
|
||||
|
||||
bool wasDefineAdded = false;
|
||||
Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" below");
|
||||
foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
|
||||
if (IsInvalidGroup(group))
|
||||
continue;
|
||||
|
||||
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
|
||||
if (!defines.Contains(define)) {
|
||||
wasDefineAdded = true;
|
||||
if (defines.EndsWith(";", System.StringComparison.Ordinal))
|
||||
defines += define;
|
||||
else
|
||||
defines += ";" + define;
|
||||
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
|
||||
}
|
||||
}
|
||||
Debug.LogWarning("Please ignore errors \"PlayerSettings Validation: Requested build target group doesn't exist\" above");
|
||||
|
||||
if (wasDefineAdded) {
|
||||
Debug.LogWarning("Setting Scripting Define Symbol " + define);
|
||||
}
|
||||
else {
|
||||
Debug.LogWarning("Already Set Scripting Define Symbol " + define);
|
||||
}
|
||||
return wasDefineAdded;
|
||||
}
|
||||
|
||||
public static bool DisableBuildDefine (string define) {
|
||||
|
||||
bool wasDefineRemoved = false;
|
||||
foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
|
||||
if (IsInvalidGroup(group))
|
||||
continue;
|
||||
|
||||
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
|
||||
if (defines.Contains(define)) {
|
||||
wasDefineRemoved = true;
|
||||
if (defines.Contains(define + ";"))
|
||||
defines = defines.Replace(define + ";", "");
|
||||
else
|
||||
defines = defines.Replace(define, "");
|
||||
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
|
||||
}
|
||||
}
|
||||
|
||||
if (wasDefineRemoved) {
|
||||
Debug.LogWarning("Removing Scripting Define Symbol " + define);
|
||||
}
|
||||
else {
|
||||
Debug.LogWarning("Already Removed Scripting Define Symbol " + define);
|
||||
}
|
||||
return wasDefineRemoved;
|
||||
}
|
||||
|
||||
public static void DisableSpineAsmdefFiles () {
|
||||
SetAsmdefFileActive("spine-unity-editor", false);
|
||||
SetAsmdefFileActive("spine-unity", false);
|
||||
}
|
||||
|
||||
public static void EnableSpineAsmdefFiles () {
|
||||
SetAsmdefFileActive("spine-unity-editor", true);
|
||||
SetAsmdefFileActive("spine-unity", true);
|
||||
}
|
||||
|
||||
internal static void SetAsmdefFileActive (string filename, bool setActive) {
|
||||
|
||||
string typeSearchString = setActive ? " t:TextAsset" : " t:AssemblyDefinitionAsset";
|
||||
string extensionBeforeChange = setActive ? ".txt" : ".asmdef";
|
||||
string[] guids = AssetDatabase.FindAssets(filename + typeSearchString);
|
||||
foreach (string guid in guids) {
|
||||
string currentPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (System.IO.Path.GetExtension(currentPath) != extensionBeforeChange) // asmdef is also found as t:TextAsset, so check
|
||||
continue;
|
||||
|
||||
string targetPath = System.IO.Path.ChangeExtension(currentPath, setActive ? "asmdef" : "txt");
|
||||
if (System.IO.File.Exists(currentPath) && !System.IO.File.Exists(targetPath)) {
|
||||
System.IO.File.Copy(currentPath, targetPath);
|
||||
System.IO.File.Copy(currentPath + ".meta", targetPath + ".meta");
|
||||
}
|
||||
AssetDatabase.DeleteAsset(currentPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80767dcb23931c645ad70c88670ddeb6
|
||||
timeCreated: 1563313275
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,145 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma warning disable 0219
|
||||
|
||||
#define SPINE_SKELETONMECANIM
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
#define NEWPLAYMODECALLBACKS
|
||||
#endif
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Spine.Unity.Editor {
|
||||
|
||||
public partial class SpineEditorUtilities {
|
||||
public static class DataReloadHandler {
|
||||
|
||||
internal static Dictionary<int, string> savedSkeletonDataAssetAtSKeletonGraphicID = new Dictionary<int, string>();
|
||||
|
||||
#if NEWPLAYMODECALLBACKS
|
||||
internal static void OnPlaymodeStateChanged (PlayModeStateChange stateChange) {
|
||||
#else
|
||||
internal static void OnPlaymodeStateChanged () {
|
||||
#endif
|
||||
ReloadAllActiveSkeletonsEditMode();
|
||||
}
|
||||
|
||||
public static void ReloadAllActiveSkeletonsEditMode () {
|
||||
|
||||
if (EditorApplication.isPaused) return;
|
||||
if (EditorApplication.isPlaying) return;
|
||||
if (EditorApplication.isCompiling) return;
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
|
||||
|
||||
var skeletonDataAssetsToReload = new HashSet<SkeletonDataAsset>();
|
||||
|
||||
var activeSkeletonRenderers = GameObject.FindObjectsOfType<SkeletonRenderer>();
|
||||
foreach (var sr in activeSkeletonRenderers) {
|
||||
var skeletonDataAsset = sr.skeletonDataAsset;
|
||||
if (skeletonDataAsset != null) skeletonDataAssetsToReload.Add(skeletonDataAsset);
|
||||
}
|
||||
|
||||
// Under some circumstances (e.g. on first import) SkeletonGraphic objects
|
||||
// have their skeletonGraphic.skeletonDataAsset reference corrupted
|
||||
// by the instance of the ScriptableObject being destroyed but still assigned.
|
||||
// Here we save the skeletonGraphic.skeletonDataAsset asset path in order
|
||||
// to restore it later.
|
||||
var activeSkeletonGraphics = GameObject.FindObjectsOfType<SkeletonGraphic>();
|
||||
foreach (var sg in activeSkeletonGraphics) {
|
||||
var skeletonDataAsset = sg.skeletonDataAsset;
|
||||
if (skeletonDataAsset != null) {
|
||||
var assetPath = AssetDatabase.GetAssetPath(skeletonDataAsset);
|
||||
var sgID = sg.GetInstanceID();
|
||||
savedSkeletonDataAssetAtSKeletonGraphicID[sgID] = assetPath;
|
||||
skeletonDataAssetsToReload.Add(skeletonDataAsset);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sda in skeletonDataAssetsToReload) {
|
||||
sda.Clear();
|
||||
sda.GetSkeletonData(true);
|
||||
}
|
||||
|
||||
foreach (var sr in activeSkeletonRenderers) {
|
||||
var meshRenderer = sr.GetComponent<MeshRenderer>();
|
||||
var sharedMaterials = meshRenderer.sharedMaterials;
|
||||
foreach (var m in sharedMaterials) {
|
||||
if (m == null) {
|
||||
sr.Initialize(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sg in activeSkeletonGraphics) {
|
||||
if (sg.mainTexture == null)
|
||||
sg.Initialize(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReloadSceneSkeletonComponents (SkeletonDataAsset skeletonDataAsset) {
|
||||
if (EditorApplication.isPaused) return;
|
||||
if (EditorApplication.isPlaying) return;
|
||||
if (EditorApplication.isCompiling) return;
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
|
||||
|
||||
var activeSkeletonRenderers = GameObject.FindObjectsOfType<SkeletonRenderer>();
|
||||
foreach (var sr in activeSkeletonRenderers) {
|
||||
if (sr.isActiveAndEnabled && sr.skeletonDataAsset == skeletonDataAsset) sr.Initialize(true);
|
||||
}
|
||||
|
||||
var activeSkeletonGraphics = GameObject.FindObjectsOfType<SkeletonGraphic>();
|
||||
foreach (var sg in activeSkeletonGraphics) {
|
||||
if (sg.isActiveAndEnabled && sg.skeletonDataAsset == skeletonDataAsset) sg.Initialize(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReloadAnimationReferenceAssets (SkeletonDataAsset skeletonDataAsset) {
|
||||
string[] guids = UnityEditor.AssetDatabase.FindAssets("t:AnimationReferenceAsset");
|
||||
foreach (string guid in guids) {
|
||||
string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (!string.IsNullOrEmpty(path)) {
|
||||
var referenceAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<AnimationReferenceAsset>(path);
|
||||
if (referenceAsset.SkeletonDataAsset == skeletonDataAsset)
|
||||
referenceAsset.Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8a1a76014a68634a8ede50af6db1cae
|
||||
timeCreated: 1563310382
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user