Pontus

Hi,

I noticed that over 50 minutes were spent in PreprocessSpinePrefabMeshes every time I build. We're using Unity 2020.3.32f and spine-unity-4.1-2022-07-01.

This function seems to open every prefab in the project (and dependent packages?) and scan for objects with SkeletonRenderer and MeshFilter components in order to remove shared meshes. Adding an hour to the build time in local builds is killing productivity. The feature is enabled by HAS_ON_POSTPROCESS_PREFAB but we are unable to disable it because it is forced like this
#if UNITY_2020_2_OR_NEWER
#define HAS_ON_POSTPROCESS_PREFAB
#endif
We could of course start modifying the spine source to strip it out, but it sounds like this feature should be active for live builds at least, to not waste package space and memory. Is there no faster way to do it?

Best Regards,
Pontus
Pontus
  • Posts: 5

Harald

This is some very substantial overhead, we are very sorry for the troubles, and thanks for reporting!

We have re-opened the issue ticket below and will do our best to improve the situation:
https://github.com/EsotericSoftware/spine-runtimes/issues/1273
User avatar
Harald

Harri
  • Posts: 4332

Pontus

Thank you, let me know if I can help out in some way. Looking forward to seeing what you come up with!

Best Regards,
Pontus
Pontus
  • Posts: 5

Harald

Thanks for the offer, I will let you know. :)
User avatar
Harald

Harri
  • Posts: 4332

vhristov

