Problem statement
I have a spine project imported in Unity and rendered in a prefab.
That project was recently updated and reimported in Unity.
No error from the importer:
skin_lot_3_ville_Atlas :: Imported with 5 material
Changes to 'Assets/Content/Spine/NPC/City/Lot3/skin_lot_3_ville.json' or atlas detected. Clearing SkeletonDataAsset: Assets/Content/Spine/NPC/City/Lot3/skin_lot_3_ville_SkeletonData.asset
After that, when the prefab assign that skeletonData into the SkeletonAnimation, it's triggering a flood of errors in the console when I run the game.
ArgumentNullException: Value cannot be null.
Parameter name: source
UnityEngine.Material..ctor (UnityEngine.Material source) (at <f7237cf7abef49bfbb552d7eb076e422>:0)
Spine.Unity.SkeletonRenderer.InitSpriteMaskMaterialsForMaskType (UnityEngine.Rendering.CompareFunction maskFunction, UnityEngine.Material[]& materialsToFill) (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:704)
Spine.Unity.SkeletonRenderer.InitSpriteMaskMaterialsOutsideMask () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:692)
Spine.Unity.SkeletonRenderer.AssignSpriteMaskMaterials () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:680)
Spine.Unity.SkeletonRenderer.LateUpdateMesh () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:566)
Spine.Unity.SkeletonRenderer.LateUpdate () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:459)
Spine.Unity.SkeletonAnimation.LateUpdate () (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonAnimation.cs:283)
Spine.Unity.SkeletonRenderer.Initialize (System.Boolean overwrite, System.Boolean quiet) (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonRenderer.cs:427)
Spine.Unity.SkeletonAnimation.Initialize (System.Boolean overwrite, System.Boolean quiet) (at ./Library/PackageCache/com.esotericsoftware.spine.spine-unity@6adfde3c0f/Runtime/spine-unity/Components/SkeletonAnimation.cs:188)
Hotel.Gameplay.NpcModel.<Rebuild>g__Resolve|39_0 (Spine.Unity.SkeletonDataAsset skeletonData) (at Assets/Content/Hotel/Gameplay/NpcModel.cs:230)
Hotel.Utility.AssetUtil+<>c__DisplayClass1_0`1[T].<LoadAsset>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] handle) (at Assets/Content/Hotel/Utility/AssetUtil.cs:31)
DelegateList`1[T].Invoke (T res) (at ./Library/PackageCache/com.unity.addressables@1.21.20/Runtime/ResourceManager/Util/DelegateList.cs:75)
UnityEngine.Debug:LogException(Exception)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at ./Library/PackageCache/com.unity.addressables@1.21.20/Runtime/ResourceManager/Util/DelegateList.cs:79)
UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate() (at ./Library/PackageCache/com.unity.addressables@1.21.20/Runtime/ResourceManager/Util/DelayedActionManager.cs:162)
After digging a bit and comparing to other skeleton it seems to be caused by an empty material in the material list of the SkeletonAnimation
Additional Info : There's a Skeleton Render Separator added to the SkeletonAnimation prefab for the characters. In the prefab, the SkeletonAnimation has mask interaction outside mask set.
The previous version of the spine project did not trigger any error. The difference between the previous one and the one causing the errors is a change from spine 4.1.23 to 4.1.24 and the project is more complex than previous one.
Prefab component: SpineAnimation, MeshRenderer, MeshFilter, Skeleton Render Separator, Custom Script, Box Collider
The code I used to swap the SkeletonData:
skeleton.skeletonDataAsset = skeletonData;
skeleton.initialSkinName = SkinName;
skeleton.Initialize(true, true);
Note that this code was working OK with the previous version of the project.
As I could not solve the issue, I removed all Spine related scripts from the prefab and added them using code. The code above became:
skeleton = SkeletonAnimation.AddToGameObject(gameObject, skeletonData);
GetComponent<MeshRenderer>().sortingOrder = 30;
var slot1 = skeleton.Skeleton.FindSlot("Bras_OL");
var slot2 = skeleton.Skeleton.FindSlot("Jambe_UL");
skeleton.separatorSlots.Clear();
skeleton.separatorSlots.Add(slot1);
skeleton.separatorSlots.Add(slot2);
skeleton.Skeleton.SetSkin(SkinName);
_separator = SkeletonRenderSeparator.AddToSkeletonRenderer(skeleton);
_separator.enabled = false;
Using that method, the materials in the mesh renderer don't have an empty value and everything is working correctly but it's less convenient and I can't tweak the prefab using the inspector anymore.
I don't know if the problem came from a feature we used in the spine project or from the upgrade from 4.1.23 to 4.1.24.
Any help would be appreciated.
Runtime information
tried with
Spine 4.1.24
spine-unity Runtime 4.1.21
spine-csharp Runtime 4.1.0
Spine Universal RP Shaders 4.1.21
and the latest to date:
spine-unity Runtime 4.1.27
spine-csharp Runtime 4.1.2
Spine Universal RP Shaders 4.1.40