mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 23:34:53 +08:00
Spine.Unity namespace and some editor tweaks.
This commit is contained in:
parent
50a0960a7d
commit
9e8fdeef6c
@ -28,126 +28,124 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
//#define BAKE_ALL_BUTTON
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
namespace Spine.Unity {
|
||||
|
||||
[CustomEditor(typeof(AtlasAsset))]
|
||||
public class AtlasAssetInspector : Editor {
|
||||
private SerializedProperty atlasFile, materials;
|
||||
private AtlasAsset atlasAsset;
|
||||
private List<bool> baked;
|
||||
private List<GameObject> bakedObjects;
|
||||
|
||||
[CustomEditor(typeof(AtlasAsset))]
|
||||
public class AtlasAssetInspector : Editor {
|
||||
private SerializedProperty atlasFile, materials;
|
||||
private AtlasAsset atlasAsset;
|
||||
private List<bool> baked;
|
||||
private List<GameObject> bakedObjects;
|
||||
void OnEnable () {
|
||||
SpineEditorUtilities.ConfirmInitialization();
|
||||
atlasFile = serializedObject.FindProperty("atlasFile");
|
||||
materials = serializedObject.FindProperty("materials");
|
||||
atlasAsset = (AtlasAsset)target;
|
||||
UpdateBakedList();
|
||||
}
|
||||
|
||||
void OnEnable () {
|
||||
SpineEditorUtilities.ConfirmInitialization();
|
||||
atlasFile = serializedObject.FindProperty("atlasFile");
|
||||
materials = serializedObject.FindProperty("materials");
|
||||
atlasAsset = (AtlasAsset)target;
|
||||
UpdateBakedList();
|
||||
}
|
||||
|
||||
void UpdateBakedList () {
|
||||
AtlasAsset asset = (AtlasAsset)target;
|
||||
baked = new List<bool>();
|
||||
bakedObjects = new List<GameObject>();
|
||||
if (atlasFile.objectReferenceValue != null) {
|
||||
Atlas atlas = asset.GetAtlas();
|
||||
FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
|
||||
List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
|
||||
string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
||||
string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
||||
string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
||||
void UpdateBakedList () {
|
||||
AtlasAsset asset = (AtlasAsset)target;
|
||||
baked = new List<bool>();
|
||||
bakedObjects = new List<GameObject>();
|
||||
if (atlasFile.objectReferenceValue != null) {
|
||||
Atlas atlas = asset.GetAtlas();
|
||||
FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
|
||||
List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
|
||||
string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
||||
string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
||||
string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
||||
|
||||
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
AtlasRegion region = regions[i];
|
||||
string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
|
||||
GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
|
||||
baked.Add(prefab != null);
|
||||
bakedObjects.Add(prefab);
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
AtlasRegion region = regions[i];
|
||||
string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
|
||||
GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
|
||||
baked.Add(prefab != null);
|
||||
bakedObjects.Add(prefab);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
AtlasAsset asset = (AtlasAsset)target;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(atlasFile);
|
||||
EditorGUILayout.PropertyField(materials, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
AtlasAsset asset = (AtlasAsset)target;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(atlasFile);
|
||||
EditorGUILayout.PropertyField(materials, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (materials.arraySize == 0) {
|
||||
EditorGUILayout.LabelField(new GUIContent("Error: Missing materials", SpineEditorUtilities.Icons.warning));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < materials.arraySize; i++) {
|
||||
SerializedProperty prop = materials.GetArrayElementAtIndex(i);
|
||||
Material mat = (Material)prop.objectReferenceValue;
|
||||
if (mat == null) {
|
||||
EditorGUILayout.LabelField(new GUIContent("Error: Materials cannot be null", SpineEditorUtilities.Icons.warning));
|
||||
if (materials.arraySize == 0) {
|
||||
EditorGUILayout.LabelField(new GUIContent("Error: Missing materials", SpineEditorUtilities.Icons.warning));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (atlasFile.objectReferenceValue != null) {
|
||||
Atlas atlas = asset.GetAtlas();
|
||||
FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
|
||||
List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
|
||||
EditorGUILayout.LabelField(new GUIContent("Region Baking", SpineEditorUtilities.Icons.unityIcon));
|
||||
EditorGUI.indentLevel++;
|
||||
AtlasPage lastPage = null;
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
if (lastPage != regions[i].page) {
|
||||
if (lastPage != null) {
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
lastPage = regions[i].page;
|
||||
Material mat = ((Material)lastPage.rendererObject);
|
||||
if (mat != null) {
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250));
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
} else {
|
||||
EditorGUILayout.LabelField(new GUIContent("Page missing material!", SpineEditorUtilities.Icons.warning));
|
||||
}
|
||||
for (int i = 0; i < materials.arraySize; i++) {
|
||||
SerializedProperty prop = materials.GetArrayElementAtIndex(i);
|
||||
Material mat = (Material)prop.objectReferenceValue;
|
||||
if (mat == null) {
|
||||
EditorGUILayout.LabelField(new GUIContent("Error: Materials cannot be null", SpineEditorUtilities.Icons.warning));
|
||||
return;
|
||||
}
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
//EditorGUILayout.ToggleLeft(baked[i] ? "" : regions[i].name, baked[i]);
|
||||
bool result = baked[i] ? EditorGUILayout.ToggleLeft("", baked[i], GUILayout.Width(24)) : EditorGUILayout.ToggleLeft(" " + regions[i].name, baked[i]);
|
||||
if(baked[i]){
|
||||
EditorGUILayout.ObjectField(bakedObjects[i], typeof(GameObject), false, GUILayout.Width(250));
|
||||
}
|
||||
|
||||
if (atlasFile.objectReferenceValue != null) {
|
||||
Atlas atlas = asset.GetAtlas();
|
||||
FieldInfo field = typeof(Atlas).GetField("regions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic);
|
||||
List<AtlasRegion> regions = (List<AtlasRegion>)field.GetValue(atlas);
|
||||
EditorGUILayout.LabelField(new GUIContent("Region Baking", SpineEditorUtilities.Icons.unityIcon));
|
||||
EditorGUI.indentLevel++;
|
||||
AtlasPage lastPage = null;
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
if (lastPage != regions[i].page) {
|
||||
if (lastPage != null) {
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
lastPage = regions[i].page;
|
||||
Material mat = ((Material)lastPage.rendererObject);
|
||||
if (mat != null) {
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(250));
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
} else {
|
||||
EditorGUILayout.LabelField(new GUIContent("Page missing material!", SpineEditorUtilities.Icons.warning));
|
||||
}
|
||||
}
|
||||
if (result && !baked[i]) {
|
||||
//bake
|
||||
baked[i] = true;
|
||||
bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
|
||||
EditorGUIUtility.PingObject(bakedObjects[i]);
|
||||
} else if (!result && baked[i]) {
|
||||
//unbake
|
||||
bool unbakeResult = EditorUtility.DisplayDialog("Delete Baked Region", "Do you want to delete the prefab for " + regions[i].name, "Yes", "Cancel");
|
||||
switch (unbakeResult) {
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
//EditorGUILayout.ToggleLeft(baked[i] ? "" : regions[i].name, baked[i]);
|
||||
bool result = baked[i] ? EditorGUILayout.ToggleLeft("", baked[i], GUILayout.Width(24)) : EditorGUILayout.ToggleLeft(" " + regions[i].name, baked[i]);
|
||||
if(baked[i]){
|
||||
EditorGUILayout.ObjectField(bakedObjects[i], typeof(GameObject), false, GUILayout.Width(250));
|
||||
}
|
||||
if (result && !baked[i]) {
|
||||
//bake
|
||||
baked[i] = true;
|
||||
bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
|
||||
EditorGUIUtility.PingObject(bakedObjects[i]);
|
||||
} else if (!result && baked[i]) {
|
||||
//unbake
|
||||
bool unbakeResult = EditorUtility.DisplayDialog("Delete Baked Region", "Do you want to delete the prefab for " + regions[i].name, "Yes", "Cancel");
|
||||
switch (unbakeResult) {
|
||||
case true:
|
||||
//delete
|
||||
string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
||||
@ -160,18 +158,62 @@ public class AtlasAssetInspector : Editor {
|
||||
case false:
|
||||
//do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
asset.Reset();
|
||||
#if BAKE_ALL_BUTTON
|
||||
// Check state
|
||||
bool allBaked = true;
|
||||
bool allUnbaked = true;
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
allBaked &= baked[i];
|
||||
allUnbaked &= !baked[i];
|
||||
}
|
||||
|
||||
if (!allBaked && GUILayout.Button("Bake All")) {
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
if (!baked[i]) {
|
||||
baked[i] = true;
|
||||
bakedObjects[i] = SpineEditorUtilities.BakeRegion(atlasAsset, regions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!allUnbaked && GUILayout.Button("Unbake All")) {
|
||||
bool unbakeResult = EditorUtility.DisplayDialog("Delete All Baked Regions", "Are you sure you want to unbake all region prefabs? This cannot be undone.", "Yes", "Cancel");
|
||||
switch (unbakeResult) {
|
||||
case true:
|
||||
//delete
|
||||
for (int i = 0; i < regions.Count; i++) {
|
||||
if (baked[i]) {
|
||||
string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
|
||||
string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
|
||||
string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
|
||||
string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(regions[i]) + ".prefab").Replace("\\", "/");
|
||||
AssetDatabase.DeleteAsset(bakedPrefabPath);
|
||||
baked[i] = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case false:
|
||||
//do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
asset.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -28,57 +28,57 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
public class Menus {
|
||||
[MenuItem("Assets/Create/Spine Atlas")]
|
||||
static public void CreateAtlas () {
|
||||
CreateAsset<AtlasAsset>("New Atlas");
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Create/Spine SkeletonData")]
|
||||
static public void CreateSkeletonData () {
|
||||
CreateAsset<SkeletonDataAsset>("New SkeletonData");
|
||||
}
|
||||
|
||||
static private void CreateAsset <T> (String name) where T : ScriptableObject {
|
||||
var dir = "Assets/";
|
||||
var selected = Selection.activeObject;
|
||||
if (selected != null) {
|
||||
var assetDir = AssetDatabase.GetAssetPath(selected.GetInstanceID());
|
||||
if (assetDir.Length > 0 && Directory.Exists(assetDir))
|
||||
dir = assetDir + "/";
|
||||
namespace Spine.Unity {
|
||||
public static class Menus {
|
||||
[MenuItem("Assets/Create/Spine Atlas")]
|
||||
static public void CreateAtlas () {
|
||||
CreateAsset<AtlasAsset>("New Atlas");
|
||||
}
|
||||
ScriptableObject asset = ScriptableObject.CreateInstance<T>();
|
||||
AssetDatabase.CreateAsset(asset, dir + name + ".asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = asset;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/Spine/SkeletonRenderer", false, 10)]
|
||||
static public void CreateSkeletonRendererGameObject () {
|
||||
CreateSpineGameObject<SkeletonRenderer>("New SkeletonRenderer");
|
||||
}
|
||||
[MenuItem("Assets/Create/Spine SkeletonData")]
|
||||
static public void CreateSkeletonData () {
|
||||
CreateAsset<SkeletonDataAsset>("New SkeletonData");
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)]
|
||||
static public void CreateSkeletonAnimationGameObject () {
|
||||
CreateSpineGameObject<SkeletonAnimation>("New SkeletonAnimation");
|
||||
}
|
||||
static private void CreateAsset <T> (String name) where T : ScriptableObject {
|
||||
var dir = "Assets/";
|
||||
var selected = Selection.activeObject;
|
||||
if (selected != null) {
|
||||
var assetDir = AssetDatabase.GetAssetPath(selected.GetInstanceID());
|
||||
if (assetDir.Length > 0 && Directory.Exists(assetDir))
|
||||
dir = assetDir + "/";
|
||||
}
|
||||
ScriptableObject asset = ScriptableObject.CreateInstance<T>();
|
||||
AssetDatabase.CreateAsset(asset, dir + name + ".asset");
|
||||
AssetDatabase.SaveAssets();
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = asset;
|
||||
}
|
||||
|
||||
static public void CreateSpineGameObject<T> (string name) where T : MonoBehaviour {
|
||||
var parentGameObject = Selection.activeObject as GameObject;
|
||||
var parentTransform = parentGameObject == null ? null : parentGameObject.transform;
|
||||
[MenuItem("GameObject/Spine/SkeletonRenderer", false, 10)]
|
||||
static public void CreateSkeletonRendererGameObject () {
|
||||
CreateSpineGameObject<SkeletonRenderer>("New SkeletonRenderer");
|
||||
}
|
||||
|
||||
var gameObject = new GameObject("New SkeletonRenderer", typeof(T));
|
||||
gameObject.transform.SetParent(parentTransform, false);
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = gameObject;
|
||||
EditorGUIUtility.PingObject(Selection.activeObject);
|
||||
[MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)]
|
||||
static public void CreateSkeletonAnimationGameObject () {
|
||||
CreateSpineGameObject<SkeletonAnimation>("New SkeletonAnimation");
|
||||
}
|
||||
|
||||
static public void CreateSpineGameObject<T> (string name) where T : MonoBehaviour {
|
||||
var parentGameObject = Selection.activeObject as GameObject;
|
||||
var parentTransform = parentGameObject == null ? null : parentGameObject.transform;
|
||||
|
||||
var gameObject = new GameObject("New SkeletonRenderer", typeof(T));
|
||||
gameObject.transform.SetParent(parentTransform, false);
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = gameObject;
|
||||
EditorGUIUtility.PingObject(Selection.activeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,83 +28,85 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimation))]
|
||||
public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty animationName, loop, timeScale, autoReset;
|
||||
protected bool m_isPrefab;
|
||||
protected bool wasAnimationNameChanged;
|
||||
namespace Spine.Unity {
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimation))]
|
||||
public class SkeletonAnimationInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty animationName, loop, timeScale, autoReset;
|
||||
protected bool m_isPrefab;
|
||||
protected bool wasAnimationNameChanged;
|
||||
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
animationName = serializedObject.FindProperty("_animationName");
|
||||
loop = serializedObject.FindProperty("loop");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
animationName = serializedObject.FindProperty("_animationName");
|
||||
loop = serializedObject.FindProperty("loop");
|
||||
timeScale = serializedObject.FindProperty("timeScale");
|
||||
|
||||
if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
|
||||
m_isPrefab = true;
|
||||
}
|
||||
|
||||
protected override void DrawInspectorGUI () {
|
||||
base.DrawInspectorGUI();
|
||||
|
||||
SkeletonAnimation component = (SkeletonAnimation)target;
|
||||
if (!component.valid)
|
||||
return;
|
||||
|
||||
if (wasAnimationNameChanged) {
|
||||
if (!Application.isPlaying) {
|
||||
if (component.state != null) component.state.ClearTrack(0);
|
||||
component.skeleton.SetToSetupPose();
|
||||
}
|
||||
|
||||
Spine.Animation animationToUse = component.skeleton.Data.FindAnimation(animationName.stringValue);
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
if (animationToUse != null) animationToUse.Apply(component.skeleton, 0f, 0f, false, null);
|
||||
component.Update();
|
||||
component.LateUpdate();
|
||||
SceneView.RepaintAll();
|
||||
} else {
|
||||
if (animationToUse != null)
|
||||
component.state.SetAnimation(0, animationToUse, loop.boolValue);
|
||||
else
|
||||
component.state.ClearTrack(0);
|
||||
}
|
||||
|
||||
wasAnimationNameChanged = false;
|
||||
if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
|
||||
m_isPrefab = true;
|
||||
}
|
||||
|
||||
// Reflect animationName serialized property in the inspector even if SetAnimation API was used.
|
||||
if (Application.isPlaying) {
|
||||
TrackEntry current = component.state.GetCurrent(0);
|
||||
if (current != null) {
|
||||
if (component.AnimationName != animationName.stringValue) {
|
||||
animationName.stringValue = current.Animation.Name;
|
||||
protected override void DrawInspectorGUI () {
|
||||
base.DrawInspectorGUI();
|
||||
|
||||
SkeletonAnimation component = (SkeletonAnimation)target;
|
||||
if (!component.valid)
|
||||
return;
|
||||
|
||||
if (wasAnimationNameChanged) {
|
||||
if (!Application.isPlaying) {
|
||||
if (component.state != null) component.state.ClearTrack(0);
|
||||
component.skeleton.SetToSetupPose();
|
||||
}
|
||||
|
||||
Spine.Animation animationToUse = component.skeleton.Data.FindAnimation(animationName.stringValue);
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
if (animationToUse != null) animationToUse.Apply(component.skeleton, 0f, 0f, false, null);
|
||||
component.Update();
|
||||
component.LateUpdate();
|
||||
SceneView.RepaintAll();
|
||||
} else {
|
||||
if (animationToUse != null)
|
||||
component.state.SetAnimation(0, animationToUse, loop.boolValue);
|
||||
else
|
||||
component.state.ClearTrack(0);
|
||||
}
|
||||
|
||||
wasAnimationNameChanged = false;
|
||||
}
|
||||
|
||||
// Reflect animationName serialized property in the inspector even if SetAnimation API was used.
|
||||
if (Application.isPlaying) {
|
||||
TrackEntry current = component.state.GetCurrent(0);
|
||||
if (current != null) {
|
||||
if (component.AnimationName != animationName.stringValue) {
|
||||
animationName.stringValue = current.Animation.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(animationName);
|
||||
wasAnimationNameChanged |= EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(loop);
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
component.timeScale = Math.Max(component.timeScale, 0);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(animationName);
|
||||
wasAnimationNameChanged |= EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(loop);
|
||||
EditorGUILayout.PropertyField(timeScale);
|
||||
component.timeScale = Math.Max(component.timeScale, 0);
|
||||
|
||||
if (!m_isPrefab) {
|
||||
if (component.GetComponent<SkeletonUtility>() == null) {
|
||||
if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
|
||||
component.gameObject.AddComponent<SkeletonUtility>();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (!m_isPrefab) {
|
||||
if (component.GetComponent<SkeletonUtility>() == null) {
|
||||
if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
|
||||
component.gameObject.AddComponent<SkeletonUtility>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* SkeletonAnimatorInspector created by Mitch Thompson
|
||||
* Full irrevocable rights and permissions granted to Esoteric Software
|
||||
@ -7,37 +5,38 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Spine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonAnimator))]
|
||||
public class SkeletonAnimatorInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty layerMixModes;
|
||||
protected bool isPrefab;
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
layerMixModes = serializedObject.FindProperty("layerMixModes");
|
||||
namespace Spine.Unity {
|
||||
[CustomEditor(typeof(SkeletonAnimator))]
|
||||
public class SkeletonAnimatorInspector : SkeletonRendererInspector {
|
||||
protected SerializedProperty layerMixModes;
|
||||
protected bool isPrefab;
|
||||
protected override void OnEnable () {
|
||||
base.OnEnable();
|
||||
layerMixModes = serializedObject.FindProperty("layerMixModes");
|
||||
|
||||
if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
|
||||
isPrefab = true;
|
||||
}
|
||||
if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
|
||||
isPrefab = true;
|
||||
}
|
||||
|
||||
protected override void DrawInspectorGUI () {
|
||||
base.DrawInspectorGUI();
|
||||
protected override void DrawInspectorGUI () {
|
||||
base.DrawInspectorGUI();
|
||||
|
||||
EditorGUILayout.PropertyField(layerMixModes, true);
|
||||
EditorGUILayout.PropertyField(layerMixModes, true);
|
||||
|
||||
SkeletonAnimator component = (SkeletonAnimator)target;
|
||||
if (!component.valid)
|
||||
return;
|
||||
SkeletonAnimator component = (SkeletonAnimator)target;
|
||||
if (!component.valid)
|
||||
return;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (!isPrefab) {
|
||||
if (component.GetComponent<SkeletonUtility>() == null) {
|
||||
if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
|
||||
component.gameObject.AddComponent<SkeletonUtility>();
|
||||
if (!isPrefab) {
|
||||
if (component.GetComponent<SkeletonUtility>() == null) {
|
||||
if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
|
||||
component.gameObject.AddComponent<SkeletonUtility>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,118 +33,121 @@ using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(SkeletonRenderer))]
|
||||
public class SkeletonRendererInspector : Editor {
|
||||
protected static bool advancedFoldout;
|
||||
namespace Spine.Unity {
|
||||
|
||||
[CustomEditor(typeof(SkeletonRenderer))]
|
||||
public class SkeletonRendererInspector : Editor {
|
||||
protected static bool advancedFoldout;
|
||||
|
||||
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes, immutableTriangles, submeshSeparators, front, zSpacing;
|
||||
protected SerializedProperty skeletonDataAsset, initialSkinName, normals, tangents, meshes, immutableTriangles, submeshSeparators, front, zSpacing;
|
||||
|
||||
protected SpineInspectorUtility.SerializedSortingProperties sortingProperties;
|
||||
protected SpineInspectorUtility.SerializedSortingProperties sortingProperties;
|
||||
|
||||
protected virtual void OnEnable () {
|
||||
SpineEditorUtilities.ConfirmInitialization();
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
normals = serializedObject.FindProperty("calculateNormals");
|
||||
tangents = serializedObject.FindProperty("calculateTangents");
|
||||
meshes = serializedObject.FindProperty("renderMeshes");
|
||||
immutableTriangles = serializedObject.FindProperty("immutableTriangles");
|
||||
submeshSeparators = serializedObject.FindProperty("submeshSeparators");
|
||||
front = serializedObject.FindProperty("frontFacing");
|
||||
zSpacing = serializedObject.FindProperty("zSpacing");
|
||||
protected virtual void OnEnable () {
|
||||
SpineEditorUtilities.ConfirmInitialization();
|
||||
skeletonDataAsset = serializedObject.FindProperty("skeletonDataAsset");
|
||||
initialSkinName = serializedObject.FindProperty("initialSkinName");
|
||||
normals = serializedObject.FindProperty("calculateNormals");
|
||||
tangents = serializedObject.FindProperty("calculateTangents");
|
||||
meshes = serializedObject.FindProperty("renderMeshes");
|
||||
immutableTriangles = serializedObject.FindProperty("immutableTriangles");
|
||||
submeshSeparators = serializedObject.FindProperty("submeshSeparators");
|
||||
front = serializedObject.FindProperty("frontFacing");
|
||||
zSpacing = serializedObject.FindProperty("zSpacing");
|
||||
|
||||
var renderer = ((SkeletonRenderer)target).GetComponent<Renderer>();
|
||||
sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(renderer);
|
||||
}
|
||||
var renderer = ((SkeletonRenderer)target).GetComponent<Renderer>();
|
||||
sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(renderer);
|
||||
}
|
||||
|
||||
protected virtual void DrawInspectorGUI () {
|
||||
SkeletonRenderer component = (SkeletonRenderer)target;
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
float reloadWidth = GUI.skin.label.CalcSize(new GUIContent("Reload")).x + 20;
|
||||
if (GUILayout.Button("Reload", GUILayout.Width(reloadWidth))) {
|
||||
if (component.skeletonDataAsset != null) {
|
||||
foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets) {
|
||||
if (aa != null)
|
||||
aa.Reset();
|
||||
protected virtual void DrawInspectorGUI () {
|
||||
SkeletonRenderer component = (SkeletonRenderer)target;
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PropertyField(skeletonDataAsset);
|
||||
float reloadWidth = GUI.skin.label.CalcSize(new GUIContent("Reload")).x + 20;
|
||||
if (GUILayout.Button("Reload", GUILayout.Width(reloadWidth))) {
|
||||
if (component.skeletonDataAsset != null) {
|
||||
foreach (AtlasAsset aa in component.skeletonDataAsset.atlasAssets) {
|
||||
if (aa != null)
|
||||
aa.Reset();
|
||||
}
|
||||
|
||||
component.skeletonDataAsset.Reset();
|
||||
}
|
||||
|
||||
component.skeletonDataAsset.Reset();
|
||||
component.Initialize(true);
|
||||
}
|
||||
component.Initialize(true);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (!component.valid) {
|
||||
component.Initialize(true);
|
||||
component.LateUpdate();
|
||||
if (!component.valid)
|
||||
return;
|
||||
}
|
||||
|
||||
// Initial skin name.
|
||||
{
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count];
|
||||
int skinIndex = 0;
|
||||
for (int i = 0; i < skins.Length; i++) {
|
||||
String skinNameString = component.skeleton.Data.Skins.Items[i].Name;
|
||||
skins[i] = skinNameString;
|
||||
if (skinNameString == initialSkinName.stringValue)
|
||||
skinIndex = i;
|
||||
if (!component.valid) {
|
||||
component.Initialize(true);
|
||||
component.LateUpdate();
|
||||
if (!component.valid)
|
||||
return;
|
||||
}
|
||||
|
||||
skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);
|
||||
initialSkinName.stringValue = skins[skinIndex];
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Sorting Layers
|
||||
{
|
||||
SpineInspectorUtility.SortingPropertyFields(sortingProperties, applyModifiedProperties: true);
|
||||
}
|
||||
|
||||
// More Render Options...
|
||||
{
|
||||
advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
|
||||
if(advancedFoldout) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(submeshSeparators, true);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(meshes,
|
||||
new GUIContent("Render Mesh Attachments", "Disable to optimize rendering for skeletons that don't use Mesh Attachments"));
|
||||
EditorGUILayout.PropertyField(immutableTriangles,
|
||||
new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
|
||||
EditorGUILayout.Space();
|
||||
|
||||
const float MinZSpacing = -0.1f;
|
||||
const float MaxZSpacing = 0f;
|
||||
EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing);
|
||||
|
||||
if (normals != null) {
|
||||
EditorGUILayout.PropertyField(normals);
|
||||
EditorGUILayout.PropertyField(tangents);
|
||||
// Initial skin name.
|
||||
{
|
||||
String[] skins = new String[component.skeleton.Data.Skins.Count];
|
||||
int skinIndex = 0;
|
||||
for (int i = 0; i < skins.Length; i++) {
|
||||
String skinNameString = component.skeleton.Data.Skins.Items[i].Name;
|
||||
skins[i] = skinNameString;
|
||||
if (skinNameString == initialSkinName.stringValue)
|
||||
skinIndex = i;
|
||||
}
|
||||
|
||||
if (front != null) {
|
||||
EditorGUILayout.PropertyField(front);
|
||||
}
|
||||
skinIndex = EditorGUILayout.Popup("Initial Skin", skinIndex, skins);
|
||||
initialSkinName.stringValue = skins[skinIndex];
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUI.indentLevel--;
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Sorting Layers
|
||||
{
|
||||
SpineInspectorUtility.SortingPropertyFields(sortingProperties, applyModifiedProperties: true);
|
||||
}
|
||||
|
||||
// More Render Options...
|
||||
{
|
||||
advancedFoldout = EditorGUILayout.Foldout(advancedFoldout, "Advanced");
|
||||
if(advancedFoldout) {
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(submeshSeparators, true);
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(meshes,
|
||||
new GUIContent("Render Mesh Attachments", "Disable to optimize rendering for skeletons that don't use Mesh Attachments"));
|
||||
EditorGUILayout.PropertyField(immutableTriangles,
|
||||
new GUIContent("Immutable Triangles", "Enable to optimize rendering for skeletons that never change attachment visbility"));
|
||||
EditorGUILayout.Space();
|
||||
|
||||
const float MinZSpacing = -0.1f;
|
||||
const float MaxZSpacing = 0f;
|
||||
EditorGUILayout.Slider(zSpacing, MinZSpacing, MaxZSpacing);
|
||||
|
||||
if (normals != null) {
|
||||
EditorGUILayout.PropertyField(normals);
|
||||
EditorGUILayout.PropertyField(tangents);
|
||||
}
|
||||
|
||||
if (front != null) {
|
||||
EditorGUILayout.PropertyField(front);
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
DrawInspectorGUI();
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying)
|
||||
((SkeletonRenderer)target).Initialize(true);
|
||||
override public void OnInspectorGUI () {
|
||||
serializedObject.Update();
|
||||
DrawInspectorGUI();
|
||||
if (serializedObject.ApplyModifiedProperties() ||
|
||||
(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
|
||||
) {
|
||||
if (!Application.isPlaying)
|
||||
((SkeletonRenderer)target).Initialize(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,59 +34,62 @@ using System.Collections;
|
||||
using UnityEditor;
|
||||
using System.Reflection;
|
||||
|
||||
public static class SpineInspectorUtility {
|
||||
|
||||
#region Sorting Layer Field Helpers
|
||||
static readonly GUIContent SortingLayerLabel = new GUIContent("Sorting Layer");
|
||||
static readonly GUIContent OrderInLayerLabel = new GUIContent("Order in Layer");
|
||||
namespace Spine.Unity {
|
||||
public static class SpineInspectorUtility {
|
||||
|
||||
static MethodInfo m_SortingLayerFieldMethod;
|
||||
static MethodInfo SortingLayerFieldMethod {
|
||||
get {
|
||||
if (m_SortingLayerFieldMethod == null)
|
||||
m_SortingLayerFieldMethod = typeof(EditorGUILayout).GetMethod("SortingLayerField", BindingFlags.Static | BindingFlags.NonPublic, null, new System.Type[] { typeof(GUIContent), typeof(SerializedProperty), typeof(GUIStyle) }, null);
|
||||
#region Sorting Layer Field Helpers
|
||||
static readonly GUIContent SortingLayerLabel = new GUIContent("Sorting Layer");
|
||||
static readonly GUIContent OrderInLayerLabel = new GUIContent("Order in Layer");
|
||||
|
||||
return m_SortingLayerFieldMethod;
|
||||
}
|
||||
}
|
||||
static MethodInfo m_SortingLayerFieldMethod;
|
||||
static MethodInfo SortingLayerFieldMethod {
|
||||
get {
|
||||
if (m_SortingLayerFieldMethod == null)
|
||||
m_SortingLayerFieldMethod = typeof(EditorGUILayout).GetMethod("SortingLayerField", BindingFlags.Static | BindingFlags.NonPublic, null, new System.Type[] { typeof(GUIContent), typeof(SerializedProperty), typeof(GUIStyle) }, null);
|
||||
|
||||
public struct SerializedSortingProperties {
|
||||
public SerializedObject renderer;
|
||||
public SerializedProperty sortingLayerID;
|
||||
public SerializedProperty sortingOrder;
|
||||
|
||||
public SerializedSortingProperties (Renderer r) {
|
||||
renderer = new SerializedObject(r);
|
||||
sortingLayerID = renderer.FindProperty("m_SortingLayerID");
|
||||
sortingOrder = renderer.FindProperty("m_SortingOrder");
|
||||
}
|
||||
|
||||
public void ApplyModifiedProperties () {
|
||||
renderer.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SortingPropertyFields (SerializedSortingProperties prop, bool applyModifiedProperties) {
|
||||
if (applyModifiedProperties) {
|
||||
EditorGUI.BeginChangeCheck();
|
||||
SortingPropertyFields(prop.sortingLayerID, prop.sortingOrder);
|
||||
if(EditorGUI.EndChangeCheck()) {
|
||||
prop.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(prop.renderer.targetObject);
|
||||
return m_SortingLayerFieldMethod;
|
||||
}
|
||||
} else {
|
||||
SortingPropertyFields(prop.sortingLayerID, prop.sortingOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SortingPropertyFields (SerializedProperty m_SortingLayerID, SerializedProperty m_SortingOrder) {
|
||||
if (SpineInspectorUtility.SortingLayerFieldMethod != null && m_SortingLayerID != null) {
|
||||
SpineInspectorUtility.SortingLayerFieldMethod.Invoke(null, new object[] { SortingLayerLabel, m_SortingLayerID, EditorStyles.popup } );
|
||||
} else {
|
||||
EditorGUILayout.PropertyField(m_SortingLayerID);
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(m_SortingOrder, OrderInLayerLabel);
|
||||
public struct SerializedSortingProperties {
|
||||
public SerializedObject renderer;
|
||||
public SerializedProperty sortingLayerID;
|
||||
public SerializedProperty sortingOrder;
|
||||
|
||||
public SerializedSortingProperties (Renderer r) {
|
||||
renderer = new SerializedObject(r);
|
||||
sortingLayerID = renderer.FindProperty("m_SortingLayerID");
|
||||
sortingOrder = renderer.FindProperty("m_SortingOrder");
|
||||
}
|
||||
|
||||
public void ApplyModifiedProperties () {
|
||||
renderer.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SortingPropertyFields (SerializedSortingProperties prop, bool applyModifiedProperties) {
|
||||
if (applyModifiedProperties) {
|
||||
EditorGUI.BeginChangeCheck();
|
||||
SortingPropertyFields(prop.sortingLayerID, prop.sortingOrder);
|
||||
if(EditorGUI.EndChangeCheck()) {
|
||||
prop.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(prop.renderer.targetObject);
|
||||
}
|
||||
} else {
|
||||
SortingPropertyFields(prop.sortingLayerID, prop.sortingOrder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SortingPropertyFields (SerializedProperty m_SortingLayerID, SerializedProperty m_SortingOrder) {
|
||||
if (SpineInspectorUtility.SortingLayerFieldMethod != null && m_SortingLayerID != null) {
|
||||
SpineInspectorUtility.SortingLayerFieldMethod.Invoke(null, new object[] { SortingLayerLabel, m_SortingLayerID, EditorStyles.popup } );
|
||||
} else {
|
||||
EditorGUILayout.PropertyField(m_SortingLayerID);
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(m_SortingOrder, OrderInLayerLabel);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ namespace Spine.Unity {
|
||||
EditorGUIUtility.PingObject(Selection.activeObject);
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Spine/Instantiate (UnityUI)", false, 0)]
|
||||
[MenuItem("Assets/Spine/Instantiate (UnityUI)", false, 10)]
|
||||
static void InstantiateSkeletonGraphic () {
|
||||
Object[] arr = Selection.objects;
|
||||
foreach (Object o in arr) {
|
||||
@ -161,7 +161,7 @@ namespace Spine.Unity {
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Assets/Spine/Instantiate (UnityUI)", true, 0)]
|
||||
[MenuItem("Assets/Spine/Instantiate (UnityUI)", true, 10)]
|
||||
static bool ValidateInstantiateSkeletonGraphic () {
|
||||
Object[] arr = Selection.objects;
|
||||
|
||||
|
||||
@ -212,7 +212,7 @@ namespace Spine.Unity {
|
||||
spineMeshGenerator.Scale = canvas.referencePixelsPerUnit; // TODO: move this to a listener to of the canvas?
|
||||
|
||||
canvasRenderer.SetMesh(spineMeshGenerator.GenerateMesh(skeleton));
|
||||
this.UpdateMaterial();
|
||||
//this.UpdateMaterial(); // TODO: This allocates memory.
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user