• Unity
  • Sprite attaching to skel sometimes shows black

Ok cool, yea I figured... but it was easier to do a little write-up than pack up a sample project haha. I'll work on getting you something though, thanks for the attention so far!

A little more insight into those thoughts:

  • BCoroutine.WaitAndPerform just kicks off a coroutine yea. Normally if that second param is >= 0, it'll do a WaitForSeconds, then do the action. If you pass in -1 like I'm doing though, it just does a yield return null (waits 1 frame), then does the action.
  • _carryable.DisableRenderingForSpineAttachment(true); is just disabling the sprite on the in-game pickup object, since we're resource-loading a new sprite to attach to the skel, and we don't want the pickup's image showing on screen twice while the agent is holding it. They're separate sprites, and separate objects - I'm pretty comfortable saying that couldn't be interfering.

EDIT: Hmm just had a quick thought - would it be problematic if the skel was being disabled or enabled in the same frame that the sprite was getting attached? That would be possible in rare cases if the agent was changing face direction in the same frame that they were picking something up, since we use separate skels for their different face directions.

To add little more detail there, for face directions the agent isn't in we disable both the MeshRenderer and the SkeletonAnimation components.

An enabled face direction:

A disabled face direction:

(p.s. I don't know how to make my reply show as a new message! it just keeps showing as an edit to my last message... hopefully this notifies you as if it's a reply haha)

Related Discussions
...

Regarding the BCoroutine.WaitAndPerform - this seems ok then.

Hmm just had a quick thought - would it be problematic if the skel was being disabled or enabled in the same frame that the sprite was getting attached?

Hm, maybe this together with the call to _carryable.DisableRenderingForSpineAttachment(true) could do some harm - I don't know, but I still would guess that it has something to do with one thing being disabled (or set to null) in the wrong order and therefore too early.

If breakpoints can't be set reasonably, I would augment the whole code with a lot of print statements like "In Method X part 1" if there are no null-checks failing at all. Then pause as soon as the problem has occurred and then check if you can find some missing/unexpected/out-of-order calls logged, etc.

Unfortunately I still can't help too much without the repro package I fear..

PS: You should perhaps refill the red and blue pixels in your Unity version 😉.

Cool cool, just wanted to throw that random thought out while I had it, in case it triggered something you knew haha.

PS: You should perhaps refill the red and blue pixels in your Unity version 😉.

Oh haha, I just have it set to change green when in play mode, so I don't do anything stupid like make a bunch of adjustments in the inspector, forgetting the game is running haha.

Hehe, yes - the different play mode color scheme is a very good idea in general, I don't want to know how many changes have been lost by Unity users in the past that way! 🙂

Major breakthrough! I was putting together that sample project for you guys and was doing some testing in it to make sure I could actually repro the issue. It took awhile... the issue is really rare (maybe 1 in 200-300 attachments). But once it did happen I decided to take a peek at the runtime materials on the skeletons, and I think I found the issue! It looks like the defective materials are using the "Standard" shader, instead of the "Spine/Skeleton" shader. I have no idea why it would be getting the wrong one yet, but definitely progress.

Here's a vid of me poking around at runtime (apologies again for my green play mode tint!). The vid capture doesn't see any popout / dropdown menus, so there are some dead moments in there where you can't see what I'm doing (e.g. 0:45-1:00 can pretty much be skipped), but you'll see around 1:30 I manually change the defective material from the "Standard" shader to the "Spine/Skeleton" shader, and all is well again.

https://www.dropbox.com/s/s6adhrz43nimq8h/issue%20is%20wrong%20shader.mp4?dl=0

While I continue to get this sample project built for you, any ideas off the top of your head why it would randomly assign the wrong shader? Or maybe any ways to force it?

Oh, this is interesting! Thanks very much for figuring this out - I don't yet have any idea why that happens, but now I know what to search for!

Having seen everything in motion now: OMG - your game looks so cute! Awesome work! 🙂

And no need to apologize for the green editor tint at all, I was just joking! 🙂

Haha well thank you so much, very kind of you to say 🙂 We'll be showing it at GDC if you'll be there and want to check it out!

Do you have a secure/private way for me to send you the project?

Very cool! Unfortunately I will not be at GDC (since I'm living in Europe) - will be attending Reboot Develop on the other hand, but I guess it's unlikely you will exhibit there.. Anyway - we wish you all the best for the expo!

Regarding sending the project securely:
Please send it to contact@esotericsoftware.com, I can assure you that it will only be used for bugfixing purposes.

Sent!

4 dana kasnije

Some things that I found out:

First I could not reproduce the problem in Unity 2018.3.0f1, then upgraded to f2 and instantly could! Maybe related to the unity version and either some implicit behaviour change, or a bug in a Unity version - maybe you could test that with different Unity versions?

I can confirm that the shader or material is not null. After some time I got this error message, but no wrong Sprite (at least I did not see any).

Assertion failed on expression: '!m_CoroutineEnumeratorGCHandle.HasTarget()'
UnityEngine.Coroutine:Finalize()

One more very interesting thing: I just closed unity and reopened it - et voila, the problem occurred instantly in the first 10 attachments (or the very first? don't know), but only if I don't attach the debugger (so it's definitely a timing issue..)!


I found the cause!

The problem is with your 4 movement directions having SpineAnimations for each direction, but all start disabled and having no Material assigned (maybe that is cleared by unity upon save? I don't know) except for the FrontAnimation version - then you have to pick up one of your spritelings before they turned in all directions and throw them at a target resource, then when the method attachSpriteToSkeleton() below is called, the _mesh for the disabled directions has no materials assigned in the inspector and will get the default material assigned implicitly upon calling the method:

You can add the following code to trap the error case:

in BAgentAnimator.cs:

void attachSpriteToSkeleton(SkeletonAnimation _skelAnim, MeshRenderer _mesh, Slot _slot, Sprite _sprite)
   {
      // Add this on top of the method to catch the problem case:
      if (!_mesh.material.shader.name.Contains("Spine"))
         Debug.LogError("shader with different name found!" + _mesh.material.shader.name);

So long story short: You have to make sure that the material gets either saved or is assigned properly before attaching the Sprite.


I noticed that the material is cleared by the SkeletonAnimation when the MeshRenderer is deactivated. Since this is undesired behaviour, I have quickly fixed it. So you should be able to update the Spine unitypackage and enable and then again disable your MeshRenderers, then all material references should be restored and kept intact, then apply you prefabs again.

You can download the latest unitypackage here as usual:
Spine Unity Download

Please let me know if this solved your problem.

Awesome thank you so much! Implemented these changes and so far so good! Since it's rare I'm still gonna keep an eye out, but we have what we need now to track it if it happens to pop back up 🙂 You guys are the best!

Glad we could make it work 🙂!

Actually it was not rare when I hurried up to grab the spriteling quickly before he turns. After I knew what I had to do, I had about 70% chance of reproducing it instantly.

Ah yea, good point! With that in mind I think we're all set!