• RuntimesUnity
  • Ghost and Unity Layers

Hi Harald,

I have a bit of a unique situation, I set all my Spine renderers to a sorting layer called ART.

I don't let the camera renderer anything on the layer DEFAULT, to reduce the amount of things being renderered.

As a result I notice Spine's ghost shader won't appear now, because I guess it's set to the sorting layer DEFAULT? 🤔

I was checking out the SkeletonGhost.cs script and noticed this line 155:
pool[poolIndex].Initialize(meshFilter.sharedMesh, materials, color, additive, fadeSpeed, meshRenderer.sortingLayerID, (sortWithDistanceOnly) ? meshRenderer.sortingOrder : meshRenderer.sortingOrder - 1);

Is meshRenderer.sortingLayerID the argument that is controlling the layer visibility? If it is, do you know if it's possible to update that via code at runtime? (change the sorting layer ID to ART) I guess I could hack this script, but I don't think it's the best way to go about it?

Can you advise? 🙂
Thanks!

Related Discussions
...
  • تم التحرير

Actually I don't think it has anything to do with the sorting layer ID

I set the culling mask to everything and the spine ghost doesn't appear.

Any ideas Harald? 🤔 Is it because ghost only works in SRP? (I'm on URP)


I followed along with the video, but couldn't get the ghosting effect to appear.

Thanks for the help


Hi Harald,
Following up with more tests. I made a brand new project and ghost works, but only for SRP. 😢

Is there any chance we could URP support? It's a really cool effect.

@IndieDoroid At first I was a bit confused since you said SRP which usually stands for Scriptable Render Pipeline, but I assume by SRP you meant Standard Render Pipeline. 🙂

Anyway, unfortunately I could not reproduce the issue in Unity 2020.3 when either using the URP 3D or 2D renderer by assigning the provided Example URP Asset or Example 2D URP Asset as Render Pipeline Asset. Everything was rendered as expected. Which Unity version are you using?

    Hi Harald

    Yea Unity and their many acronyms .. I should have just wrote standard render pipeline 😅

    Oops forgot to mention that. 😓 I'm on Unity 2021.3.24f1

    ...message editing expired while I was typing. 🙄

    Hi Harald

    hmm.. I just created a new URP project and the skeleton ghost works there.. ok something else must be happening with the main project. 🤔

    Also another thing I noticed is that there is no warning about spine 4.0 incompatibility with this new URP project.

    I wonder if that has anything to do with it?

    Because on the main project, whenever I re-import the libraries I always get warning pop ups saying some spine example files being version 4.0 and weren't imported correctly. (because I updated all the spine files and runtimes to version 4.1)

    I'll do a bit more testing and get back to you.
    Thanks for the confirmation!

      IndieDoroid Because on the main project, whenever I re-import the libraries I always get warning pop ups saying some spine example files being version 4.0 and weren't imported correctly. (because I updated all the spine files and runtimes to version 4.1)

      Then I assume that you then did not cleanly remove the 4.0 runtime before installing the 4.1 runtime (as described here), and thus have some leftover 4.0 files remaining which trigger the warning. Unless you have modifed the spine-unity runtime files, I would recommend removing your potentially "mixed" 4.0 / 4.1 runtime again and installing the latest version of the 4.1 runtime cleanly. As always, backup your project first, just in case anything goes wrong or if you forgot about some modifications you did to the runtime.

        Harald
        Thanks Harald. Everything works now. I re-installed the runtime and deleted all the older Spine files using ver 4.0

        @IndieDoroid Glad to hear you've figured it out, thanks for getting back to us!

        15 أيام لاحقا

        Hi Harald
        Ok the issue came back again. I was wrong with my previous reply.

        I found out what was the cause. It's indeed because Spine Skeleton Ghost only renders to the Default layer. 😥

        Could you please suggest how I could set the Skeleton Ghost to render on another layerID? I made a movie so you can see what I mean.

        Sorry for the trouble and thanks again for your continued help 🙂

        @IndieDoroid SkeletonGhost spawns GameObjects programmatically here, then sets the GameObject's hide flags to hide them in the hierarchy here. So you just need to change the layer of the hidden spawned ghost GameObjects accordingly.

        Thanks Harald,

        I'm not quite sure what that code is doing, but I'll give it a try.

        If I hack this script, will it get overridden when a new Spine runtime is installed? 🤔

        • تم التحرير

        Thanks Harald,

        I'm not quite sure what that code is doing, but I'll give it a try.

        If I hack this script, will it get overridden when a new Spine runtime is installed? 🤔 -- I guess the fix is to use and save a different iteration of the script.

        --UPDATE--
        Ok got it working! I just added a line to change each spawned game object layerID.

        I also changed this. Hopefully that doesn't do anything nasty to the script.
        const HideFlags GhostHideFlags = HideFlags.None;

        Just out of curiosity, what is the benefit of using the HideFlags variable\const? .. from what I can see, it just makes it harder to debug the hierarchy 😵‍💫

        Also I read online that getcomponent() isn't suggested to be run at runtime? Best to keep it in Awake()\Start()? Is it ok to keep running all the time?
        pool[i] = go.GetComponent<SkeletonGhostRenderer>()
        I use the ghost script whenever a power up is used, which is frequently. 🤔

          oh nevermind, it doesn't get run all the time! got confused.. 🥴

          IndieDoroid If I hack this script, will it get overridden when a new Spine runtime is installed? 🤔 -- I guess the fix is to use and save a different iteration of the script.

          If you modify the original script, then yes, you might accidentally override your changes. You could however easily just create a copy of this example script (named differently) an adjust it to your needs. The scripts in the Spine.Unity.Examples namespace are as reference for your own implementation. They are not a generic solution which covers all use cases.

          IndieDoroid I also changed this. Hopefully that doesn't do anything nasty to the script.
          const HideFlags GhostHideFlags = HideFlags.None;

          It will just no longer hide it in the hierarchy, as the name implies.

          Just out of curiosity, what is the benefit of using the HideFlags variable\const? .. from what I can see, it just makes it harder to debug the hierarchy 😵‍💫

          This line is for hiding the many ghost renderer instances (10 per skeleton ghost) in the hierarchy. Otherwise it would be cluttering the hierarchy window with lots of entries.

          IndieDoroid Also I read online that getcomponent() isn't suggested to be run at runtime? Best to keep it in Awake()\Start()? Is it ok to keep running all the time?
          pool[i] = go.GetComponent<SkeletonGhostRenderer>()

          I use the ghost script whenever a power up is used, which is frequently. 🤔

          oh nevermind, it doesn't get run all the time! got confused.. 🥴

          Yes, it's run only in Start. In general it's only an example component, if you dislike anything, please change it accordingly (in your own copy of the script).

            Harald If you modify the original script, then yes, you might accidentally override your changes. You could however easily just create a copy of this example script (named differently) an adjust it to your needs. The scripts in the Spine.Unity.Examples namespace are as reference for your own implementation. They are not a generic solution which covers all use cases.

            Yea, that's what I did. 🙂I had to also make a copy of SkeletonGhostRenderer.cs it seems.

            Harald This line is for hiding the many ghost renderer instances (10 per skeleton ghost) in the hierarchy. Otherwise it would be cluttering the hierarchy window with lots of entries.

            Now that you mention this.. I can see the benefits of it. I'm going to figure out how to incorporate this into my other scripts. 😁

            Thanks for the help Harald!

              IndieDoroid I had to also make a copy of SkeletonGhostRenderer.cs it seems.

              I don't see why that is necessary, but you might have your reasons 🙂.

              IndieDoroid Now that you mention this.. I can see the benefits of it. I'm going to figure out how to incorporate this into my other scripts. 😁
              Now that you mention this.. I can see the benefits of it. I'm going to figure out how to incorporate this into my other scripts. 😁

              Thanks for the help Harald!

              🙂 Glad it helped.

                Harald I don't see why that is necessary, but you might have your reasons 🙂.

                Unity was telling me there were two versions of the same script even though I made a copy of SkeletonGhost.cs -- I narrowed it down to namespace Spine.Unity.Examples. I tried to remove the .Examples, but the duplicate SkeletonGhost script wasn't able to find SkeletonGhostRenderer.cs (it'd only work if I also remove .Examples from SkeletonGhostRenderer.cs) ...

                Anyways its probably confusing.. but everything works now. Thanks again

                • تم التحرير

                Hi Harald,

                So I dove deeper into the GhostSkeleton script. It's pretty interesting how the script functions. I swapped out the Ghost shader for Spine's Unlit shader, it created some cool results.

                I wanted to adjust the render queue because Unity's depth blur was blurring the object pooled ghost mesh renderer. (This undesired blurring also happens even if I use the ghost shader)

                I added line 176 in the SkeletonGhost.cs script, but it doesn't seem to update the new material at runtime. The goal was to have the render queue become alpha test with -100 offset.

                My guess is that I think it might have to do with the fact the Spine shader uses the render queue offset variable. Is that correct? If so how do we access that at runtime? 🤔

                Thanks for the help Harald. Hope you don't mind diving deeper into this subject.

                • تم التحرير

                Oh nevermind. fixed it. God I suck at coding 🤦‍♂️

                I needed to put it outside of the ghostMat block