提交Spine插件
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6351693f94cbf774182d4b3f2a756a43
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569401
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7f013ad20f0af34e913e21b44466777
|
||||
folderAsset: yes
|
||||
timeCreated: 1455492480
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 670a3cefa3853bd48b5da53a424fd542
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffde24e0e567a61418f76218f8cffb4c
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569418
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99abd7478ddde384cbf86f2ecd396900
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e70f7f2a241d6d34aafd6a4a52a368d0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Spine/Editor/spine-unity/Modules/Ragdoll.meta
Normal file
9
Assets/Spine/Editor/spine-unity/Modules/Ragdoll.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5ca7a6f2b7e25646ad2f5776178bf78
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569438
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7220dc1e8d545e849a2eb63e8633349b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -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 {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6dd0b99faf3aeb4d803eb9989cb369c
|
||||
timeCreated: 1431741936
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c95a670c56447c644a0f062e4cdd448e
|
||||
timeCreated: 1431740230
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Spine/Editor/spine-unity/Modules/Shaders.meta
Normal file
9
Assets/Spine/Editor/spine-unity/Modules/Shaders.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10e0b626d7ae7394a934ee9f2fb81b5a
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569604
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9ef69c370f1b0f4db091a85df7f2c96
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569612
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bebbafa671002646b3a7267b32a0d60
|
||||
folderAsset: yes
|
||||
timeCreated: 1479419399
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aef90b4c481362e42891bb46de344c1c
|
||||
timeCreated: 1479458475
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a4120eda5e72634b8ea086a00778669
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569450
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78bba472871bc624f8930d51dea6dd3d
|
||||
folderAsset: yes
|
||||
timeCreated: 1455570938
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da44a8561fd243c43a1f77bda36de0eb
|
||||
timeCreated: 1499279157
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d81cc76b52fcdf499b2db252a317726
|
||||
timeCreated: 1455570945
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1bf8fd476d074f449bbae932a1c8a360
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569465
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 211465c9f045fd142abe552a6ffdc799
|
||||
folderAsset: yes
|
||||
timeCreated: 1457405813
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30e43037bf4433645ad70266f34c1c8b
|
||||
timeCreated: 1458051036
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2a5062cfe5dd4344831cda4723128af
|
||||
timeCreated: 1458067064
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18ee2876d53412642bbfa1070a1b947f
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569487
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ad4318c20ec5674a9f4d7f786afd681
|
||||
folderAsset: yes
|
||||
timeCreated: 1496449217
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbec7dc66dca80a419477536c23b7a0d
|
||||
timeCreated: 1496449255
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Spine/Editor/spine-unity/Modules/Timeline.meta
Normal file
9
Assets/Spine/Editor/spine-unity/Modules/Timeline.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7ef9595ebe8c204a8a4f251a55d4d22
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569508
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cdbaf8cb2e511f4fa3b631af94fa18e
|
||||
folderAsset: yes
|
||||
timeCreated: 1527569538
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8a0a5d3de45a5e48ae96aa414860d3c
|
||||
timeCreated: 1500876411
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user