Search Unity

Shadow Caster 2D not working on TileMap?

Discussion in '2D Experimental Preview' started by ayockel90, Dec 14, 2019.

  1. ayockel90

    ayockel90

    Joined:
    Jan 27, 2019
    Posts:
    15
    I have Shadow Caster 2D working on regular objects (doors in my game) but it doesn't seem to work on my TileMap walls.

    https://imgur.com/a/n7OvxAm

    Is this a known issue or am I doing something wrong?
     
  2. thomasedw

    thomasedw

    Joined:
    Dec 23, 2019
    Posts:
    8
    The current ShadowCaster2D component appears to only take the bounds of a collider and/or object. You can modify the Awake() function in ShadowCaster2D.cs to check if the type of collider is a polygon, then use the path of the polygon as the shape for the generated shadow mesh. The file was located at "Library\PackageCache\com.unity.render-pipelines.universal@7.1.7\Runtime\2D" for me.
    Code (CSharp):
    1. private void Awake() {
    2.             if(m_ApplyToSortingLayers == null)
    3.                 m_ApplyToSortingLayers = SetDefaultSortingLayers();
    4.  
    5.             Bounds bounds = new Bounds(transform.position, Vector3.one);
    6.          
    7.             Renderer renderer = GetComponent<Renderer>();
    8.             if (renderer != null)
    9.             {
    10.                 bounds = renderer.bounds;
    11.             }
    12.             else
    13.             {
    14.                 Collider2D collider = GetComponent<Collider2D>();
    15.                 if (collider != null)
    16.                     if (collider.GetType() == typeof(PolygonCollider2D)) {
    17.                         m_ShapePath = Array.ConvertAll<Vector2, Vector3>(((PolygonCollider2D)collider).GetPath(0), vec2To3);
    18.                         m_UseRendererSilhouette = false;
    19.                     } else {
    20.                         bounds = collider.bounds;
    21.                     }
    22.             }
    23.  
    24.             Vector3 relOffset = bounds.center - transform.position;
    25.  
    26.             if (m_ShapePath == null || m_ShapePath.Length == 0)
    27.             {
    28.                 m_ShapePath = new Vector3[]
    29.                 {
    30.                     relOffset + new Vector3(-bounds.extents.x, -bounds.extents.y),
    31.                     relOffset + new Vector3(bounds.extents.x, -bounds.extents.y),
    32.                     relOffset + new Vector3(bounds.extents.x, bounds.extents.y),
    33.                     relOffset + new Vector3(-bounds.extents.x, bounds.extents.y)
    34.                 };
    35.             }
    36. }
    I then use a different script that requires a CompositeCollider2D to be attached to my tilemap and builds a ShadowCaster2D for each distinct path in the composite collider, which looks like the following:
    Code (CSharp):
    1.  
    2. public void Start() {
    3.             tilemapCollider = GetComponent<CompositeCollider2D>();
    4.             GameObject shadowCasterContainer = GameObject.Find("shadow_casters");
    5.             for (int i = 0; i < tilemapCollider.pathCount; i++) {
    6.             Vector2[] pathVertices = new Vector2[tilemapCollider.GetPathPointCount(i)];
    7.             tilemapCollider.GetPath(i, pathVertices);
    8.             GameObject shadowCaster = new GameObject("shadow_caster_" + i);
    9.             PolygonCollider2D shadowPolygon = (PolygonCollider2D)shadowCaster.AddComponent(typeof(PolygonCollider2D));
    10.             shadowCaster.transform.parent = shadowCasterContainer.transform;
    11.             shadowPolygon.points = pathVertices;
    12.             shadowPolygon.enabled = false;
    13.             ShadowCaster2D shadowCasterComponent = shadowCaster.AddComponent<ShadowCaster2D>();
    14.             shadowCasterComponent.selfShadows = true;
    15.             }
    16. }
    Editing ShadowCaster2D should be a somewhat temporary fix until Unity alter the implementation, as in my case it can be refetched and your changes will be lost (unless you fork the ScriptableRenderPipeline repository and point the package manager to use your changes) - so I'd recommend saving the modified ShadowCaster2D script somewhere as a backup to copy and paste if it does the same for you.
     
    Last edited: Dec 29, 2019
    ToastandBananas likes this.
  3. ayockel90

    ayockel90

    Joined:
    Jan 27, 2019
    Posts:
    15


    Thanks, I've tried your fix but I receive the following error after modifying ShadowCaster2D.cs

    Library\PackageCache\com.unity.render-pipelines.universal@7.1.5\Runtime\2D\ShadowCaster2D.cs(102,116): error CS0103: The name 'vec2To3' does not exist in the current context
     
  4. thomasedw

    thomasedw

    Joined:
    Dec 23, 2019
    Posts:
    8
    Ah I forgot to add this method in my original snippet as-well, add this method in and it should hopefully work:
    Code (CSharp):
    1. private Vector3 vec2To3(Vector2 inputVector) {
    2.     return new Vector3(inputVector.x, inputVector.y, 0);
    3. }
     
    ToastandBananas likes this.
  5. ayockel90

    ayockel90

    Joined:
    Jan 27, 2019
    Posts:
    15
    That fixed the compiler error but sadly the light is still going through my walls.

    At least I know it's a limitation of the component. Sounds like it will be better to wait for them to implement Tilemap shadows.

    Thanks for your help anyway.
     
  6. japhib

    japhib

    Joined:
    May 26, 2017
    Posts:
    8
    @thomasedw Your solution works great! @ayockel90 just make sure that you have a TilemapCollider2D on the tilemap, with the "Used By Composite" checkbox checked, in addition to having a CompositeCollider2D component on there.
     
    thomasedw likes this.
  7. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,607
    CherryFake likes this.
  8. ToastandBananas

    ToastandBananas

    Joined:
    Jun 8, 2018
    Posts:
    8
    @thomasedw you're amazing! Your fix works perfectly!
     
    thomasedw likes this.
  9. ToastandBananas

    ToastandBananas

    Joined:
    Jun 8, 2018
    Posts:
    8
    @thomasedw Well I just discovered that when you close down and reopen Unity, that the ShadowCaster2D script reverts back to it's original form, so anything I added isn't there anymore. Do you know of a way to prevent this?
     
  10. thomasedw

    thomasedw

    Joined:
    Dec 23, 2019
    Posts:
    8
    You need to fork this GitHub repository https://github.com/Unity-Technologies/ScriptableRenderPipeline, make changes in that and then you link to your forked version in the package manager by clicking the "+" icon and choosing "Add package from git URL..."
     
    ToastandBananas likes this.
  11. ToastandBananas

    ToastandBananas

    Joined:
    Jun 8, 2018
    Posts:
    8
  12. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,607
    Perhaps change the name of the package... like CustomScriptableRenderPipeline
     
  13. thomasedw

    thomasedw

    Joined:
    Dec 23, 2019
    Posts:
    8
    It's been a while since I first added it - but @dotaxis posted on this here: https://forum.unity.com/threads/the-new-2d-lighting-on-tilemaps-advice-and-suggestions.810927/, they altered their manifest.json file directly (incase using the package manager doesn't work).
     
    ToastandBananas likes this.
  14. ToastandBananas

    ToastandBananas

    Joined:
    Jun 8, 2018
    Posts:
    8
    @thomasedw Ahhhh beautiful, this worked perfectly...thanks again, you're awesome!
     
    thomasedw likes this.
  15. robbel

    robbel

    Joined:
    Nov 11, 2016
    Posts:
    10
  16. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,607
    I replied to this here:
    https://forum.unity.com/threads/the...s-advice-and-suggestions.810927/#post-5436126
     
unityunity