- Home /
How to hide a sprite when they are in shadow using Unity 2D Light System?
I want to know how to hide a character when they are in shadow when am using Unity 2D Light system. Currently I try to hide a character by playing with the shadow, but no matter what I do the character is still rendered as a black body. Which is not the effect am going for.
Here is what I mean
As you can see, I have the shadow intensity maxed up (red square has the shadow caster 2d), but the green square is still lit when in the shadow and even when its outside the light spot. I would like in this case to hide the part in the shadow completely put still show the part in the light.
Is there some setting am missing or something? or is there a shader where i can apply to green square so its hidden when in the shadow?
I really been looking around for answers but cant find anything, am really desperate here, any help would be appreciated. Thank you in advance.
Answer by bolagadalla777 · Jul 23, 2021 at 03:01 PM
@Mirmukhsin yea I was able to find a solution to it and I posted it here if you want to skip reading everything. The solution basically edits the Sprite-Lit-Default
script so that it takes into account the luminosity of the object, basically how much light is hitting the sprite. With that it will calculate the amount of light hitting the sprite and apply either a transparent texture or a lit texture. So if you look at the image above, it will the dark area would become transparent and the lit area (with the gradient fallout) will stay the same.
Same feature as in the game Among Us (I was trying to make a clone at the time). However I wasn't the one who came up with this solution, someone from the Unity discord server helped me out. I also posted this solution on stackoverflow here.
Now there are some flaws (maybe not for your case). One, since it does some calculation using the Light system, if there is no light in the scene (and I mean anywhere in the scene it can even be on the other side of the map, it will still use that light to calculate the luminosity of the object, basically you must be using lights for this to work) the texture will appear completely visible, unlike when you apply the Sprite-Lit-Default
to it and it becomes dark. Two, you have to use good amount of lighting, light intensity, meaning if you make it too intense the light will "bleed" into the shadow area making it slightly lit, now again you can use this as a feature or it might be the deal breaker for you, but this is what I got.
First the person who helped me with this created a .hlsl
file, now this is the same file used for the CombinedShapeLightShared.hlsl
can be found here, but with added functionality to calculate luminosity, Unity uses this to calculate lighting. He named it CombinedShapeLightSharedHidden.hlsl, now this is important that the name stays the same or else you have to change the name to the file and everywhere else you see this name. It seems when I try to type code here for .hlsl
it messes up the markdown because of the #
s. So you can go to the stackoverflow post I posted and get it from there
The second file he created was HideInShadow.shader, and this is the same thing as the Sprite-Lit-Default.shader
that you would use for the light system but with added functionality, it will basically call the function from the previous file that calculates the luminosity of the texture and apply it to the texture. Again, its being weird with me with writing code, you can find the code in stackoverflow same post.
Then you create a material to apply the HideInShadow.shader
to and then apply that material to the objects you want to be invisible in the shadows.
Now keep in mind these 2 things. One, don't change the names unless you change them everywhere else. And two, both files that were create must be in the same folder. Unless you know what you are doing. FEEL FREE TO POST ANOTHER SOLUTION IF YOU FOUND ANY
Thanks, mate, it worked. However, I had to tweak it slightly because the objects were appearing as if the light was co$$anonymous$$g from the opposite direction (I am using Point light). If anyone stumbles upon it, let me know!
Hi @Mirmukhsin , were you able to find the solution , I am also seeing same errror
@Mirmukhsin are you able to post the edit here? I might reuse the code later and come upon the same issue. And I don't want to suffer the same way again. it was hell to get an answer to this question.
Thank you in advance.
Hi @bolagadalla777 ,
Thank you for this solution , but for some reason , it is working weirdly , Here is what i am getting if i use sprite-lit default i get black for rest of object , but with Code given , it is working in scene, but in-game scene ,it is not even visible , is there a way I can contact you directly please in discord?
@Gzone I can try to help you on discord like you said, but please keep in mind that this wasnt my code or anything, someone helped me with it on Discord as well. However I can try my best to help you and everything. Here is my discord tag Azeil#3500 Let me know when you add me, I got to change the ID afterward.
Answer by barry1251 · Feb 24 at 07:49 AM
It took me a while to figure it out, and tbh I wasn't the one who figured it out, I got help from someone on the Unity Discord server. He went into the Sprite-Lit-Default and changed some code that accounts for the luminance, now I don't know anything about shader programming so I won't be able to explain it much. But he created a .hlsl file with the same functionality as the CombinedShapeLightShared.hlsl file which Unity uses to calculate lights, can be found here, but added some argument that accounts for luminance. Now here are the file content of both the .shader file and the .hlsl file.
bruh...why are you taking what i said in the stackoverflow and just posting it with a random link?