Actually I am surprised it even compiles for the asset bundles (TBH I am not very familiar with thems), but AFAIK the issue which required PreprocessSpinePrefabMeshes was that the meshes were getting inside the build, and when they are marked as DontSaveInEditor/Build there was a build error (see https://github.com/EsotericSoftware/spine-runtimes/pull/1937 ). From what I have read the build preprocessor is not called when building asset bundles, so the meshes shall all be getting in the bundles, which shall cause a build error (correct me if I am wrong)?

On the other hand I am pretty sure that this change was not needed that much for the prefab override itself, but it was more related to the prefab thumbnails preview (see https://github.com/EsotericSoftware/spine-runtimes/commit/c2cbdc57b710eec6468ae3f7c4b90266d2cc7388 )
I am not currently 100% sure about how the prefab override and the thumbnail are exactly connected
I believe the original discussion was here:
Two questions: Prefab thumbnail & SkelRend inspector update

I am thinking about a possible optimization here (which is not yet completed in my head):
Can we use some kind of a label to find only the prefabs that really needs modification (using for example FindAssets("l:PrefabsWithSpineSkeletonInThem")?
(This is based on the assumption that the huge overhead Pontus is seeing is not because there are millions of prefabs with spine that need patching, but because there are a lot of prefabs and just a minor portion of them are having skeletons in them)
vhristov
  • Posts: 49

PotatoVeg

vhristov wrote:Actually I am surprised it even compiles for the asset bundles (TBH I am not very familiar with thems), but AFAIK the issue which required PreprocessSpinePrefabMeshes was that the meshes were getting inside the build, and when they are marked as DontSaveInEditor/Build there was a build error (see https://github.com/EsotericSoftware/spine-runtimes/pull/1937 ). From what I have read the build preprocessor is not called when building asset bundles, so the meshes shall all be getting in the bundles, which shall cause a build error (correct me if I am wrong)?
I have been using Addressables for a long time now and I have never had any build error such as you describe regardless how I built my Addressables (locally or to remote).

Perhaps for the original AssetBundles system its acting different? :think:
PotatoVeg
  • Posts: 4

vhristov

PotatoVeg wrote:
I have been using Addressables for a long time now and I have never had any build error such as you describe regardless how I built my Addressables (locally or to remote).

Perhaps for the original AssetBundles system its acting different? :think:
Does this mean you have removed the prefab cleanup code and you have enabled the prefab override option to enable ?

Maybe I wasn't clear enough but I don't have spine prefabs in neither asset bundles, nor in addressables, the issue on my side was with a regular build, with prefab override fix enabled. I was just surprised it works for adressables (maybe I am wrong and the clean up is also performed on these too)

I'll try to create an addressable with spine on my side to see what is going on when building them and if it requires or not any cleanup.

P.S.
It seems my initial answer was on the wrong thread and was supposed to go on BuildPlayerWindow.OnGUI.mouseUp during build WebGL, but because they are pretty much the same I have mismatched them...


Update:
I were unable to reproduce any of the build issues I was facing previously, no matter how hard I tried to break the current code... This includes both regular build and addressables. I am starting to wonder if there was some change in unity since 2020.x or there was some change in spine runtimes (which I cannot find) that is removing the don't save in editor/build flag... Does anything rings a bell to someone?
vhristov
  • Posts: 49

Pontus

(This is based on the assumption that the huge overhead Pontus is seeing is not because there are millions of prefabs with spine that need patching, but because there are a lot of prefabs and just a minor portion of them are having skeletons in them)
The project has just shy of 5000 prefabs, and I believe most of them do not have SkeletonRenderer components. I didn't profile it, I can if you think it's necessary, but I think it's reasonable to expect that loading a prefab can take on the order of hundreds of milliseconds on a modern machine, so if we do it 5k times it doesn't strike me as odd that it could add up to the hour mark.
Pontus
  • Posts: 5

vhristov

Ok, Finally managed to reproduce the issue from before:
An asset is marked with HideFlags.DontSave but is included in the build:
Asset: 'Assets/Prefabs/Characters/BaseAlly_Hero.prefab'
Asset name: Skeleton Prefab Mesh "Bullet"
(You are probably referencing internal Unity data in your build.)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
It happens in every version i tested (including 2022.1 and 2021.3).

The changes I did for the test are located here:
https://github.com/vhristov/spine-runtimes/tree/4.1-hideflags-test-brokenbuilds

My tests seems to reproduce the same problem even in addressables... but I am not 100% sure if I am building the them properly. Can someone give it a try with addressables/asset bundles and check if it is reproduceable in this case too?
(one might need to reimport some spine prefabs for the change to take effect, before trying to build)

EDIT WARNING: DO A BACKUP OR USE GIT WHEN TESTING THE ABOVE!!! IT COULD BE DESTRUCTIVE!!!
vhristov
  • Posts: 49

Harald

FYI: we have just added a Spine Preferences parameter to disable the timewise costly pre-processing step. This will at least allow the situtation to be improved until it's properly resolved.

From the changelog:
* Added Spine Preferences setting Prefabs - Optimize Preview Meshes. When enabled, Spine prefab preview meshes will be removed in a pre-build step to reduce build size. This increases build time as all prefabs in the project will be processed. Defaults to false to not slow down builds substantially every time.

A new 4.1 spine-unity package has been released:
spine-unity Download
User avatar
Harald

Harri
  • Posts: 4332

Pontus

Hi Harald,

Thanks a lot for the quick fix, we will be sure to give it a try!

I have a few questions about it.

What is the potential downside of leaving this preference turned off?
In what situations should it definitely be turned back on?

I'm guessing you'll say that for official/live builds we should definitely keep it on, and that brings me to my next question. Is it possible to override this flag from the Unity command line so it can be a build flag?

Thanks again!
Pontus
  • Posts: 5

Harald

Pontus wrote:What is the potential downside of leaving this preference turned off?
The downside is that the skeleton mesh vertices will be part of your game build, making the build size slightly larger than it needs to be. However, it is likely that this will not matter as much compared to the size of your textures. Also, it could add a slight unnecessary loading overhead when additional data needs to be de-serialized. I doubt that this loading time overhead will have any measurable impact though.
In what situations should it definitely be turned back on?
I'm guessing you'll say that for official/live builds we should definitely keep it on [..]
Yes, you might want to enable this setting once before making a final build of your game that is released on your target store. This might slightly reduce the download and installation size.
Pontus wrote:and that brings me to my next question. Is it possible to override this flag from the Unity command line so it can be a build flag?
I see two ways to achieve this:
  1. Prepare two versions of the SpineSettings.asset file (IIRC by default located in Assets/Editor) in which the Spine-relevant settings are stored. Before triggering the build, copy the desired settings file over.
  2. Use c# build scripts as described here and call your own build method which sets up these Spine settings. Then call it like e.g. /Path/To/Unity -quit -batchmode -executeMethod YourAndroidBuilder.ProductionBuild.
User avatar
Harald

Harri
  • Posts: 4332

Pontus

Thanks for the additional hints! Will let you know how the testing goes.
Pontus
  • Posts: 5


Return to Unity