提交Spine插件

This commit is contained in:
YiHan0621
2025-08-28 18:32:49 +08:00
parent 254a40d87d
commit 316427ebef
970 changed files with 139525 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6351693f94cbf774182d4b3f2a756a43
folderAsset: yes
timeCreated: 1527569401
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b7f013ad20f0af34e913e21b44466777
folderAsset: yes
timeCreated: 1455492480
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,215 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* 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;
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 OnEnable () {
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
// 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();
}
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(50f))) {
AddBoundingBoxFollowerChild(skeletonRendererValue, follower);
DestroyImmediate(follower);
return;
}
}
EditorGUILayout.Space();
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(skeletonRenderer);
EditorGUILayout.PropertyField(slotName, new GUIContent("Slot"));
if (EditorGUI.EndChangeCheck()) {
serializedObject.ApplyModifiedProperties();
#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();
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--;
}
}
}
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");
}
#endregion
static GameObject AddBoundingBoxFollowerChild (SkeletonRenderer sr, BoundingBoxFollower original = null) {
var go = SpineEditorUtilities.EditorInstantiation.NewGameObject("BoundingBoxFollower");
go.transform.SetParent(sr.transform, false);
var newFollower = go.AddComponent<BoundingBoxFollower>();
if (original != null) {
newFollower.slotName = original.slotName;
newFollower.isTrigger = original.isTrigger;
newFollower.clearStateOnDisable = original.clearStateOnDisable;
}
newFollower.skeletonRenderer = sr;
newFollower.Initialize();
Selection.activeGameObject = go;
EditorGUIUtility.PingObject(go);
return go;
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 670a3cefa3853bd48b5da53a424fd542
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ffde24e0e567a61418f76218f8cffb4c
folderAsset: yes
timeCreated: 1527569418
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 99abd7478ddde384cbf86f2ecd396900
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,165 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#define SPINE_OPTIONAL_MATERIALOVERRIDE
// Contributed by: Lost Polygon
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Spine.Unity.Modules;
namespace Spine.Unity.Editor {
// This script is not intended for use with code. See the readme.txt file in SkeletonRendererCustomMaterials folder to learn more.
[CustomEditor(typeof(SkeletonRendererCustomMaterials))]
public class SkeletonRendererCustomMaterialsInspector : UnityEditor.Editor {
List<SkeletonRendererCustomMaterials.AtlasMaterialOverride> componentCustomMaterialOverrides, _customMaterialOverridesPrev;
List<SkeletonRendererCustomMaterials.SlotMaterialOverride> componentCustomSlotMaterials, _customSlotMaterialsPrev;
SkeletonRendererCustomMaterials component;
const BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo RemoveCustomMaterialOverrides, RemoveCustomSlotMaterials, SetCustomMaterialOverrides, SetCustomSlotMaterials;
#region SkeletonRenderer context menu
[MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials")]
static void AddSkeletonRendererCustomMaterials (MenuCommand menuCommand) {
var skeletonRenderer = (SkeletonRenderer)menuCommand.context;
var newComponent = skeletonRenderer.gameObject.AddComponent<SkeletonRendererCustomMaterials>();
Undo.RegisterCreatedObjectUndo(newComponent, "Add Basic Serialized Custom Materials");
}
[MenuItem("CONTEXT/SkeletonRenderer/Add Basic Serialized Custom Materials", true)]
static bool AddSkeletonRendererCustomMaterials_Validate (MenuCommand menuCommand) {
var skeletonRenderer = (SkeletonRenderer)menuCommand.context;
return (skeletonRenderer.GetComponent<SkeletonRendererCustomMaterials>() == null);
}
#endregion
void OnEnable () {
Type cm = typeof(SkeletonRendererCustomMaterials);
RemoveCustomMaterialOverrides = cm.GetMethod("RemoveCustomMaterialOverrides", PrivateInstance);
RemoveCustomSlotMaterials = cm.GetMethod("RemoveCustomSlotMaterials", PrivateInstance);
SetCustomMaterialOverrides = cm.GetMethod("SetCustomMaterialOverrides", PrivateInstance);
SetCustomSlotMaterials = cm.GetMethod("SetCustomSlotMaterials", PrivateInstance);
}
public override void OnInspectorGUI () {
component = (SkeletonRendererCustomMaterials)target;
var skeletonRenderer = component.skeletonRenderer;
// Draw the default inspector
DrawDefaultInspector();
if (serializedObject.isEditingMultipleObjects)
return;
if (componentCustomMaterialOverrides == null) {
Type cm = typeof(SkeletonRendererCustomMaterials);
componentCustomMaterialOverrides = cm.GetField("customMaterialOverrides", PrivateInstance).GetValue(component) as List<SkeletonRendererCustomMaterials.AtlasMaterialOverride>;
componentCustomSlotMaterials = cm.GetField("customSlotMaterials", PrivateInstance).GetValue(component) as List<SkeletonRendererCustomMaterials.SlotMaterialOverride>;
if (componentCustomMaterialOverrides == null) {
Debug.Log("Reflection failed.");
return;
}
}
// Fill with current values at start
if (_customMaterialOverridesPrev == null || _customSlotMaterialsPrev == null) {
_customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides);
_customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials);
}
// Compare new values with saved. If change is detected:
// store new values, restore old values, remove overrides, restore new values, restore overrides.
// 1. Store new values
var customMaterialOverridesNew = CopyList(componentCustomMaterialOverrides);
var customSlotMaterialsNew = CopyList(componentCustomSlotMaterials);
// Detect changes
if (!_customMaterialOverridesPrev.SequenceEqual(customMaterialOverridesNew) ||
!_customSlotMaterialsPrev.SequenceEqual(customSlotMaterialsNew)) {
// 2. Restore old values
componentCustomMaterialOverrides.Clear();
componentCustomSlotMaterials.Clear();
componentCustomMaterialOverrides.AddRange(_customMaterialOverridesPrev);
componentCustomSlotMaterials.AddRange(_customSlotMaterialsPrev);
// 3. Remove overrides
RemoveCustomMaterials();
// 4. Restore new values
componentCustomMaterialOverrides.Clear();
componentCustomSlotMaterials.Clear();
componentCustomMaterialOverrides.AddRange(customMaterialOverridesNew);
componentCustomSlotMaterials.AddRange(customSlotMaterialsNew);
// 5. Restore overrides
SetCustomMaterials();
if (skeletonRenderer != null)
skeletonRenderer.LateUpdate();
}
_customMaterialOverridesPrev = CopyList(componentCustomMaterialOverrides);
_customSlotMaterialsPrev = CopyList(componentCustomSlotMaterials);
if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Clear and Reapply Changes", tooltip: "Removes all non-serialized overrides in the SkeletonRenderer and reapplies the overrides on this component."))) {
if (skeletonRenderer != null) {
#if SPINE_OPTIONAL_MATERIALOVERRIDE
skeletonRenderer.CustomMaterialOverride.Clear();
#endif
skeletonRenderer.CustomSlotMaterials.Clear();
RemoveCustomMaterials();
SetCustomMaterials();
skeletonRenderer.LateUpdate();
}
}
}
void RemoveCustomMaterials () {
RemoveCustomMaterialOverrides.Invoke(component, null);
RemoveCustomSlotMaterials.Invoke(component, null);
}
void SetCustomMaterials () {
SetCustomMaterialOverrides.Invoke(component, null);
SetCustomSlotMaterials.Invoke(component, null);
}
static List<T> CopyList<T> (List<T> list) {
return list.GetRange(0, list.Count);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e70f7f2a241d6d34aafd6a4a52a368d0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a5ca7a6f2b7e25646ad2f5776178bf78
folderAsset: yes
timeCreated: 1527569438
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 7220dc1e8d545e849a2eb63e8633349b
folderAsset: yes
DefaultImporter:
userData:

View File

@@ -0,0 +1,37 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
// Contributed by: Mitch Thompson
using UnityEngine;
using UnityEditor;
namespace Spine.Unity.Modules {
public class SkeletonRagdoll2DInspector {}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b6dd0b99faf3aeb4d803eb9989cb369c
timeCreated: 1431741936
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
// Contributed by: Mitch Thompson
using UnityEngine;
using UnityEditor;
namespace Spine.Unity.Modules {
public class SkeletonRagdollInspector : UnityEditor.Editor {
[CustomPropertyDrawer(typeof(SkeletonRagdoll.LayerFieldAttribute))]
public class LayerFieldPropertyDrawer : PropertyDrawer {
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
property.intValue = EditorGUI.LayerField(position, label, property.intValue);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c95a670c56447c644a0f062e4cdd448e
timeCreated: 1431740230
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 10e0b626d7ae7394a934ee9f2fb81b5a
folderAsset: yes
timeCreated: 1527569604
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f9ef69c370f1b0f4db091a85df7f2c96
folderAsset: yes
timeCreated: 1527569612
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7bebbafa671002646b3a7267b32a0d60
folderAsset: yes
timeCreated: 1479419399
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,972 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using UnityEditor;
using SpineInspectorUtility = Spine.Unity.Editor.SpineInspectorUtility;
public class SpineSpriteShaderGUI : ShaderGUI {
static readonly string kShaderVertexLit = "Spine/Sprite/Vertex Lit";
static readonly string kShaderPixelLit = "Spine/Sprite/Pixel Lit";
static readonly string kShaderUnlit = "Spine/Sprite/Unlit";
static readonly int kSolidQueue = 2000;
static readonly int kAlphaTestQueue = 2450;
static readonly int kTransparentQueue = 3000;
private enum eBlendMode {
PreMultipliedAlpha,
StandardAlpha,
Opaque,
Additive,
SoftAdditive,
Multiply,
Multiplyx2,
};
private enum eLightMode {
VertexLit,
PixelLit,
Unlit,
};
private enum eCulling {
Off = 0,
Front = 1,
Back = 2,
};
private enum eNormalsMode {
MeshNormals = -1,
FixedNormalsViewSpace = 0,
FixedNormalsModelSpace = 1,
};
MaterialEditor _materialEditor;
MaterialProperty _mainTexture = null;
MaterialProperty _color = null;
MaterialProperty _pixelSnap = null;
MaterialProperty _writeToDepth = null;
MaterialProperty _depthAlphaCutoff = null;
MaterialProperty _shadowAlphaCutoff = null;
MaterialProperty _renderQueue = null;
MaterialProperty _culling = null;
MaterialProperty _customRenderQueue = null;
MaterialProperty _overlayColor = null;
MaterialProperty _hue = null;
MaterialProperty _saturation = null;
MaterialProperty _brightness = null;
MaterialProperty _rimPower = null;
MaterialProperty _rimColor = null;
MaterialProperty _bumpMap = null;
MaterialProperty _bumpScale = null;
MaterialProperty _diffuseRamp = null;
MaterialProperty _fixedNormal = null;
MaterialProperty _blendTexture = null;
MaterialProperty _blendTextureLerp = null;
MaterialProperty _emissionMap = null;
MaterialProperty _emissionColor = null;
MaterialProperty _emissionPower = null;
MaterialProperty _metallic = null;
MaterialProperty _metallicGlossMap = null;
MaterialProperty _smoothness = null;
MaterialProperty _smoothnessScale = null;
static GUIContent _albedoText = new GUIContent("Albedo", "Albedo (RGB) and Transparency (A)");
static GUIContent _altAlbedoText = new GUIContent("Secondary Albedo", "When a secondary albedo texture is set the albedo will be a blended mix of the two textures based on the blend value.");
static GUIContent _metallicMapText = new GUIContent("Metallic", "Metallic (R) and Smoothness (A)");
static GUIContent _smoothnessText = new GUIContent("Smoothness", "Smoothness value");
static GUIContent _smoothnessScaleText = new GUIContent("Smoothness", "Smoothness scale factor");
static GUIContent _normalMapText = new GUIContent("Normal Map", "Normal Map");
static GUIContent _emissionText = new GUIContent("Emission", "Emission (RGB)");
static GUIContent _emissionPowerText = new GUIContent("Emission Power");
static GUIContent _emissionToggleText = new GUIContent("Emission", "Enable Emission.");
static GUIContent _diffuseRampText = new GUIContent("Diffuse Ramp", "A black and white gradient can be used to create a 'Toon Shading' effect.");
static GUIContent _depthText = new GUIContent("Write to Depth", "Write to Depth Buffer by clipping alpha.");
static GUIContent _depthAlphaCutoffText = new GUIContent("Depth Alpha Cutoff", "Threshold for depth write alpha cutoff");
static GUIContent _shadowAlphaCutoffText = new GUIContent("Shadow Alpha Cutoff", "Threshold for shadow alpha cutoff");
static GUIContent _fixedNormalText = new GUIContent("Fixed Normals", "If this is ticked instead of requiring mesh normals a Fixed Normal will be used instead (it's quicker and can result in better looking lighting effects on 2d objects).");
static GUIContent _fixedNormalDirectionText = new GUIContent("Fixed Normal Direction", "Should normally be (0,0,1) if in view-space or (0,0,-1) if in model-space.");
static GUIContent _adjustBackfaceTangentText = new GUIContent("Adjust Back-face Tangents", "Tick only if you are going to rotate the sprite to face away from the camera, the tangents will be flipped when this is the case to make lighting correct.");
static GUIContent _sphericalHarmonicsText = new GUIContent("Spherical Harmonics", "Enable to use spherical harmonics to calculate ambient light / light probes. In vertex-lit mode this will be approximated from scenes ambient trilight settings.");
static GUIContent _lightingModeText = new GUIContent("Lighting Mode", "Lighting Mode");
static GUIContent[] _lightingModeOptions = {
new GUIContent("Vertex Lit"),
new GUIContent("Pixel Lit"),
new GUIContent("Unlit")
};
static GUIContent _blendModeText = new GUIContent("Blend Mode", "Blend Mode");
static GUIContent[] _blendModeOptions = {
new GUIContent("Pre-Multiplied Alpha"),
new GUIContent("Standard Alpha"),
new GUIContent("Opaque"),
new GUIContent("Additive"),
new GUIContent("Soft Additive"),
new GUIContent("Multiply"),
new GUIContent("Multiply x2")
};
static GUIContent _rendererQueueText = new GUIContent("Renderer Queue");
static GUIContent _cullingModeText = new GUIContent("Culling Mode");
static GUIContent[] _cullingModeOptions = { new GUIContent("Off"), new GUIContent("Front"), new GUIContent("Back") };
static GUIContent _pixelSnapText = new GUIContent("Pixel Snap");
//static GUIContent _customRenderTypetagsText = new GUIContent("Use Custom RenderType tags");
static GUIContent _fixedNormalSpaceText = new GUIContent("Fixed Normal Space");
static GUIContent[] _fixedNormalSpaceOptions = { new GUIContent("View-Space"), new GUIContent("Model-Space") };
static GUIContent _rimLightingToggleText = new GUIContent("Rim Lighting", "Enable Rim Lighting.");
static GUIContent _rimColorText = new GUIContent("Rim Color");
static GUIContent _rimPowerText = new GUIContent("Rim Power");
static GUIContent _specularToggleText = new GUIContent("Specular", "Enable Specular.");
static GUIContent _colorAdjustmentToggleText = new GUIContent("Color Adjustment", "Enable material color adjustment.");
static GUIContent _colorAdjustmentColorText = new GUIContent("Overlay Color");
static GUIContent _colorAdjustmentHueText = new GUIContent("Hue");
static GUIContent _colorAdjustmentSaturationText = new GUIContent("Saturation");
static GUIContent _colorAdjustmentBrightnessText = new GUIContent("Brightness");
static GUIContent _fogToggleText = new GUIContent("Fog", "Enable Fog rendering on this renderer.");
static GUIContent _meshRequiresTangentsText = new GUIContent("Note: Material requires a mesh with tangents.");
static GUIContent _meshRequiresNormalsText = new GUIContent("Note: Material requires a mesh with normals.");
static GUIContent _meshRequiresNormalsAndTangentsText = new GUIContent("Note: Material requires a mesh with Normals and Tangents.");
const string _primaryMapsText = "Main Maps";
const string _depthLabelText = "Depth";
const string _shadowsText = "Shadows";
const string _customRenderType = "Use Custom RenderType";
#region ShaderGUI
public override void OnGUI (MaterialEditor materialEditor, MaterialProperty[] properties) {
FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
_materialEditor = materialEditor;
ShaderPropertiesGUI();
}
public override void AssignNewShaderToMaterial (Material material, Shader oldShader, Shader newShader) {
base.AssignNewShaderToMaterial(material, oldShader, newShader);
//If not originally a sprite shader set default keywords
if (oldShader.name != kShaderVertexLit && oldShader.name != kShaderPixelLit && oldShader.name != kShaderUnlit) {
SetDefaultSpriteKeywords(material, newShader);
}
SetMaterialKeywords(material);
}
#endregion
#region Virtual Interface
protected virtual void FindProperties (MaterialProperty[] props) {
_mainTexture = FindProperty("_MainTex", props);
_color = FindProperty("_Color", props);
_pixelSnap = FindProperty("PixelSnap", props);
_writeToDepth = FindProperty("_ZWrite", props);
_depthAlphaCutoff = FindProperty("_Cutoff", props);
_shadowAlphaCutoff = FindProperty("_ShadowAlphaCutoff", props);
_renderQueue = FindProperty("_RenderQueue", props);
_culling = FindProperty("_Cull", props);
_customRenderQueue = FindProperty("_CustomRenderQueue", props);
_bumpMap = FindProperty("_BumpMap", props, false);
_bumpScale = FindProperty("_BumpScale", props, false);
_diffuseRamp = FindProperty("_DiffuseRamp", props, false);
_fixedNormal = FindProperty("_FixedNormal", props, false);
_blendTexture = FindProperty("_BlendTex", props, false);
_blendTextureLerp = FindProperty("_BlendAmount", props, false);
_overlayColor = FindProperty("_OverlayColor", props, false);
_hue = FindProperty("_Hue", props, false);
_saturation = FindProperty("_Saturation", props, false);
_brightness = FindProperty("_Brightness", props, false);
_rimPower = FindProperty("_RimPower", props, false);
_rimColor = FindProperty("_RimColor", props, false);
_emissionMap = FindProperty("_EmissionMap", props, false);
_emissionColor = FindProperty("_EmissionColor", props, false);
_emissionPower = FindProperty("_EmissionPower", props, false);
_metallic = FindProperty("_Metallic", props, false);
_metallicGlossMap = FindProperty("_MetallicGlossMap", props, false);
_smoothness = FindProperty("_Glossiness", props, false);
_smoothnessScale = FindProperty("_GlossMapScale", props, false);
}
static bool BoldToggleField (GUIContent label, bool value) {
FontStyle origFontStyle = EditorStyles.label.fontStyle;
EditorStyles.label.fontStyle = FontStyle.Bold;
value = EditorGUILayout.Toggle(label, value, EditorStyles.toggle);
EditorStyles.label.fontStyle = origFontStyle;
return value;
}
protected virtual void ShaderPropertiesGUI () {
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
RenderMeshInfoBox();
// Detect any changes to the material
bool dataChanged = RenderModes();
GUILayout.Label(_primaryMapsText, EditorStyles.boldLabel);
{
dataChanged |= RenderTextureProperties();
}
GUILayout.Label(_depthLabelText, EditorStyles.boldLabel);
{
dataChanged |= RenderDepthProperties();
}
GUILayout.Label(_shadowsText, EditorStyles.boldLabel);
{
dataChanged |= RenderShadowsProperties();
}
if (_metallic != null) {
dataChanged |= RenderSpecularProperties();
}
if (_emissionMap != null && _emissionColor != null) {
dataChanged |= RenderEmissionProperties();
}
if (_fixedNormal != null) {
dataChanged |= RenderNormalsProperties();
}
if (_fixedNormal != null) {
dataChanged |= RenderSphericalHarmonicsProperties();
}
{
dataChanged |= RenderFogProperties();
}
{
dataChanged |= RenderColorProperties();
}
if (_rimColor != null) {
dataChanged |= RenderRimLightingProperties();
}
if (dataChanged) {
MaterialChanged(_materialEditor);
}
}
protected virtual bool RenderModes () {
bool dataChanged = false;
//Lighting Mode
{
EditorGUI.BeginChangeCheck();
eLightMode lightMode = GetMaterialLightMode((Material)_materialEditor.target);
EditorGUI.showMixedValue = false;
foreach (Material material in _materialEditor.targets) {
if (lightMode != GetMaterialLightMode(material)) {
EditorGUI.showMixedValue = true;
break;
}
}
lightMode = (eLightMode)EditorGUILayout.Popup(_lightingModeText, (int)lightMode, _lightingModeOptions);
if (EditorGUI.EndChangeCheck()) {
foreach (Material material in _materialEditor.targets) {
switch (lightMode) {
case eLightMode.VertexLit:
if (material.shader.name != kShaderVertexLit)
_materialEditor.SetShader(Shader.Find(kShaderVertexLit), false);
break;
case eLightMode.PixelLit:
if (material.shader.name != kShaderPixelLit)
_materialEditor.SetShader(Shader.Find(kShaderPixelLit), false);
break;
case eLightMode.Unlit:
if (material.shader.name != kShaderUnlit)
_materialEditor.SetShader(Shader.Find(kShaderUnlit), false);
break;
}
}
dataChanged = true;
}
}
//Blend Mode
{
eBlendMode blendMode = GetMaterialBlendMode((Material)_materialEditor.target);
EditorGUI.showMixedValue = false;
foreach (Material material in _materialEditor.targets) {
if (blendMode != GetMaterialBlendMode(material)) {
EditorGUI.showMixedValue = true;
break;
}
}
EditorGUI.BeginChangeCheck();
blendMode = (eBlendMode)EditorGUILayout.Popup(_blendModeText, (int)blendMode, _blendModeOptions);
if (EditorGUI.EndChangeCheck()) {
foreach (Material mat in _materialEditor.targets) {
SetBlendMode(mat, blendMode);
}
dataChanged = true;
}
}
// GUILayout.Label(Styles.advancedText, EditorStyles.boldLabel);
// m_MaterialEditor.RenderQueueField();
// m_MaterialEditor.EnableInstancingField();
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = _renderQueue.hasMixedValue;
int renderQueue = EditorGUILayout.IntSlider(_rendererQueueText, (int)_renderQueue.floatValue, 0, 49);
if (EditorGUI.EndChangeCheck()) {
SetInt("_RenderQueue", renderQueue);
dataChanged = true;
}
EditorGUI.BeginChangeCheck();
var culling = (eCulling)Mathf.RoundToInt(_culling.floatValue);
EditorGUI.showMixedValue = _culling.hasMixedValue;
culling = (eCulling)EditorGUILayout.Popup(_cullingModeText, (int)culling, _cullingModeOptions);
if (EditorGUI.EndChangeCheck()) {
SetInt("_Cull", (int)culling);
dataChanged = true;
}
EditorGUI.showMixedValue = false;
EditorGUI.BeginChangeCheck();
_materialEditor.ShaderProperty(_pixelSnap, _pixelSnapText);
dataChanged |= EditorGUI.EndChangeCheck();
return dataChanged;
}
protected virtual bool RenderTextureProperties () {
bool dataChanged = false;
EditorGUI.BeginChangeCheck();
_materialEditor.TexturePropertySingleLine(_albedoText, _mainTexture, _color);
if (_bumpMap != null)
_materialEditor.TexturePropertySingleLine(_normalMapText, _bumpMap, _bumpMap.textureValue != null ? _bumpScale : null);
if (_diffuseRamp != null)
_materialEditor.TexturePropertySingleLine(_diffuseRampText, _diffuseRamp);
dataChanged |= EditorGUI.EndChangeCheck();
if (_blendTexture != null) {
EditorGUI.BeginChangeCheck();
_materialEditor.TexturePropertySingleLine(_altAlbedoText, _blendTexture, _blendTextureLerp);
if (EditorGUI.EndChangeCheck()) {
SetKeyword(_materialEditor, "_TEXTURE_BLEND", _blendTexture != null);
dataChanged = true;
}
}
EditorGUI.BeginChangeCheck();
_materialEditor.TextureScaleOffsetProperty(_mainTexture);
dataChanged |= EditorGUI.EndChangeCheck();
EditorGUI.showMixedValue = false;
return dataChanged;
}
protected virtual bool RenderDepthProperties () {
bool dataChanged = false;
EditorGUI.BeginChangeCheck();
bool mixedValue = _writeToDepth.hasMixedValue;
EditorGUI.showMixedValue = mixedValue;
bool writeTodepth = EditorGUILayout.Toggle(_depthText, _writeToDepth.floatValue != 0.0f);
if (EditorGUI.EndChangeCheck()) {
SetInt("_ZWrite", writeTodepth ? 1 : 0);
_depthAlphaCutoff.floatValue = writeTodepth ? 0.5f : 0.0f;
mixedValue = false;
dataChanged = true;
}
if (writeTodepth && !mixedValue && GetMaterialBlendMode((Material)_materialEditor.target) != eBlendMode.Opaque) {
EditorGUI.BeginChangeCheck();
_materialEditor.RangeProperty(_depthAlphaCutoff, _depthAlphaCutoffText.text);
dataChanged |= EditorGUI.EndChangeCheck();
}
{
bool useCustomRenderType = _customRenderQueue.floatValue > 0.0f;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = _customRenderQueue.hasMixedValue;
useCustomRenderType = EditorGUILayout.Toggle(_customRenderType, useCustomRenderType);
if (EditorGUI.EndChangeCheck()) {
dataChanged = true;
_customRenderQueue.floatValue = useCustomRenderType ? 1.0f : 0.0f;
foreach (Material material in _materialEditor.targets) {
eBlendMode blendMode = GetMaterialBlendMode(material);
switch (blendMode) {
case eBlendMode.Opaque:
{
SetRenderType(material, "Opaque", useCustomRenderType);
}
break;
default:
{
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderType);
}
break;
}
}
}
}
EditorGUI.showMixedValue = false;
return dataChanged;
}
protected virtual bool RenderNormalsProperties () {
bool dataChanged = false;
eNormalsMode normalsMode = GetMaterialNormalsMode((Material)_materialEditor.target);
bool mixedNormalsMode = false;
foreach (Material material in _materialEditor.targets) {
if (normalsMode != GetMaterialNormalsMode(material)) {
mixedNormalsMode = true;
break;
}
}
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = mixedNormalsMode;
bool fixedNormals = BoldToggleField(_fixedNormalText, normalsMode != eNormalsMode.MeshNormals);
if (EditorGUI.EndChangeCheck()) {
normalsMode = fixedNormals ? eNormalsMode.FixedNormalsViewSpace : eNormalsMode.MeshNormals;
SetNormalsMode(_materialEditor, normalsMode, false);
_fixedNormal.vectorValue = new Vector4(0.0f, 0.0f, normalsMode == eNormalsMode.FixedNormalsViewSpace ? 1.0f : -1.0f, 1.0f);
mixedNormalsMode = false;
dataChanged = true;
}
if (fixedNormals) {
//Show drop down for normals space
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = mixedNormalsMode;
normalsMode = (eNormalsMode)EditorGUILayout.Popup(_fixedNormalSpaceText, (int)normalsMode, _fixedNormalSpaceOptions);
if (EditorGUI.EndChangeCheck()) {
SetNormalsMode((Material)_materialEditor.target, normalsMode, GetMaterialFixedNormalsBackfaceRenderingOn((Material)_materialEditor.target));
foreach (Material material in _materialEditor.targets) {
SetNormalsMode(material, normalsMode, GetMaterialFixedNormalsBackfaceRenderingOn(material));
}
//Reset fixed normal to default (Vector3.forward for model-space, -Vector3.forward for view-space).
_fixedNormal.vectorValue = new Vector4(0.0f, 0.0f, normalsMode == eNormalsMode.FixedNormalsViewSpace ? 1.0f : -1.0f, 1.0f);
mixedNormalsMode = false;
dataChanged = true;
}
//Show fixed normal
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = _fixedNormal.hasMixedValue;
Vector3 normal = EditorGUILayout.Vector3Field(_fixedNormalDirectionText, _fixedNormal.vectorValue);
if (EditorGUI.EndChangeCheck()) {
_fixedNormal.vectorValue = new Vector4(normal.x, normal.y, normal.z, 1.0f);
dataChanged = true;
}
//Show adjust for back face rendering
{
bool fixBackFaceRendering = GetMaterialFixedNormalsBackfaceRenderingOn((Material)_materialEditor.target);
bool mixedBackFaceRendering = false;
foreach (Material material in _materialEditor.targets) {
if (fixBackFaceRendering != GetMaterialFixedNormalsBackfaceRenderingOn(material)) {
mixedBackFaceRendering = true;
break;
}
}
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = mixedBackFaceRendering;
bool backRendering = EditorGUILayout.Toggle(_adjustBackfaceTangentText, fixBackFaceRendering);
if (EditorGUI.EndChangeCheck()) {
SetNormalsMode(_materialEditor, normalsMode, backRendering);
dataChanged = true;
}
}
}
EditorGUI.showMixedValue = false;
return dataChanged;
}
protected virtual bool RenderShadowsProperties () {
EditorGUI.BeginChangeCheck();
_materialEditor.RangeProperty(_shadowAlphaCutoff, _shadowAlphaCutoffText.text);
return EditorGUI.EndChangeCheck();
}
protected virtual bool RenderSphericalHarmonicsProperties () {
EditorGUI.BeginChangeCheck();
bool mixedValue;
bool enabled = IsKeywordEnabled(_materialEditor, "_SPHERICAL_HARMONICS", out mixedValue);
EditorGUI.showMixedValue = mixedValue;
enabled = BoldToggleField(_sphericalHarmonicsText, enabled);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck()) {
SetKeyword(_materialEditor, "_SPHERICAL_HARMONICS", enabled);
return true;
}
return false;
}
protected virtual bool RenderFogProperties () {
EditorGUI.BeginChangeCheck();
bool mixedValue;
bool fog = IsKeywordEnabled(_materialEditor, "_FOG", out mixedValue);
EditorGUI.showMixedValue = mixedValue;
fog = BoldToggleField(_fogToggleText, fog);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck()) {
SetKeyword(_materialEditor, "_FOG", fog);
return true;
}
return false;
}
protected virtual bool RenderColorProperties () {
bool dataChanged = false;
EditorGUI.BeginChangeCheck();
bool mixedValue;
bool colorAdjust = IsKeywordEnabled(_materialEditor, "_COLOR_ADJUST", out mixedValue);
EditorGUI.showMixedValue = mixedValue;
colorAdjust = BoldToggleField(_colorAdjustmentToggleText, colorAdjust);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck()) {
SetKeyword(_materialEditor, "_COLOR_ADJUST", colorAdjust);
mixedValue = false;
dataChanged = true;
}
if (colorAdjust && !mixedValue) {
EditorGUI.BeginChangeCheck();
_materialEditor.ColorProperty(_overlayColor, _colorAdjustmentColorText.text);
_materialEditor.RangeProperty(_hue, _colorAdjustmentHueText.text);
_materialEditor.RangeProperty(_saturation, _colorAdjustmentSaturationText.text);
_materialEditor.RangeProperty(_brightness, _colorAdjustmentBrightnessText.text);
dataChanged |= EditorGUI.EndChangeCheck();
}
return dataChanged;
}
protected virtual bool RenderSpecularProperties () {
bool dataChanged = false;
bool mixedSpecularValue;
bool specular = IsKeywordEnabled(_materialEditor, "_SPECULAR", out mixedSpecularValue);
bool mixedSpecularGlossMapValue;
bool specularGlossMap = IsKeywordEnabled(_materialEditor, "_SPECULAR_GLOSSMAP", out mixedSpecularGlossMapValue);
bool mixedValue = mixedSpecularValue || mixedSpecularGlossMapValue;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = mixedValue;
bool specularEnabled = BoldToggleField(_specularToggleText, specular || specularGlossMap);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck()) {
foreach (Material material in _materialEditor.targets) {
bool hasGlossMap = material.GetTexture("_MetallicGlossMap") != null;
SetKeyword(material, "_SPECULAR", specularEnabled && !hasGlossMap);
SetKeyword(material, "_SPECULAR_GLOSSMAP", specularEnabled && hasGlossMap);
}
mixedValue = false;
dataChanged = true;
}
if (specularEnabled && !mixedValue) {
EditorGUI.BeginChangeCheck();
bool hasGlossMap = _metallicGlossMap.textureValue != null;
_materialEditor.TexturePropertySingleLine(_metallicMapText, _metallicGlossMap, hasGlossMap ? null : _metallic);
if (EditorGUI.EndChangeCheck()) {
hasGlossMap = _metallicGlossMap.textureValue != null;
SetKeyword(_materialEditor, "_SPECULAR", !hasGlossMap);
SetKeyword(_materialEditor, "_SPECULAR_GLOSSMAP", hasGlossMap);
dataChanged = true;
}
const int indentation = 2;
_materialEditor.ShaderProperty(hasGlossMap ? _smoothnessScale : _smoothness, hasGlossMap ? _smoothnessScaleText : _smoothnessText, indentation);
}
return dataChanged;
}
protected virtual bool RenderEmissionProperties () {
bool dataChanged = false;
bool mixedValue;
bool emission = IsKeywordEnabled(_materialEditor, "_EMISSION", out mixedValue);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = mixedValue;
emission = BoldToggleField(_emissionToggleText, emission);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck()) {
SetKeyword(_materialEditor, "_EMISSION", emission);
mixedValue = false;
dataChanged = true;
}
if (emission && !mixedValue) {
EditorGUI.BeginChangeCheck();
#if UNITY_2018_1_OR_NEWER
_materialEditor.TexturePropertyWithHDRColor(_emissionText, _emissionMap, _emissionColor, true);
#else
_materialEditor.TexturePropertyWithHDRColor(_emissionText, _emissionMap, _emissionColor, new ColorPickerHDRConfig(0, 1, 0.01010101f, 3), true);
#endif
_materialEditor.FloatProperty(_emissionPower, _emissionPowerText.text);
dataChanged |= EditorGUI.EndChangeCheck();
}
return dataChanged;
}
protected virtual bool RenderRimLightingProperties () {
bool dataChanged = false;
bool mixedValue;
bool rimLighting = IsKeywordEnabled(_materialEditor, "_RIM_LIGHTING", out mixedValue);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = mixedValue;
rimLighting = BoldToggleField(_rimLightingToggleText, rimLighting);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck()) {
SetKeyword(_materialEditor, "_RIM_LIGHTING", rimLighting);
mixedValue = false;
dataChanged = true;
}
if (rimLighting && !mixedValue) {
EditorGUI.BeginChangeCheck();
_materialEditor.ColorProperty(_rimColor, _rimColorText.text);
_materialEditor.FloatProperty(_rimPower, _rimPowerText.text);
dataChanged |= EditorGUI.EndChangeCheck();
}
return dataChanged;
}
#endregion
#region Private Functions
void RenderMeshInfoBox () {
var material = (Material)_materialEditor.target;
bool requiresNormals = _fixedNormal != null && GetMaterialNormalsMode(material) == eNormalsMode.MeshNormals;
bool requiresTangents = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null;
if (requiresNormals || requiresTangents) {
GUILayout.Label(requiresNormals && requiresTangents ? _meshRequiresNormalsAndTangentsText : requiresNormals ? _meshRequiresNormalsText : _meshRequiresTangentsText, GUI.skin.GetStyle("helpBox"));
}
}
void SetInt (string propertyName, int value) {
foreach (Material material in _materialEditor.targets) {
material.SetInt(propertyName, value);
}
}
void SetDefaultSpriteKeywords (Material material, Shader shader) {
//Disable emission by default (is set on by default in standard shader)
SetKeyword(material, "_EMISSION", false);
//Start with preMultiply alpha by default
SetBlendMode(material, eBlendMode.PreMultipliedAlpha);
//Start with mesh normals by default
SetNormalsMode(material, eNormalsMode.MeshNormals, false);
if (_fixedNormal != null)
_fixedNormal.vectorValue = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);
//Start with spherical harmonics disabled?
SetKeyword(material, "_SPHERICAL_HARMONICS", false);
//Start with specular disabled
SetKeyword(material, "_SPECULAR", false);
SetKeyword(material, "_SPECULAR_GLOSSMAP", false);
//Start with Culling disabled
material.SetInt("_Cull", (int)eCulling.Off);
//Start with Z writing disabled
material.SetInt("_ZWrite", 0);
}
//Z write is on then
static void SetRenderType (Material material, string renderType, bool useCustomRenderQueue) {
//Want a check box to say if should use Sprite render queue (for custom writing depth and normals)
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
if (useCustomRenderQueue) {
//If sprite has fixed normals then assign custom render type so we can write its correct normal with soft edges
eNormalsMode normalsMode = GetMaterialNormalsMode(material);
switch (normalsMode) {
case eNormalsMode.FixedNormalsViewSpace:
renderType = "SpriteViewSpaceFixedNormal";
break;
case eNormalsMode.FixedNormalsModelSpace:
renderType = "SpriteModelSpaceFixedNormal";
break;
case eNormalsMode.MeshNormals:
{
//If sprite doesn't write to depth assign custom render type so we can write its depth with soft edges
if (!zWrite) {
renderType = "Sprite";
}
}
break;
}
}
//If we don't write to depth set tag so custom shaders can write to depth themselves
material.SetOverrideTag("AlphaDepth", zWrite ? "False" : "True");
material.SetOverrideTag("RenderType", renderType);
}
static void SetMaterialKeywords (Material material) {
eBlendMode blendMode = GetMaterialBlendMode(material);
SetBlendMode(material, blendMode);
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
bool clipAlpha = zWrite && blendMode != eBlendMode.Opaque && material.GetFloat("_Cutoff") > 0.0f;
SetKeyword(material, "_ALPHA_CLIP", clipAlpha);
bool normalMap = material.HasProperty("_BumpMap") && material.GetTexture("_BumpMap") != null;
SetKeyword(material, "_NORMALMAP", normalMap);
bool diffuseRamp = material.HasProperty("_DiffuseRamp") && material.GetTexture("_DiffuseRamp") != null;
SetKeyword(material, "_DIFFUSE_RAMP", diffuseRamp);
bool blendTexture = material.HasProperty("_BlendTex") && material.GetTexture("_BlendTex") != null;
SetKeyword(material, "_TEXTURE_BLEND", blendTexture);
}
static void MaterialChanged (MaterialEditor materialEditor) {
foreach (Material material in materialEditor.targets)
SetMaterialKeywords(material);
}
static void SetKeyword (MaterialEditor m, string keyword, bool state) {
foreach (Material material in m.targets) {
SetKeyword(material, keyword, state);
}
}
static void SetKeyword (Material m, string keyword, bool state) {
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
static bool IsKeywordEnabled (MaterialEditor editor, string keyword, out bool mixedValue) {
bool keywordEnabled = ((Material)editor.target).IsKeywordEnabled(keyword);
mixedValue = false;
foreach (Material material in editor.targets) {
if (material.IsKeywordEnabled(keyword) != keywordEnabled) {
mixedValue = true;
break;
}
}
return keywordEnabled;
}
static eLightMode GetMaterialLightMode (Material material) {
if (material.shader.name == kShaderPixelLit) {
return eLightMode.PixelLit;
} else if (material.shader.name == kShaderUnlit) {
return eLightMode.Unlit;
} else {
return eLightMode.VertexLit;
}
}
static eBlendMode GetMaterialBlendMode (Material material) {
if (material.IsKeywordEnabled("_ALPHABLEND_ON"))
return eBlendMode.StandardAlpha;
if (material.IsKeywordEnabled("_ALPHAPREMULTIPLY_ON"))
return eBlendMode.PreMultipliedAlpha;
if (material.IsKeywordEnabled("_MULTIPLYBLEND"))
return eBlendMode.Multiply;
if (material.IsKeywordEnabled("_MULTIPLYBLEND_X2"))
return eBlendMode.Multiplyx2;
if (material.IsKeywordEnabled("_ADDITIVEBLEND"))
return eBlendMode.Additive;
if (material.IsKeywordEnabled("_ADDITIVEBLEND_SOFT"))
return eBlendMode.SoftAdditive;
return eBlendMode.Opaque;
}
static void SetBlendMode (Material material, eBlendMode blendMode) {
SetKeyword(material, "_ALPHABLEND_ON", blendMode == eBlendMode.StandardAlpha);
SetKeyword(material, "_ALPHAPREMULTIPLY_ON", blendMode == eBlendMode.PreMultipliedAlpha);
SetKeyword(material, "_MULTIPLYBLEND", blendMode == eBlendMode.Multiply);
SetKeyword(material, "_MULTIPLYBLEND_X2", blendMode == eBlendMode.Multiplyx2);
SetKeyword(material, "_ADDITIVEBLEND", blendMode == eBlendMode.Additive);
SetKeyword(material, "_ADDITIVEBLEND_SOFT", blendMode == eBlendMode.SoftAdditive);
int renderQueue;
bool useCustomRenderQueue = material.GetFloat("_CustomRenderQueue") > 0.0f;
switch (blendMode) {
case eBlendMode.Opaque:
{
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
SetRenderType(material, "Opaque", useCustomRenderQueue);
renderQueue = kSolidQueue;
}
break;
case eBlendMode.Additive:
{
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue);
renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
}
break;
case eBlendMode.SoftAdditive:
{
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcColor);
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue);
renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
}
break;
case eBlendMode.Multiply:
{
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor);
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue);
renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
}
break;
case eBlendMode.Multiplyx2:
{
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.SrcColor);
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue);
renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
}
break;
default:
{
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
bool zWrite = material.GetFloat("_ZWrite") > 0.0f;
SetRenderType(material, zWrite ? "TransparentCutout" : "Transparent", useCustomRenderQueue);
renderQueue = zWrite ? kAlphaTestQueue : kTransparentQueue;
}
break;
}
material.renderQueue = renderQueue + material.GetInt("_RenderQueue");
material.SetOverrideTag("IgnoreProjector", blendMode == eBlendMode.Opaque ? "False" : "True");
}
static eNormalsMode GetMaterialNormalsMode (Material material) {
if (material.IsKeywordEnabled("_FIXED_NORMALS_VIEWSPACE") || material.IsKeywordEnabled("_FIXED_NORMALS_VIEWSPACE_BACKFACE"))
return eNormalsMode.FixedNormalsViewSpace;
if (material.IsKeywordEnabled("_FIXED_NORMALS_MODELSPACE") || material.IsKeywordEnabled("_FIXED_NORMALS_MODELSPACE_BACKFACE"))
return eNormalsMode.FixedNormalsModelSpace;
return eNormalsMode.MeshNormals;
}
static void SetNormalsMode (MaterialEditor materialEditor, eNormalsMode normalsMode, bool allowBackFaceRendering) {
SetNormalsMode((Material)materialEditor.target, normalsMode, allowBackFaceRendering);
foreach (Material material in materialEditor.targets) {
SetNormalsMode(material, normalsMode, allowBackFaceRendering);
}
}
static void SetNormalsMode (Material material, eNormalsMode normalsMode, bool allowBackFaceRendering) {
SetKeyword(material, "_FIXED_NORMALS_VIEWSPACE", normalsMode == eNormalsMode.FixedNormalsViewSpace && !allowBackFaceRendering);
SetKeyword(material, "_FIXED_NORMALS_VIEWSPACE_BACKFACE", normalsMode == eNormalsMode.FixedNormalsViewSpace && allowBackFaceRendering);
SetKeyword(material, "_FIXED_NORMALS_MODELSPACE", normalsMode == eNormalsMode.FixedNormalsModelSpace && !allowBackFaceRendering);
SetKeyword(material, "_FIXED_NORMALS_MODELSPACE_BACKFACE", normalsMode == eNormalsMode.FixedNormalsModelSpace && allowBackFaceRendering);
}
static bool GetMaterialFixedNormalsBackfaceRenderingOn (Material material) {
return material.IsKeywordEnabled("_FIXED_NORMALS_VIEWSPACE_BACKFACE") || material.IsKeywordEnabled("_FIXED_NORMALS_MODELSPACE_BACKFACE");
}
#endregion
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: aef90b4c481362e42891bb46de344c1c
timeCreated: 1479458475
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7a4120eda5e72634b8ea086a00778669
folderAsset: yes
timeCreated: 1527569450
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 78bba472871bc624f8930d51dea6dd3d
folderAsset: yes
timeCreated: 1455570938
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,198 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* 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, followZPosition, followBoneRotation, followLocalScale, followSkeletonFlip;
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 = SpineEditorUtilities.EditorInstantiation.NewGameObject("BoneFollower", 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");
followZPosition = serializedObject.FindProperty("followZPosition");
followLocalScale = serializedObject.FindProperty("followLocalScale");
followSkeletonFlip = serializedObject.FindProperty("followSkeletonFlip");
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(followZPosition);
EditorGUILayout.PropertyField(followLocalScale);
EditorGUILayout.PropertyField(followSkeletonFlip);
//BoneFollowerInspector.RecommendRigidbodyButton(targetBoneFollower);
} else {
var boneFollowerSkeletonGraphic = targetBoneFollower.skeletonGraphic;
if (boneFollowerSkeletonGraphic == null) {
EditorGUILayout.HelpBox("SkeletonGraphic is unassigned. Please assign a SkeletonRenderer (SkeletonAnimation or SkeletonAnimator).", 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();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: da44a8561fd243c43a1f77bda36de0eb
timeCreated: 1499279157
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,229 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using UnityEditor;
using Spine;
namespace Spine.Unity.Editor {
[InitializeOnLoad]
[CustomEditor(typeof(SkeletonGraphic))]
[CanEditMultipleObjects]
public class SkeletonGraphicInspector : UnityEditor.Editor {
SerializedProperty material, color;
SerializedProperty skeletonDataAsset, initialSkinName;
SerializedProperty startingAnimation, startingLoop, timeScale, freeze, unscaledTime, tintBlack;
SerializedProperty initialFlipX, initialFlipY;
SerializedProperty meshGeneratorSettings;
SerializedProperty raycastTarget;
SkeletonGraphic thisSkeletonGraphic;
void OnEnable () {
var so = this.serializedObject;
thisSkeletonGraphic = target as SkeletonGraphic;
// MaskableGraphic
material = so.FindProperty("m_Material");
color = so.FindProperty("m_Color");
raycastTarget = so.FindProperty("m_RaycastTarget");
// SkeletonRenderer
skeletonDataAsset = so.FindProperty("skeletonDataAsset");
initialSkinName = so.FindProperty("initialSkinName");
initialFlipX = so.FindProperty("initialFlipX");
initialFlipY = so.FindProperty("initialFlipY");
// SkeletonAnimation
startingAnimation = so.FindProperty("startingAnimation");
startingLoop = so.FindProperty("startingLoop");
timeScale = so.FindProperty("timeScale");
unscaledTime = so.FindProperty("unscaledTime");
freeze = so.FindProperty("freeze");
meshGeneratorSettings = so.FindProperty("meshGenerator").FindPropertyRelative("settings");
meshGeneratorSettings.isExpanded = SkeletonRendererInspector.advancedFoldout;
}
public override void OnInspectorGUI () {
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(skeletonDataAsset);
EditorGUILayout.PropertyField(material);
EditorGUILayout.PropertyField(color);
if (thisSkeletonGraphic.skeletonDataAsset == null) {
EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info);
serializedObject.ApplyModifiedProperties();
serializedObject.Update();
return;
}
using (new SpineInspectorUtility.BoxScope()) {
EditorGUILayout.PropertyField(meshGeneratorSettings, SpineInspectorUtility.TempContent("Advanced..."), includeChildren: true);
SkeletonRendererInspector.advancedFoldout = meshGeneratorSettings.isExpanded;
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(initialSkinName);
{
var rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight);
EditorGUI.PrefixLabel(rect, SpineInspectorUtility.TempContent("Initial Flip"));
rect.x += EditorGUIUtility.labelWidth;
rect.width = 30f;
SpineInspectorUtility.ToggleLeft(rect, initialFlipX, SpineInspectorUtility.TempContent("X", tooltip: "initialFlipX"));
rect.x += 35f;
SpineInspectorUtility.ToggleLeft(rect, initialFlipY, SpineInspectorUtility.TempContent("Y", tooltip: "initialFlipY"));
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Animation", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(startingAnimation);
EditorGUILayout.PropertyField(startingLoop);
EditorGUILayout.PropertyField(timeScale);
EditorGUILayout.PropertyField(unscaledTime, SpineInspectorUtility.TempContent(unscaledTime.displayName, tooltip: "If checked, this will use Time.unscaledDeltaTime to make this update independent of game Time.timeScale. Instance SkeletonGraphic.timeScale will still be applied."));
EditorGUILayout.Space();
EditorGUILayout.PropertyField(freeze);
EditorGUILayout.Space();
EditorGUILayout.LabelField("UI", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(raycastTarget);
bool wasChanged = EditorGUI.EndChangeCheck();
if (wasChanged)
serializedObject.ApplyModifiedProperties();
}
#region Menus
[MenuItem("CONTEXT/SkeletonGraphic/Match RectTransform with Mesh Bounds")]
static void MatchRectTransformWithBounds (MenuCommand command) {
var skeletonGraphic = (SkeletonGraphic)command.context;
Mesh mesh = skeletonGraphic.GetLastMesh();
if (mesh == null) {
Debug.Log("Mesh was not previously generated.");
return;
}
if (mesh.vertexCount == 0) {
skeletonGraphic.rectTransform.sizeDelta = new Vector2(50f, 50f);
skeletonGraphic.rectTransform.pivot = new Vector2(0.5f, 0.5f);
return;
}
mesh.RecalculateBounds();
var bounds = mesh.bounds;
var size = bounds.size;
var center = bounds.center;
var p = new Vector2(
0.5f - (center.x / size.x),
0.5f - (center.y / size.y)
);
skeletonGraphic.rectTransform.sizeDelta = size;
skeletonGraphic.rectTransform.pivot = p;
}
[MenuItem("GameObject/Spine/SkeletonGraphic (UnityUI)", false, 15)]
static public void SkeletonGraphicCreateMenuItem () {
var parentGameObject = Selection.activeObject as GameObject;
var parentTransform = parentGameObject == null ? null : parentGameObject.GetComponent<RectTransform>();
if (parentTransform == null)
Debug.LogWarning("Your new SkeletonGraphic will not be visible until it is placed under a Canvas");
var gameObject = NewSkeletonGraphicGameObject("New SkeletonGraphic");
gameObject.transform.SetParent(parentTransform, false);
EditorUtility.FocusProjectWindow();
Selection.activeObject = gameObject;
EditorGUIUtility.PingObject(Selection.activeObject);
}
// SpineEditorUtilities.InstantiateDelegate. Used by drag and drop.
public static Component SpawnSkeletonGraphicFromDrop (SkeletonDataAsset data) {
return InstantiateSkeletonGraphic(data);
}
public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, string skinName) {
return InstantiateSkeletonGraphic(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
}
public static SkeletonGraphic InstantiateSkeletonGraphic (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
string spineGameObjectName = string.Format("SkeletonGraphic ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
var go = NewSkeletonGraphicGameObject(spineGameObjectName);
var graphic = go.GetComponent<SkeletonGraphic>();
graphic.skeletonDataAsset = skeletonDataAsset;
SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
if (data == null) {
for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
skeletonDataAsset.atlasAssets[i] = (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAssetBase));
}
data = skeletonDataAsset.GetSkeletonData(true);
}
skin = skin ?? data.DefaultSkin ?? data.Skins.Items[0];
graphic.MeshGenerator.settings.zSpacing = SpineEditorUtilities.Preferences.defaultZSpacing;
graphic.startingLoop = SpineEditorUtilities.Preferences.defaultInstantiateLoop;
graphic.Initialize(false);
if (skin != null) graphic.Skeleton.SetSkin(skin);
graphic.initialSkinName = skin.Name;
graphic.Skeleton.UpdateWorldTransform();
graphic.UpdateMesh();
return graphic;
}
static GameObject NewSkeletonGraphicGameObject (string gameObjectName) {
var go = SpineEditorUtilities.EditorInstantiation.NewGameObject(gameObjectName, typeof(RectTransform), typeof(CanvasRenderer), typeof(SkeletonGraphic));
var graphic = go.GetComponent<SkeletonGraphic>();
graphic.material = SkeletonGraphicInspector.DefaultSkeletonGraphicMaterial;
return go;
}
public static Material DefaultSkeletonGraphicMaterial {
get {
var guids = AssetDatabase.FindAssets("SkeletonGraphicDefault t:material");
if (guids.Length <= 0) return null;
var firstAssetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
if (string.IsNullOrEmpty(firstAssetPath)) return null;
var firstMaterial = AssetDatabase.LoadAssetAtPath<Material>(firstAssetPath);
return firstMaterial;
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0d81cc76b52fcdf499b2db252a317726
timeCreated: 1455570945
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1bf8fd476d074f449bbae932a1c8a360
folderAsset: yes
timeCreated: 1527569465
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 211465c9f045fd142abe552a6ffdc799
folderAsset: yes
timeCreated: 1457405813
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using UnityEditor;
using Spine.Unity.Editor;
namespace Spine.Unity.Modules {
[CustomEditor(typeof(SkeletonPartsRenderer))]
public class SkeletonRenderPartInspector : UnityEditor.Editor {
SpineInspectorUtility.SerializedSortingProperties sortingProperties;
void OnEnable () {
sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(SpineInspectorUtility.GetRenderersSerializedObject(serializedObject));
}
public override void OnInspectorGUI () {
SpineInspectorUtility.SortingPropertyFields(sortingProperties, true);
if (!serializedObject.isEditingMultipleObjects) {
EditorGUILayout.Space();
if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Select SkeletonRenderer", SpineEditorUtilities.Icons.spine))) {
var thisSkeletonPartsRenderer = target as SkeletonPartsRenderer;
var srs = thisSkeletonPartsRenderer.GetComponentInParent<SkeletonRenderSeparator>();
if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null)
Selection.activeGameObject = srs.SkeletonRenderer.gameObject;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 30e43037bf4433645ad70266f34c1c8b
timeCreated: 1458051036
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,308 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using Spine.Unity;
using Spine.Unity.Editor;
namespace Spine.Unity.Modules {
[CustomEditor(typeof(SkeletonRenderSeparator))]
public class SkeletonRenderSeparatorInspector : UnityEditor.Editor {
SkeletonRenderSeparator component;
// Properties
SerializedProperty skeletonRenderer_, copyPropertyBlock_, copyMeshRendererFlags_, partsRenderers_;
static bool partsRenderersExpanded = false;
// For separator field.
SerializedObject skeletonRendererSerializedObject;
SerializedProperty separatorNamesProp;
static bool skeletonRendererExpanded = true;
bool slotsReapplyRequired = false;
bool partsRendererInitRequired = false;
void OnEnable () {
if (component == null)
component = target as SkeletonRenderSeparator;
skeletonRenderer_ = serializedObject.FindProperty("skeletonRenderer");
copyPropertyBlock_ = serializedObject.FindProperty("copyPropertyBlock");
copyMeshRendererFlags_ = serializedObject.FindProperty("copyMeshRendererFlags");
var partsRenderers = component.partsRenderers;
partsRenderers_ = serializedObject.FindProperty("partsRenderers");
partsRenderers_.isExpanded = partsRenderersExpanded || // last state
partsRenderers.Contains(null) || // null items found
partsRenderers.Count < 1 || // no parts renderers
(skeletonRenderer_.objectReferenceValue != null && SkeletonRendererSeparatorCount + 1 > partsRenderers.Count); // not enough parts renderers
}
int SkeletonRendererSeparatorCount {
get {
if (Application.isPlaying)
return component.SkeletonRenderer.separatorSlots.Count;
else
return separatorNamesProp == null ? 0 : separatorNamesProp.arraySize;
}
}
public override void OnInspectorGUI () {
// Restore mesh part for undo logic after undo of "Add Parts Renderer".
// Triggers regeneration and assignment of the mesh filter's mesh.
if (component.GetComponent<MeshFilter>() && component.GetComponent<MeshFilter>().sharedMesh == null) {
component.OnDisable();
component.OnEnable();
}
var componentRenderers = component.partsRenderers;
int totalParts;
using (new SpineInspectorUtility.LabelWidthScope()) {
bool componentEnabled = component.enabled;
bool checkBox = EditorGUILayout.Toggle("Enable Separator", componentEnabled);
if (checkBox != componentEnabled)
component.enabled = checkBox;
if (component.SkeletonRenderer.disableRenderingOnOverride && !component.enabled)
EditorGUILayout.HelpBox("By default, SkeletonRenderer's MeshRenderer is disabled while the SkeletonRenderSeparator takes over rendering. It is re-enabled when SkeletonRenderSeparator is disabled.", MessageType.Info);
EditorGUILayout.PropertyField(copyPropertyBlock_);
EditorGUILayout.PropertyField(copyMeshRendererFlags_);
}
// SkeletonRenderer Box
using (new SpineInspectorUtility.BoxScope(false)) {
// Fancy SkeletonRenderer foldout reference field
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
var foldoutSkeletonRendererRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(foldoutSkeletonRendererRect, skeletonRenderer_);
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
if (component.SkeletonRenderer != null) {
skeletonRendererExpanded = EditorGUI.Foldout(foldoutSkeletonRendererRect, skeletonRendererExpanded, "");
}
EditorGUI.indentLevel--;
}
int separatorCount = 0;
EditorGUI.BeginChangeCheck();
if (component.SkeletonRenderer != null) {
// Separators from SkeletonRenderer
{
bool skeletonRendererMismatch = skeletonRendererSerializedObject != null && skeletonRendererSerializedObject.targetObject != component.SkeletonRenderer;
if (separatorNamesProp == null || skeletonRendererMismatch) {
if (component.SkeletonRenderer != null) {
skeletonRendererSerializedObject = new SerializedObject(component.SkeletonRenderer);
separatorNamesProp = skeletonRendererSerializedObject.FindProperty("separatorSlotNames");
separatorNamesProp.isExpanded = true;
}
}
if (separatorNamesProp != null) {
if (skeletonRendererExpanded) {
EditorGUI.indentLevel++;
SkeletonRendererInspector.SeparatorsField(separatorNamesProp);
EditorGUI.indentLevel--;
}
separatorCount = this.SkeletonRendererSeparatorCount;
}
}
if (SkeletonRendererSeparatorCount == 0) {
EditorGUILayout.HelpBox("Separators are empty. Change the size to 1 and choose a slot if you want the render to be separated.", MessageType.Info);
}
}
if (EditorGUI.EndChangeCheck()) {
skeletonRendererSerializedObject.ApplyModifiedProperties();
if (!Application.isPlaying)
slotsReapplyRequired = true;
}
totalParts = separatorCount + 1;
var counterStyle = skeletonRendererExpanded ? EditorStyles.label : EditorStyles.miniLabel;
EditorGUILayout.LabelField(string.Format("{0}: separates into {1}.", SpineInspectorUtility.Pluralize(separatorCount, "separator", "separators"), SpineInspectorUtility.Pluralize(totalParts, "part", "parts") ), counterStyle);
}
// Parts renderers
using (new SpineInspectorUtility.BoxScope(false)) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(this.partsRenderers_, true);
EditorGUI.indentLevel--;
// Null items warning
bool nullItemsFound = componentRenderers.Contains(null);
if (nullItemsFound)
EditorGUILayout.HelpBox("Some items in the parts renderers list are null and may cause problems.\n\nYou can right-click on that element and choose 'Delete Array Element' to remove it.", MessageType.Warning);
// (Button) Match Separators count
if (separatorNamesProp != null) {
int currentRenderers = 0;
foreach (var r in componentRenderers) {
if (r != null)
currentRenderers++;
}
int extraRenderersNeeded = totalParts - currentRenderers;
if (component.enabled && component.SkeletonRenderer != null && extraRenderersNeeded > 0) {
EditorGUILayout.HelpBox(string.Format("Insufficient parts renderers. Some parts will not be rendered."), MessageType.Warning);
string addMissingLabel = string.Format("Add the missing renderer{1} ({0}) ", extraRenderersNeeded, SpineInspectorUtility.PluralThenS(extraRenderersNeeded));
if (GUILayout.Button(addMissingLabel, GUILayout.Height(40f))) {
AddPartsRenderer(extraRenderersNeeded);
DetectOrphanedPartsRenderers(component);
partsRendererInitRequired = true;
}
}
}
if (partsRenderers_.isExpanded != partsRenderersExpanded) partsRenderersExpanded = partsRenderers_.isExpanded;
if (partsRenderers_.isExpanded) {
using (new EditorGUILayout.HorizontalScope()) {
// (Button) Destroy Renderers button
if (componentRenderers.Count > 0) {
if (GUILayout.Button("Clear Parts Renderers")) {
// Do you really want to destroy all?
Undo.RegisterCompleteObjectUndo(component, "Clear Parts Renderers");
if (EditorUtility.DisplayDialog("Destroy Renderers", "Do you really want to destroy all the Parts Renderer GameObjects in the list?", "Destroy", "Cancel")) {
foreach (var r in componentRenderers) {
if (r != null)
Undo.DestroyObjectImmediate(r.gameObject);
}
componentRenderers.Clear();
// Do you also want to destroy orphans? (You monster.)
DetectOrphanedPartsRenderers(component);
}
}
}
// (Button) Add Part Renderer button
if (GUILayout.Button("Add Parts Renderer")) {
AddPartsRenderer(1);
partsRendererInitRequired = true;
}
}
}
}
serializedObject.ApplyModifiedProperties();
if (partsRendererInitRequired) {
Undo.RegisterCompleteObjectUndo(component.GetComponent<MeshRenderer>(), "Add Parts Renderers");
component.OnEnable();
partsRendererInitRequired = false;
}
if (slotsReapplyRequired && UnityEngine.Event.current.type == EventType.Repaint) {
component.SkeletonRenderer.ReapplySeparatorSlotNames();
component.SkeletonRenderer.LateUpdate();
SceneView.RepaintAll();
slotsReapplyRequired = false;
}
}
public void AddPartsRenderer (int count) {
var componentRenderers = component.partsRenderers;
bool emptyFound = componentRenderers.Contains(null);
if (emptyFound) {
bool userClearEntries = EditorUtility.DisplayDialog("Empty entries found", "Null entries found. Do you want to remove null entries before adding the new renderer? ", "Clear Empty Entries", "Don't Clear");
if (userClearEntries) componentRenderers.RemoveAll(x => x == null);
}
Undo.RegisterCompleteObjectUndo(component, "Add Parts Renderers");
for (int i = 0; i < count; i++) {
int index = componentRenderers.Count;
var smr = SkeletonPartsRenderer.NewPartsRendererGameObject(component.transform, index.ToString());
Undo.RegisterCreatedObjectUndo(smr.gameObject, "New Parts Renderer GameObject.");
componentRenderers.Add(smr);
// increment renderer sorting order.
if (index == 0) continue;
var prev = componentRenderers[index - 1]; if (prev == null) continue;
var prevMeshRenderer = prev.GetComponent<MeshRenderer>();
var currentMeshRenderer = smr.GetComponent<MeshRenderer>();
if (prevMeshRenderer == null || currentMeshRenderer == null) continue;
int prevSortingLayer = prevMeshRenderer.sortingLayerID;
int prevSortingOrder = prevMeshRenderer.sortingOrder;
currentMeshRenderer.sortingLayerID = prevSortingLayer;
currentMeshRenderer.sortingOrder = prevSortingOrder + SkeletonRenderSeparator.DefaultSortingOrderIncrement;
}
}
/// <summary>Detects orphaned parts renderers and offers to delete them.</summary>
public void DetectOrphanedPartsRenderers (SkeletonRenderSeparator component) {
var children = component.GetComponentsInChildren<SkeletonPartsRenderer>();
var orphans = new System.Collections.Generic.List<SkeletonPartsRenderer>();
foreach (var r in children) {
if (!component.partsRenderers.Contains(r))
orphans.Add(r);
}
if (orphans.Count > 0) {
if (EditorUtility.DisplayDialog("Destroy Submesh Renderers", "Unassigned renderers were found. Do you want to delete them? (These may belong to another Render Separator in the same hierarchy. If you don't have another Render Separator component in the children of this GameObject, it's likely safe to delete. Warning: This operation cannot be undone.)", "Delete", "Cancel")) {
foreach (var o in orphans) {
Undo.DestroyObjectImmediate(o.gameObject);
}
}
}
}
#region SkeletonRenderer Context Menu Item
[MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator")]
static void AddRenderSeparatorComponent (MenuCommand cmd) {
var skeletonRenderer = cmd.context as SkeletonRenderer;
var newComponent = skeletonRenderer.gameObject.AddComponent<SkeletonRenderSeparator>();
Undo.RegisterCreatedObjectUndo(newComponent, "Add SkeletonRenderSeparator");
}
// Validate
[MenuItem ("CONTEXT/SkeletonRenderer/Add Skeleton Render Separator", true)]
static bool ValidateAddRenderSeparatorComponent (MenuCommand cmd) {
var skeletonRenderer = cmd.context as SkeletonRenderer;
var separator = skeletonRenderer.GetComponent<SkeletonRenderSeparator>();
bool separatorNotOnObject = separator == null;
return separatorNotOnObject;
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d2a5062cfe5dd4344831cda4723128af
timeCreated: 1458067064
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 18ee2876d53412642bbfa1070a1b947f
folderAsset: yes
timeCreated: 1527569487
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1ad4318c20ec5674a9f4d7f786afd681
folderAsset: yes
timeCreated: 1496449217
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEngine;
using UnityEditor;
using Spine.Unity.Modules;
namespace Spine.Unity.Editor {
using Editor = UnityEditor.Editor;
public class SlotBlendModesEditor : Editor {
[MenuItem("CONTEXT/SkeletonRenderer/Add Slot Blend Modes Component")]
static void AddSlotBlendModesComponent (MenuCommand command) {
var skeletonRenderer = (SkeletonRenderer)command.context;
skeletonRenderer.gameObject.AddComponent<SlotBlendModes>();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cbec7dc66dca80a419477536c23b7a0d
timeCreated: 1496449255
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b7ef9595ebe8c204a8a4f251a55d4d22
folderAsset: yes
timeCreated: 1527569508
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 3cdbaf8cb2e511f4fa3b631af94fa18e
folderAsset: yes
timeCreated: 1527569538
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using UnityEditor;
using UnityEngine;
using Spine;
using Spine.Unity;
using Spine.Unity.Playables;
//[CustomPropertyDrawer(typeof(SpineAnimationStateBehaviour))]
public class SpineAnimationStateDrawer : PropertyDrawer {
/*
public override float GetPropertyHeight (SerializedProperty property, GUIContent label) {
const int fieldCount = 8;
return fieldCount * EditorGUIUtility.singleLineHeight;
}
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
SerializedProperty skeletonDataAssetProp = property.FindPropertyRelative("skeletonDataAsset");
SerializedProperty animationNameProp = property.FindPropertyRelative("animationName");
SerializedProperty loopProp = property.FindPropertyRelative("loop");
SerializedProperty eventProp = property.FindPropertyRelative("eventThreshold");
SerializedProperty attachmentProp = property.FindPropertyRelative("attachmentThreshold");
SerializedProperty drawOrderProp = property.FindPropertyRelative("drawOrderThreshold");
Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(singleFieldRect, skeletonDataAssetProp);
float lineHeightWithSpacing = EditorGUIUtility.singleLineHeight + 2f;
singleFieldRect.y += lineHeightWithSpacing;
EditorGUI.PropertyField(singleFieldRect, animationNameProp);
singleFieldRect.y += lineHeightWithSpacing;
EditorGUI.PropertyField(singleFieldRect, loopProp);
singleFieldRect.y += lineHeightWithSpacing * 0.5f;
singleFieldRect.y += lineHeightWithSpacing;
EditorGUI.LabelField(singleFieldRect, "Mixing Settings", EditorStyles.boldLabel);
singleFieldRect.y += lineHeightWithSpacing;
EditorGUI.PropertyField(singleFieldRect, eventProp);
singleFieldRect.y += lineHeightWithSpacing;
EditorGUI.PropertyField(singleFieldRect, attachmentProp);
singleFieldRect.y += lineHeightWithSpacing;
EditorGUI.PropertyField(singleFieldRect, drawOrderProp);
}
*/
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: cba97e3d11d6d4d428fcfe1a7be16db0
timeCreated: 1510816616
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, 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.
*
* THIS SOFTWARE IS 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 THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#if UNITY_2017 || UNITY_2018 || (UNITY_2019_1_OR_NEWER && SPINE_TIMELINE_PACKAGE_DOWNLOADED)
using UnityEditor;
using UnityEngine;
using UnityEngine.Playables;
[CustomPropertyDrawer(typeof(SpineSkeletonFlipBehaviour))]
public class SpineSkeletonFlipDrawer : PropertyDrawer
{
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
int fieldCount = 1;
return fieldCount * EditorGUIUtility.singleLineHeight;
}
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty flipXProp = property.FindPropertyRelative("flipX");
SerializedProperty flipYProp = property.FindPropertyRelative("flipY");
Rect singleFieldRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(singleFieldRect, flipXProp);
singleFieldRect.y += EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(singleFieldRect, flipYProp);
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b8a0a5d3de45a5e48ae96aa414860d3c
timeCreated: 1500876411
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: