Skip to content

Instantly share code, notes, and snippets.

@Trissiklikk
Last active March 25, 2024 08:39
Show Gist options
  • Save Trissiklikk/1bfa8aa5938b842372d265afe5ee1375 to your computer and use it in GitHub Desktop.
Save Trissiklikk/1bfa8aa5938b842372d265afe5ee1375 to your computer and use it in GitHub Desktop.
Unity Spine : MixDurationIOUtilityEditor
# if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using Spine.Unity;
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using System.IO;
using Newtonsoft.Json;
public class SpineMixDurationIOUtilityEditor : EditorWindow
{
[MenuItem("Window/Trissiklikk Editor Tools/Spine Mix Duration IO Utiltity")]
public static void Init()
{
GetWindow(typeof(SpineMixDurationIOUtilityWindowEditor));
m_skeletonDataAsset = null;
}
public static SkeletonDataAsset m_skeletonDataAsset;
private const string SAVE_MIX_DURATION_PATH = "SpineMixDurationData";
private const string FILE_NAME = "MixDurationData.dat";
private List<AnimationMixPair> animationMixPairs;
public SpineMixDurationSettingWindow()
{
animationMixPairs = new List<AnimationMixPair>();
}
private void OnGUI()
{
EditorGUILayout.Space(5);
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("Drag and Drop Spine data asset in this window", TitelTextStyle());
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
EditorGUILayout.Space(10);
if (Event.current.type == EventType.DragExited)
{
if (DragAndDrop.objectReferences.Length > 1)
{
Debug.LogError("You can only drag one object at a time");
return;
}
m_skeletonDataAsset = DragAndDrop.objectReferences[0] as SkeletonDataAsset;
}
if (m_skeletonDataAsset != null)
{
EditorGUILayout.LabelField($"Data Name: {m_skeletonDataAsset.name}", DefaultTextStyle());
EditorGUILayout.Space(5);
if (GUILayout.Button("Save Data"))
SaveData();
if (GUILayout.Button("Replace Data"))
ReplaceData();
}
EditorGUILayout.EndVertical();
}
private void ReplaceData()
{
if (m_skeletonDataAsset == null)
{
Debug.LogError("Please drag and drop Spine data asset in this window");
return;
}
LoadFile();
m_skeletonDataAsset.fromAnimation = new string[animationMixPairs.Count];
m_skeletonDataAsset.toAnimation = new string[animationMixPairs.Count];
m_skeletonDataAsset.duration = new float[animationMixPairs.Count];
for (int i = 0; i < animationMixPairs.Count; i++)
{
m_skeletonDataAsset.fromAnimation[i] = animationMixPairs[i].FromAnimation;
m_skeletonDataAsset.toAnimation[i] = animationMixPairs[i].ToAnimation;
m_skeletonDataAsset.duration[i] = animationMixPairs[i].MixDuration;
}
Validate();
}
/// <summary>
/// Call this method for save data to json file.
/// This will save data to application data path that combine with SAVE_MIX_DURATION_PATH.
/// As file name is FILE_NAME.
/// </summary>
private void SaveData()
{
animationMixPairs.Clear();
for (int i = 0; i < m_skeletonDataAsset.toAnimation.Length; i++)
{
string toAnimation = m_skeletonDataAsset.toAnimation[i];
string fromAnimation = m_skeletonDataAsset.fromAnimation[i];
float mixDuration = m_skeletonDataAsset.duration[i];
bool quiet = false;
if (m_skeletonDataAsset.GetSkeletonData(quiet).FindAnimation(fromAnimation) == null)
{
if (!quiet)
Debug.LogError(string.Format("Custom Mix Durations: Animation '{0}' not found, was it renamed?",
fromAnimation), this);
continue;
}
if (m_skeletonDataAsset.GetSkeletonData(quiet).FindAnimation(toAnimation) == null)
{
if (!quiet)
Debug.LogError(string.Format("Custom Mix Durations: Animation '{0}' not found, was it renamed?",
toAnimation), this);
continue;
}
animationMixPairs.Add(new AnimationMixPair()
{
FromAnimation = fromAnimation,
ToAnimation = toAnimation,
MixDuration = mixDuration
});
}
JArray jObject = new JArray();
for (int i = 0; i < animationMixPairs.Count; i++)
{
jObject.Add(animationMixPairs[i].ToJson);
}
string path = Path.Combine(Application.dataPath, SAVE_MIX_DURATION_PATH);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
string filePath = Path.Combine(path, FILE_NAME);
string json = jObject.ToString();
File.WriteAllText(filePath, json);
Validate();
}
/// <summary>
/// Method for load data from json file from application data path that combine with SAVE_MIX_DURATION_PATH.
/// As file name is FILE_NAME.
/// </summary>
private void LoadFile()
{
animationMixPairs.Clear();
string path = Path.Combine(Application.dataPath, SAVE_MIX_DURATION_PATH);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
string[] files = Directory.GetFiles(path);
if (files.Length == 0)
{
Debug.LogError("File not found");
return;
}
string content = File.ReadAllText(files[0]);
JToken jsonToken = JsonConvert.DeserializeObject(content) as JToken;
if (jsonToken is JArray array)
{
for (int i = 0; i < array.Count; i++)
animationMixPairs.Add(AnimationMixPair.CreateFromJson(array[i]));
}
Validate();
}
/// <summary>
/// This is for get default text style.
/// </summary>
/// <returns></returns>
private GUIStyle DefaultTextStyle()
{
GUIStyle labelStyle = new GUIStyle();
labelStyle.fontStyle = FontStyle.Normal;
labelStyle.fontSize = 12;
labelStyle.alignment = TextAnchor.MiddleLeft;
labelStyle.normal.textColor = Color.white;
return labelStyle;
}
/// <summary>
/// This is for get title text style.
/// </summary>
/// <returns></returns>
private GUIStyle TitelTextStyle()
{
GUIStyle labelStyle = new GUIStyle();
labelStyle.fontStyle = FontStyle.Bold;
labelStyle.fontSize = 14;
labelStyle.alignment = TextAnchor.MiddleCenter;
labelStyle.normal.textColor = Color.white;
return labelStyle;
}
private void Validate()
{
GC.Collect();
}
public struct AnimationMixPair
{
public string FromAnimation;
public string ToAnimation;
public float MixDuration;
/// <summary>
/// Method for create AnimationMixPair from json.
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
public static AnimationMixPair CreateFromJson(JToken json)
{
AnimationMixPair animationMixPair = new AnimationMixPair();
animationMixPair.FromAnimation = json["from"].ToString();
animationMixPair.ToAnimation = json["to"].ToString();
animationMixPair.MixDuration = json["duration"].ToObject<float>();
return animationMixPair;
}
/// <summary>
/// Method for convert to JToken.
/// </summary>
public JToken ToJson
{
get
{
JObject jObject = new JObject();
jObject.Add("from", FromAnimation);
jObject.Add("to", ToAnimation);
jObject.Add("duration", MixDuration);
return jObject;
}
}
/// <summary>
/// Method for convert to string.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("{0} -> {1} : {2}", FromAnimation, ToAnimation, MixDuration);
}
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment