Script for generating ShadowCaster2Ds for Tilemaps

I got it to work!
I had to create a new Material. The one I already had was created before I set the custom pipeline asset as my graphics, and Unity did not like that. After creating a new one, and upping the shadow intensity on the lights, it started working perfectly!

1 Like

Thanks for the script, works perfectly!

1 Like

Hi, I would like to report a bug. Basically this will never work if the tilemap is a complete square, much like this

7148365--855496--upload_2021-5-17_21-56-41.png

If the brown parts are walls, lights within the walls can never be seen. This was a big problem for me that I did not realise because literally my whole map was enclosed in one big square of walls.

Right now I found out that removing ANY tile to break the wall will result in the shadow casters working properly. I do not think there is a workaround for this from the script as the paths are identical to the composite colliders, and I do not think we can adjust the composite colliders.

One potential fix, which I may attempt, is to do a preprocessing before the game starts to try and break up such squares by placing it in a different tilemap. not completely sure of it yet though.

EDIT: Example below:
7148365--855514--upload_2021-5-17_22-27-36.png
There is a light source inside but it is not working because the whole shape is treated as one big shadow caster.

Hi hkplay, thank you for your report. I cannot think of a solution right now but, as an idea for now, do you really need the exterior walls to cast shadows? Are those shadows projected somewhere? Would it be possible that you put the perimeter in a different tilemap without shadow casters?

Hello ThundThund,

First of all I want to thank you for all the work you have done for the tilemap shadows! You are a champion, this was exactly what I was looking for.

Currently I am having an issue that I do not know how to describe, if I have just a single block, or two blocks the shadows look fine… but I am generating random patterns of walls (using composite collider on those walls), but for some reason there are many shadows being casted? It looks really odd. I have attached a short gif of my player moving around (to really see how the shadows move), and also a picture with no shadows.

P.S: The ONLY light in the scene is a point light centered around the player (Why are there these random shadows that look like there is a light coming from the corners of the map?)

short video of my character moving around:

Thank you, I’m glad it’s being useful for many people.
Could you please share a capture of what shape do the ShadowCaster2Ds attached to the tilemap have?

When I highlight the 2nd shadowcaster object it looks like it perfectly outlines the walls, attached images below…

EDIT: Oh, also figured out how to disable the renderer. I will post a 4th image where you can see the outline much more clearly.

EDIT 2: I think I have found the problem. There are walls all around the player that close up the whole area. If I remove those walls the shadows work perfectly, I think this is the same issue another user posted here on this post.

EDIT 3: Confirmed that if I remove a single block from the outer wall the shadows work perfectly.




Hello, have you ever found a solution to this issue? I am having the same problem.

Ah ok, so you have a closed tilemap. That’s a known issue. I haven’t worked on a solution yet.

The problem is that the closed shapes that the composite collider generates in, for example, a ring-shaped tilemap, are 2 overlapping convex meshes that enclose the point light.
The black area is the part where the light passes the stencil test.

7220347--868285--upload_2021-6-9_2-24-4.png

I think for now the solution I will do is destroy a single piece of wall from the corner, generate the shadows, and then place the tile back through the script. Thanks for the update though!

Hello again ThundThund,

I had a quick question, I have been trying for a very long time to do this but I can’t. How can I call the method that is called when you press the button in the editor: Tools → Generate Shadow Casters. I basically want to be able to do this through a script.

If you were to generate the shadows through another script, how would you do that? Could you write a short example.

Thanks in advanced!

I’ve added the implementation of a component to the main post.
It includes a small improvement in the shadow caster generator code, the line “component.Update();” which forces it to update the mesh of the shadow caster immediately.

I also modified the #if UNITY_EDITOR blocks in the shadow caster generator.

I think you have a bug in the current version of the code:
you are calling GenerateTilemapShadowCasters as if it has a CompositeCollider2D and a bool parameter but you only define it on just a CompositeCollider2D parameter

see line 118:

public static void GenerateTilemapShadowCasters(CompositeCollider2D collider)

and lines 102, 86 and 75

GenerateTilemapShadowCasters(collider, selfShadows);
GenerateTilemapShadowCastersInEditor(colliders[i], true);
GenerateTilemapShadowCastersInEditor(colliders[i], false);

HI
It’s say
MissingReferenceException: The object of type ‘CompositeCollider2D’ has been destroyed but you are still trying to access it.
and disappearance gameobject in Hierarch.
why?
Tilemap has Tilemap Collider 2D and Composite Collider 2D.

Thank you! I knew this was going to happen as I’m modifying the code in the post, without compiling (my copy of the code is different and cannot just copy and paste, I have to remove and change things). I hope it’s correct now.

Could you post the line?

Thanks for your responses

MissingReferenceException: The object of type ‘CompositeCollider2D’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
ShadowCaster2DGenerator.GenerateTilemapShadowCasters (UnityEngine.CompositeCollider2D collider, System.Boolean selfShadows) (at Assets/Scripts/ShadowCaster2DExtensions.cs:130)
ShadowCaster2DGenerator.GenerateTilemapShadowCastersInEditor (UnityEngine.CompositeCollider2D collider, System.Boolean selfShadows) (at Assets/Scripts/ShadowCaster2DExtensions.cs:102)
ShadowCaster2DGenerator.GenerateShadowCasters () (at Assets/Scripts/ShadowCaster2DExtensions.cs:75)

Do you have a shadow caster in the same object where the TilemapShadowCaster2D is?