This commit is contained in:
badlogic 2019-10-24 16:51:09 +02:00
commit 8a93522ce9
12 changed files with 95 additions and 79 deletions

View File

@ -1064,7 +1064,7 @@ namespace Spine {
case MixBlend.Setup: case MixBlend.Setup:
deformArray.Clear(); deformArray.Clear();
return; return;
case MixBlend.Replace: case MixBlend.First:
if (alpha == 1) { if (alpha == 1) {
deformArray.Clear(); deformArray.Clear();
return; return;

View File

@ -76,8 +76,7 @@ namespace Spine {
protected AnimationStateData data; protected AnimationStateData data;
private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>(); private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>();
private readonly ExposedList<Event> events = new ExposedList<Event>(); private readonly ExposedList<Event> events = new ExposedList<Event>();
// difference to libgdx reference: delegates are used for event callbacks instead of 'final SnapshotArray<AnimationStateListener> listeners'.
// difference to libgdx reference: delegates are used for event callbacks instead of 'Array<AnimationStateListener> listeners'.
internal void OnStart (TrackEntry entry) { if (Start != null) Start(entry); } internal void OnStart (TrackEntry entry) { if (Start != null) Start(entry); }
internal void OnInterrupt (TrackEntry entry) { if (Interrupt != null) Interrupt(entry); } internal void OnInterrupt (TrackEntry entry) { if (Interrupt != null) Interrupt(entry); }
internal void OnEnd (TrackEntry entry) { if (End != null) End(entry); } internal void OnEnd (TrackEntry entry) { if (End != null) End(entry); }
@ -90,7 +89,7 @@ namespace Spine {
public delegate void TrackEntryEventDelegate (TrackEntry trackEntry, Event e); public delegate void TrackEntryEventDelegate (TrackEntry trackEntry, Event e);
public event TrackEntryEventDelegate Event; public event TrackEntryEventDelegate Event;
// end of difference
private readonly EventQueue queue; // Initialized by constructor. private readonly EventQueue queue; // Initialized by constructor.
private readonly HashSet<int> propertyIDs = new HashSet<int>(); private readonly HashSet<int> propertyIDs = new HashSet<int>();
private bool animationsChanged; private bool animationsChanged;
@ -233,8 +232,8 @@ namespace Spine {
} else { } else {
var timelineMode = current.timelineMode.Items; var timelineMode = current.timelineMode.Items;
bool firstFrame = current.timelinesRotation.Count == 0; bool firstFrame = current.timelinesRotation.Count != timelineCount << 1;
if (firstFrame) current.timelinesRotation.EnsureCapacity(timelines.Count << 1); if (firstFrame) current.timelinesRotation.Resize(timelines.Count << 1);
var timelinesRotation = current.timelinesRotation.Items; var timelinesRotation = current.timelinesRotation.Items;
for (int ii = 0; ii < timelineCount; ii++) { for (int ii = 0; ii < timelineCount; ii++) {
@ -242,8 +241,8 @@ namespace Spine {
MixBlend timelineBlend = (timelineMode[ii] & AnimationState.NotLast - 1) == AnimationState.Subsequent ? blend : MixBlend.Setup; MixBlend timelineBlend = (timelineMode[ii] & AnimationState.NotLast - 1) == AnimationState.Subsequent ? blend : MixBlend.Setup;
var rotateTimeline = timeline as RotateTimeline; var rotateTimeline = timeline as RotateTimeline;
if (rotateTimeline != null) if (rotateTimeline != null)
ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation,
firstFrame); ii << 1, firstFrame);
else else
timeline.Apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, MixDirection.In); timeline.Apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, MixDirection.In);
} }
@ -287,7 +286,7 @@ namespace Spine {
var timelineMode = from.timelineMode.Items; var timelineMode = from.timelineMode.Items;
var timelineHoldMix = from.timelineHoldMix.Items; var timelineHoldMix = from.timelineHoldMix.Items;
bool firstFrame = from.timelinesRotation.Count == 0; bool firstFrame = from.timelinesRotation.Count != timelineCount << 1;
if (firstFrame) from.timelinesRotation.Resize(timelines.Count << 1); // from.timelinesRotation.setSize if (firstFrame) from.timelinesRotation.Resize(timelines.Count << 1); // from.timelinesRotation.setSize
var timelinesRotation = from.timelinesRotation.Items; var timelinesRotation = from.timelinesRotation.Items;
@ -325,8 +324,8 @@ namespace Spine {
var rotateTimeline = timeline as RotateTimeline; var rotateTimeline = timeline as RotateTimeline;
if (rotateTimeline != null) { if (rotateTimeline != null) {
ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation,
firstFrame); i << 1, firstFrame);
} else { } else {
if (timelineBlend == MixBlend.Setup) { if (timelineBlend == MixBlend.Setup) {
if (timeline is AttachmentTimeline) { if (timeline is AttachmentTimeline) {

View File

@ -37,6 +37,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.IntSet;
import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.VertexAttachment; import com.esotericsoftware.spine.attachments.VertexAttachment;
@ -44,21 +45,36 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
/** A simple container for a list of timelines and a name. */ /** A simple container for a list of timelines and a name. */
public class Animation { public class Animation {
final String name; final String name;
final Array<Timeline> timelines; Array<Timeline> timelines;
final IntSet timelineIDs = new IntSet();
float duration; float duration;
public Animation (String name, Array<Timeline> timelines, float duration) { public Animation (String name, Array<Timeline> timelines, float duration) {
if (name == null) throw new IllegalArgumentException("name cannot be null."); if (name == null) throw new IllegalArgumentException("name cannot be null.");
if (timelines == null) throw new IllegalArgumentException("timelines cannot be null.");
this.name = name; this.name = name;
this.timelines = timelines;
this.duration = duration; this.duration = duration;
setTimelines(timelines);
} }
/** If the returned array or the timelines it contains are modified, {@link #setTimelines(Array)} must be called. */
public Array<Timeline> getTimelines () { public Array<Timeline> getTimelines () {
return timelines; return timelines;
} }
public void setTimelines (Array<Timeline> timelines) {
if (timelines == null) throw new IllegalArgumentException("timelines cannot be null.");
this.timelines = timelines;
timelineIDs.clear();
for (Timeline timeline : timelines)
timelineIDs.add(timeline.getPropertyId());
}
/** Return true if this animation contains a timeline with the specified property ID. **/
public boolean hasTimeline (int id) {
return timelineIDs.contains(id);
}
/** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */ /** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */
public float getDuration () { public float getDuration () {
return duration; return duration;

View File

@ -37,6 +37,7 @@ import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntSet; import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.Pool; import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pool.Poolable; import com.badlogic.gdx.utils.Pool.Poolable;
import com.esotericsoftware.spine.Animation.AttachmentTimeline; import com.esotericsoftware.spine.Animation.AttachmentTimeline;
import com.esotericsoftware.spine.Animation.DrawOrderTimeline; import com.esotericsoftware.spine.Animation.DrawOrderTimeline;
import com.esotericsoftware.spine.Animation.EventTimeline; import com.esotericsoftware.spine.Animation.EventTimeline;
@ -745,11 +746,11 @@ public class AnimationState {
if (!propertyIDs.add(id)) if (!propertyIDs.add(id))
timelineMode[i] = SUBSEQUENT; timelineMode[i] = SUBSEQUENT;
else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline
|| timeline instanceof EventTimeline || !hasTimeline(to, id)) { || timeline instanceof EventTimeline || !to.animation.hasTimeline(id)) {
timelineMode[i] = FIRST; timelineMode[i] = FIRST;
} else { } else {
for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) { for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) {
if (hasTimeline(next, id)) continue; if (next.animation.hasTimeline(id)) continue;
if (next.mixDuration > 0) { if (next.mixDuration > 0) {
timelineMode[i] = HOLD_MIX; timelineMode[i] = HOLD_MIX;
timelineHoldMix[i] = next; timelineHoldMix[i] = next;
@ -776,13 +777,6 @@ public class AnimationState {
} }
} }
private boolean hasTimeline (TrackEntry entry, int id) {
Object[] timelines = entry.animation.timelines.items;
for (int i = 0, n = entry.animation.timelines.size; i < n; i++)
if (((Timeline)timelines[i]).getPropertyId() == id) return true;
return false;
}
/** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
public TrackEntry getCurrent (int trackIndex) { public TrackEntry getCurrent (int trackIndex) {
if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0."); if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0.");

View File

@ -1,5 +1,5 @@
# spine-ue4 # spine-ue4
The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4.18+](https://www.unrealengine.com/). spine-ue4 is based on [spine-cpp](../spine-cpp). The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4.21+](https://www.unrealengine.com/). spine-ue4 is based on [spine-cpp](../spine-cpp).
## Licensing ## Licensing
@ -33,7 +33,7 @@ See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documen
## Example ## Example
### [Please see the spine-ue4 guide for full documentation](http://esotericsoftware.com/spine-ue4) ### [Please see the spine-ue4 guide for full documentation](http://esotericsoftware.com/spine-ue4)
The Spine UE4 example works on all platforms supported by Unreal Engine. The samples require Unreal Engine 4.18. The Spine UE4 example works on all platforms supported by Unreal Engine. The samples require Unreal Engine 4.23+.
1. Copy the `spine-cpp` folder from this repositories root directory to your `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory. 1. Copy the `spine-cpp` folder from this repositories root directory to your `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory.
2. Open the SpineUE4.uproject file with Unreal Editor 2. Open the SpineUE4.uproject file with Unreal Editor

View File

@ -1,6 +1,6 @@
{ {
"FileVersion": 3, "FileVersion": 3,
"EngineAssociation": "4.22", "EngineAssociation": "4.23",
"Category": "", "Category": "",
"Description": "", "Description": "",
"Modules": [ "Modules": [

View File

@ -659,7 +659,7 @@ namespace Spine.Unity.Editor {
} }
void DoReimport () { void DoReimport () {
AssetUtility.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true); AssetUtility.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, null, true);
preview.Clear(); preview.Clear();
InitializeEditor(); InitializeEditor();
EditorUtility.SetDirty(targetSkeletonDataAsset); EditorUtility.SetDirty(targetSkeletonDataAsset);

View File

@ -65,7 +65,7 @@ namespace Spine.Unity.Editor {
public static readonly List<ScriptableObject> protectFromStackGarbageCollection = new List<ScriptableObject>(); public static readonly List<ScriptableObject> protectFromStackGarbageCollection = new List<ScriptableObject>();
public static HashSet<string> assetsImportedInWrongState = new HashSet<string>(); public static HashSet<string> assetsImportedInWrongState = new HashSet<string>();
public static void HandleOnPostprocessAllAssets (string[] imported) { public static void HandleOnPostprocessAllAssets (string[] imported, List<string> texturesWithoutMetaFile) {
// In case user used "Assets -> Reimport All", during the import process, // In case user used "Assets -> Reimport All", during the import process,
// asset database is not initialized until some point. During that period, // asset database is not initialized until some point. During that period,
// all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath) // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath)
@ -87,7 +87,7 @@ namespace Spine.Unity.Editor {
if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) {
string[] combinedAssets = AssetUtility.assetsImportedInWrongState.ToArray(); string[] combinedAssets = AssetUtility.assetsImportedInWrongState.ToArray();
AssetUtility.assetsImportedInWrongState.Clear(); AssetUtility.assetsImportedInWrongState.Clear();
AssetUtility.ImportSpineContent(combinedAssets); AssetUtility.ImportSpineContent(combinedAssets, texturesWithoutMetaFile);
} }
} }
@ -243,7 +243,9 @@ namespace Spine.Unity.Editor {
} }
#endregion #endregion
public static void ImportSpineContent (string[] imported, bool reimport = false) { public static void ImportSpineContent (string[] imported, List<string> texturesWithoutMetaFile,
bool reimport = false) {
var atlasPaths = new List<string>(); var atlasPaths = new List<string>();
var imagePaths = new List<string>(); var imagePaths = new List<string>();
var skeletonPaths = new List<PathAndProblemInfo>(); var skeletonPaths = new List<PathAndProblemInfo>();
@ -285,7 +287,7 @@ namespace Spine.Unity.Editor {
if (ap.StartsWith("Packages")) if (ap.StartsWith("Packages"))
continue; continue;
TextAsset atlasText = AssetDatabase.LoadAssetAtPath<TextAsset>(ap); TextAsset atlasText = AssetDatabase.LoadAssetAtPath<TextAsset>(ap);
AtlasAssetBase atlas = IngestSpineAtlas(atlasText); AtlasAssetBase atlas = IngestSpineAtlas(atlasText, texturesWithoutMetaFile);
atlases.Add(atlas); atlases.Add(atlas);
} }
@ -428,7 +430,7 @@ namespace Spine.Unity.Editor {
return arr; return arr;
} }
static AtlasAssetBase IngestSpineAtlas (TextAsset atlasText) { static AtlasAssetBase IngestSpineAtlas (TextAsset atlasText, List<string> texturesWithoutMetaFile) {
if (atlasText == null) { if (atlasText == null) {
Debug.LogWarning("Atlas source cannot be null!"); Debug.LogWarning("Atlas source cannot be null!");
return null; return null;
@ -469,8 +471,9 @@ namespace Spine.Unity.Editor {
for (int i = 0; i < pageFiles.Count; i++) { for (int i = 0; i < pageFiles.Count; i++) {
string texturePath = assetPath + "/" + pageFiles[i]; string texturePath = assetPath + "/" + pageFiles[i];
Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
if (SpineEditorUtilities.Preferences.setTextureImporterSettings) { bool textureIsUninitialized = texturesWithoutMetaFile != null && texturesWithoutMetaFile.Contains(texturePath);
SetDefaultTextureSettingsIfNew(texturePath, atlasAsset); if (SpineEditorUtilities.Preferences.setTextureImporterSettings && textureIsUninitialized) {
SetDefaultTextureSettings(texturePath, atlasAsset);
} }
string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
@ -546,27 +549,13 @@ namespace Spine.Unity.Editor {
return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase)); return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase));
} }
static bool SetDefaultTextureSettingsIfNew (string texturePath, SpineAtlasAsset atlasAsset) { static bool SetDefaultTextureSettings (string texturePath, SpineAtlasAsset atlasAsset) {
TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
if (texImporter == null) { if (texImporter == null) {
Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath)); Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath));
return false; return false;
} }
#if UNITY_2018_1_OR_NEWER
bool customTextureSettingsExist = !texImporter.importSettingsMissing;
#else
// unfortunately, importSettingsMissing is not available in Unity 2017,
// so we check if any settings deviate from Unity's default texture settings.
bool customTextureSettingsExist = texImporter.mipmapEnabled != true ||
texImporter.maxTextureSize != 2048 ||
texImporter.alphaIsTransparency != true ||
texImporter.wrapMode != TextureWrapMode.Repeat ||
texImporter.filterMode != FilterMode.Bilinear;
#endif
if (customTextureSettingsExist)
return false;
texImporter.textureCompression = TextureImporterCompression.Uncompressed; texImporter.textureCompression = TextureImporterCompression.Uncompressed;
texImporter.alphaSource = TextureImporterAlphaSource.FromInput; texImporter.alphaSource = TextureImporterAlphaSource.FromInput;
texImporter.mipmapEnabled = false; texImporter.mipmapEnabled = false;

View File

@ -129,8 +129,8 @@ namespace Spine.Unity.Editor {
public const float DEFAULT_MIPMAPBIAS = SpinePreferences.DEFAULT_MIPMAPBIAS; public const float DEFAULT_MIPMAPBIAS = SpinePreferences.DEFAULT_MIPMAPBIAS;
public const float DEFAULT_SCENE_ICONS_SCALE = SpinePreferences.DEFAULT_SCENE_ICONS_SCALE; public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE";
public const string SCENE_ICONS_SCALE_KEY = SpinePreferences.SCENE_ICONS_SCALE_KEY; public static float handleScale = SpinePreferences.DEFAULT_SCENE_ICONS_SCALE;
const string AUTO_RELOAD_SCENESKELETONS_KEY = "SPINE_AUTO_RELOAD_SCENESKELETONS"; const string AUTO_RELOAD_SCENESKELETONS_KEY = "SPINE_AUTO_RELOAD_SCENESKELETONS";
public static bool autoReloadSceneSkeletons = SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS; public static bool autoReloadSceneSkeletons = SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS;
@ -141,6 +141,7 @@ namespace Spine.Unity.Editor {
const string TIMELINE_USE_BLEND_DURATION_KEY = "SPINE_TIMELINE_USE_BLEND_DURATION_KEY"; const string TIMELINE_USE_BLEND_DURATION_KEY = "SPINE_TIMELINE_USE_BLEND_DURATION_KEY";
public static bool timelineUseBlendDuration = SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION; public static bool timelineUseBlendDuration = SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION;
static bool preferencesLoaded = false; static bool preferencesLoaded = false;
public static void Load () { public static void Load () {
@ -158,8 +159,7 @@ namespace Spine.Unity.Editor {
atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING);
textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING);
timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION);
handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE);
SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE);
preferencesLoaded = true; preferencesLoaded = true;
} }
@ -176,6 +176,7 @@ namespace Spine.Unity.Editor {
newPreferences.atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); newPreferences.atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING);
newPreferences.textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); newPreferences.textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING);
newPreferences.timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); newPreferences.timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION);
newPreferences.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE);
} }
public static void SaveToEditorPrefs(SpinePreferences preferences) { public static void SaveToEditorPrefs(SpinePreferences preferences) {
@ -190,6 +191,7 @@ namespace Spine.Unity.Editor {
EditorPrefs.SetBool(ATLASTXT_WARNING_KEY, preferences.atlasTxtImportWarning); EditorPrefs.SetBool(ATLASTXT_WARNING_KEY, preferences.atlasTxtImportWarning);
EditorPrefs.SetBool(TEXTUREIMPORTER_WARNING_KEY, preferences.textureImporterWarning); EditorPrefs.SetBool(TEXTUREIMPORTER_WARNING_KEY, preferences.textureImporterWarning);
EditorPrefs.SetBool(TIMELINE_USE_BLEND_DURATION_KEY, preferences.timelineUseBlendDuration); EditorPrefs.SetBool(TIMELINE_USE_BLEND_DURATION_KEY, preferences.timelineUseBlendDuration);
EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, preferences.handleScale);
} }
#endif #endif
@ -254,10 +256,10 @@ namespace Spine.Unity.Editor {
EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel);
{ {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
SpineHandles.handleScale = EditorGUILayout.Slider("Editor Bone Scale", SpineHandles.handleScale, 0.01f, 2f); handleScale = EditorGUILayout.Slider("Editor Bone Scale", handleScale, 0.01f, 2f);
SpineHandles.handleScale = Mathf.Max(0.01f, SpineHandles.handleScale); handleScale = Mathf.Max(0.01f, handleScale);
if (EditorGUI.EndChangeCheck()) { if (EditorGUI.EndChangeCheck()) {
EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale); EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, handleScale);
SceneView.RepaintAll(); SceneView.RepaintAll();
} }
} }

View File

@ -65,13 +65,27 @@ namespace Spine.Unity.Editor {
public static string editorPath = ""; public static string editorPath = "";
public static string editorGUIPath = ""; public static string editorGUIPath = "";
public static bool initialized; public static bool initialized;
private static List<string> texturesWithoutMetaFile = new List<string>();
// Auto-import entry point // Auto-import entry point for textures
void OnPreprocessTexture () {
#if UNITY_2018_1_OR_NEWER
bool customTextureSettingsExist = !assetImporter.importSettingsMissing;
#else
bool customTextureSettingsExist = System.IO.File.Exists(assetImporter.assetPath + ".meta");
#endif
if (!customTextureSettingsExist) {
texturesWithoutMetaFile.Add(assetImporter.assetPath);
}
}
// Auto-import post process entry point for all assets
static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
if (imported.Length == 0) if (imported.Length == 0)
return; return;
AssetUtility.HandleOnPostprocessAllAssets(imported); AssetUtility.HandleOnPostprocessAllAssets(imported, texturesWithoutMetaFile);
texturesWithoutMetaFile.Clear();
} }
#region Initialization #region Initialization
@ -80,14 +94,16 @@ namespace Spine.Unity.Editor {
} }
static void Initialize () { static void Initialize () {
if (EditorApplication.isPlayingOrWillChangePlaymode) return; // Note: Preferences need to be loaded when changing play mode
// to initialize handle scale correctly.
#if !NEW_PREFERENCES_SETTINGS_PROVIDER #if !NEW_PREFERENCES_SETTINGS_PROVIDER
Preferences.Load(); Preferences.Load();
#else #else
SpinePreferences.Load(); SpinePreferences.Load();
#endif #endif
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
string[] assets = AssetDatabase.FindAssets("t:script SpineEditorUtilities"); string[] assets = AssetDatabase.FindAssets("t:script SpineEditorUtilities");
string assetPath = AssetDatabase.GUIDToAssetPath(assets[0]); string assetPath = AssetDatabase.GUIDToAssetPath(assets[0]);
editorPath = Path.GetDirectoryName(assetPath).Replace("\\", "/"); editorPath = Path.GetDirectoryName(assetPath).Replace("\\", "/");

View File

@ -44,7 +44,6 @@ namespace Spine.Unity.Editor {
using EventType = UnityEngine.EventType; using EventType = UnityEngine.EventType;
public static class SpineHandles { public static class SpineHandles {
internal static float handleScale = 1f;
public static Color BoneColor { get { return new Color(0.8f, 0.8f, 0.8f, 0.4f); } } public static Color BoneColor { get { return new Color(0.8f, 0.8f, 0.8f, 0.4f); } }
public static Color PathColor { get { return new Color(254/255f, 127/255f, 0); } } public static Color PathColor { get { return new Color(254/255f, 127/255f, 0); } }
public static Color TransformContraintColor { get { return new Color(170/255f, 226/255f, 35/255f); } } public static Color TransformContraintColor { get { return new Color(170/255f, 226/255f, 35/255f); } }
@ -200,7 +199,7 @@ namespace Spine.Unity.Editor {
Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX);
Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale;
const float my = 1.5f; const float my = 1.5f;
scale.y *= (SpineHandles.handleScale + 1) * 0.5f; scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1) * 0.5f;
scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale);
Handles.DrawPolyLine(GetBoneWireBuffer(transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale))); Handles.DrawPolyLine(GetBoneWireBuffer(transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)));
var wp = transform.TransformPoint(pos); var wp = transform.TransformPoint(pos);
@ -218,7 +217,7 @@ namespace Spine.Unity.Editor {
Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX);
Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale;
const float my = 1.5f; const float my = 1.5f;
scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1f) * 0.5f;
scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale);
SpineHandles.GetBoneMaterial().SetPass(0); SpineHandles.GetBoneMaterial().SetPass(0);
Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale));
@ -235,7 +234,7 @@ namespace Spine.Unity.Editor {
Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX);
Vector3 scale = Vector3.one * length * b.WorldScaleX; Vector3 scale = Vector3.one * length * b.WorldScaleX;
const float my = 1.5f; const float my = 1.5f;
scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1f) * 0.5f;
scale.y = Mathf.Clamp(scale.x, -my, my); scale.y = Mathf.Clamp(scale.x, -my, my);
SpineHandles.GetBoneMaterial(color).SetPass(0); SpineHandles.GetBoneMaterial(color).SetPass(0);
Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale));
@ -425,13 +424,13 @@ namespace Spine.Unity.Editor {
} }
static void DrawCrosshairs2D (Vector3 position, float scale, float skeletonRenderScale = 1f) { static void DrawCrosshairs2D (Vector3 position, float scale, float skeletonRenderScale = 1f) {
scale *= SpineHandles.handleScale * skeletonRenderScale; scale *= SpineEditorUtilities.Preferences.handleScale * skeletonRenderScale;
Handles.DrawLine(position + new Vector3(-scale, 0), position + new Vector3(scale, 0)); Handles.DrawLine(position + new Vector3(-scale, 0), position + new Vector3(scale, 0));
Handles.DrawLine(position + new Vector3(0, -scale), position + new Vector3(0, scale)); Handles.DrawLine(position + new Vector3(0, -scale), position + new Vector3(0, scale));
} }
static void DrawCrosshairs (Vector3 position, float scale, float a, float b, float c, float d, Transform transform, float skeletonRenderScale = 1f) { static void DrawCrosshairs (Vector3 position, float scale, float a, float b, float c, float d, Transform transform, float skeletonRenderScale = 1f) {
scale *= SpineHandles.handleScale * skeletonRenderScale; scale *= SpineEditorUtilities.Preferences.handleScale * skeletonRenderScale;
var xOffset = (Vector3)(new Vector2(a, c).normalized * scale); var xOffset = (Vector3)(new Vector2(a, c).normalized * scale);
var yOffset = (Vector3)(new Vector2(b, d).normalized * scale); var yOffset = (Vector3)(new Vector2(b, d).normalized * scale);
@ -443,7 +442,7 @@ namespace Spine.Unity.Editor {
} }
static void DrawArrowhead2D (Vector3 pos, float localRotation, float scale = 1f) { static void DrawArrowhead2D (Vector3 pos, float localRotation, float scale = 1f) {
scale *= SpineHandles.handleScale; scale *= SpineEditorUtilities.Preferences.handleScale;
SpineHandles.IKMaterial.SetPass(0); SpineHandles.IKMaterial.SetPass(0);
Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, Matrix4x4.TRS(pos, Quaternion.Euler(0, 0, localRotation), new Vector3(scale, scale, scale))); Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, Matrix4x4.TRS(pos, Quaternion.Euler(0, 0, localRotation), new Vector3(scale, scale, scale)));
@ -454,7 +453,7 @@ namespace Spine.Unity.Editor {
} }
static void DrawArrowhead (Matrix4x4 m) { static void DrawArrowhead (Matrix4x4 m) {
float s = SpineHandles.handleScale; float s = SpineEditorUtilities.Preferences.handleScale;
m.m00 *= s; m.m00 *= s;
m.m01 *= s; m.m01 *= s;
m.m02 *= s; m.m02 *= s;
@ -470,14 +469,14 @@ namespace Spine.Unity.Editor {
} }
static void DrawBoneCircle (Vector3 pos, Color outlineColor, Vector3 normal, float scale = 1f) { static void DrawBoneCircle (Vector3 pos, Color outlineColor, Vector3 normal, float scale = 1f) {
scale *= SpineHandles.handleScale; scale *= SpineEditorUtilities.Preferences.handleScale;
Color o = Handles.color; Color o = Handles.color;
Handles.color = outlineColor; Handles.color = outlineColor;
float firstScale = 0.08f * scale; float firstScale = 0.08f * scale;
Handles.DrawSolidDisc(pos, normal, firstScale); Handles.DrawSolidDisc(pos, normal, firstScale);
const float Thickness = 0.03f; const float Thickness = 0.03f;
float secondScale = firstScale - (Thickness * SpineHandles.handleScale * scale); float secondScale = firstScale - (Thickness * SpineEditorUtilities.Preferences.handleScale * scale);
if (secondScale > 0f) { if (secondScale > 0f) {
Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.5f); Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.5f);

View File

@ -86,8 +86,10 @@ namespace Spine.Unity.Editor {
public const bool DEFAULT_AUTO_RELOAD_SCENESKELETONS = true; public const bool DEFAULT_AUTO_RELOAD_SCENESKELETONS = true;
public bool autoReloadSceneSkeletons = DEFAULT_AUTO_RELOAD_SCENESKELETONS; public bool autoReloadSceneSkeletons = DEFAULT_AUTO_RELOAD_SCENESKELETONS;
internal const float DEFAULT_SCENE_ICONS_SCALE = 1f;
public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE";
internal const float DEFAULT_SCENE_ICONS_SCALE = 1f;
[Range(0.01f, 2f)]
public float handleScale = DEFAULT_SCENE_ICONS_SCALE;
public const bool DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME = true; public const bool DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME = true;
public bool mecanimEventIncludeFolderName = DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME; public bool mecanimEventIncludeFolderName = DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME;
@ -98,7 +100,6 @@ namespace Spine.Unity.Editor {
#if NEW_PREFERENCES_SETTINGS_PROVIDER #if NEW_PREFERENCES_SETTINGS_PROVIDER
public static void Load () { public static void Load () {
SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE);
GetOrCreateSettings(); GetOrCreateSettings();
} }
@ -172,10 +173,10 @@ namespace Spine.Unity.Editor {
EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel);
{ {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
SpineHandles.handleScale = EditorGUILayout.Slider("Editor Bone Scale", SpineHandles.handleScale, 0.01f, 2f); var scaleProperty = settings.FindProperty("handleScale");
SpineHandles.handleScale = Mathf.Max(0.01f, SpineHandles.handleScale); EditorGUILayout.PropertyField(scaleProperty, new GUIContent("Editor Bone Scale"));
if (EditorGUI.EndChangeCheck()) { if (EditorGUI.EndChangeCheck()) {
EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale); EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, scaleProperty.floatValue);
SceneView.RepaintAll(); SceneView.RepaintAll();
} }
} }