Search Unity

Shadow Caster 2D - Snapping not working?

Discussion in 'Universal Render Pipeline' started by Khazmadu, Apr 11, 2020.

  1. Khazmadu

    Khazmadu

    Joined:
    Jun 24, 2017
    Posts:
    92
    I can't get the snapping setting in the Shadow Caster 2D to work.



    The regular grid Snapping in my scene works without any problems.
    I'm using 2019.3.9
     
  2. icecold043

    icecold043

    Joined:
    Jan 9, 2019
    Posts:
    8
    Same problem over here, I also wondered if there is a way to make it automated with a tilemap
     
  3. icecold043

    icecold043

    Joined:
    Jan 9, 2019
    Posts:
    8
    Okay so i found the solution, however, the snapping only occurs on the grid and it seems that you cant set a custom grid the the shadow caster snapping.
    In the top left corner, when "snapping" is enabled, an icon will appear that looks like a magnet, here you can toggle it on and off
     
  4. Khazmadu

    Khazmadu

    Joined:
    Jun 24, 2017
    Posts:
    92
    Thanks. That seems to be it.
    Not Sure what Icon you mean but when I activate the Grid in the viewport It does work.

    The fact that you can't change the size really limits it's usefulness. I would rather want it to snap to the pixels than to the tiles but it's better than nothing.
     
    Last edited: Apr 21, 2020
  5. icecold043

    icecold043

    Joined:
    Jan 9, 2019
    Posts:
    8
    Yep, it's in an experimenting state for now, i really hope they will improve this feature, and the "default layer" thing
     
  6. Extelen1

    Extelen1

    Joined:
    Mar 22, 2019
    Posts:
    2
    I have a little trick for this, you can edit the Snapping.cs in Packages/Universal RP/Editor/2D/ShapeEditor/EditablePath and set the value of the Snap Vector3 to 1/pixelsPerUnit, for example in my case, is 1/16f. When you restart Unity, the scripts go back to the default value, but for when you are editing your shadows is really helpful. I hope this works, and sorry for the english.
     
  7. Infinite-3D

    Infinite-3D

    Joined:
    Jan 5, 2020
    Posts:
    40
    how?
     
  8. sandsalamand

    sandsalamand

    Joined:
    Jan 9, 2020
    Posts:
    24
    I just went down the rabbit hole investigating this, and it looks like the problem stems from this file in Unity's code.

    https://github.com/Unity-Technologi...or/2D/ShapeEditor/EditablePath/Snapping.cs#L8

    "MoveSnapX" and "MoveSnapY" are not found by EditorPrefs, so it returns the default, which is 1. That's why ShadowCaster will only snap in increments of 1. This can be verified by calling `EditorPrefs.GetFloat` with an absurd default value, and checking the result.

    The only solutions I can think of which are achievable without modifying the source code are
    1. Monkey-patching Snapping.Snap with something like Harmony.
    2. Some kind of Editor script which scans for changes to the points of the active ShadowCaster2D, and corrects them with the proper snapping value.
     
  9. sandsalamand

    sandsalamand

    Joined:
    Jan 9, 2020
    Posts:
    24
    Here is a solution that detects when a ShadowCaster2D is selected, and snaps the points every 0.5 seconds. It's ugly, but it works.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using Unity.EditorCoroutines.Editor;
    4. using UnityEditor;
    5. using UnityEngine;
    6. using UnityEngine.Rendering.Universal;
    7.  
    8. public class ShadowCasterSnapper : Editor
    9. {
    10.     static bool editorWantsToQuit = false;
    11.     static float durationBetweenSnap = 0.5f;
    12.  
    13.     [InitializeOnLoadMethod]
    14.     private static void Initialize()
    15.     {
    16.         EditorApplication.wantsToQuit += () => editorWantsToQuit = true;
    17.         EditorCoroutineUtility.StartCoroutineOwnerless(CheckForShadowCaster());
    18.     }
    19.  
    20.     private static IEnumerator CheckForShadowCaster()
    21.     {
    22.         while (!editorWantsToQuit)
    23.         {
    24.             var activeTransform = Selection.activeTransform;
    25.             if (activeTransform == null)
    26.             {
    27.                 yield return new EditorWaitForSeconds(durationBetweenSnap);
    28.                 continue;
    29.             }
    30.  
    31.             ShadowCaster2D[] shadowCasters = activeTransform.gameObject.GetComponents<ShadowCaster2D>();
    32.  
    33.             if (shadowCasters != null && shadowCasters.Length != 0)
    34.                 shadowCasters[0].SetShape(RoundPoints(shadowCasters[0].shapePath));
    35.  
    36.             yield return new EditorWaitForSeconds(durationBetweenSnap);
    37.         }
    38.     }
    39.  
    40.     // ignores z because this is 2D-specific
    41.     private static Vector3[] RoundPoints(Vector3[] points)
    42.     {
    43.         Vector3[] roundedPoints = new Vector3[points.Length];
    44.  
    45.         var gridSizeX = EditorSnapSettings.gridSize.x;
    46.         var gridSizeY = EditorSnapSettings.gridSize.y;
    47.  
    48.         for (int i = 0; i < points.Length; i++)
    49.         {
    50.             Vector3 point = points[i];
    51.  
    52.             roundedPoints[i] = new Vector3(
    53.                 x: Mathf.Round(point.x / gridSizeX) * gridSizeX,
    54.                 y: Mathf.Round(point.y / gridSizeY) * gridSizeY,
    55.                 z: 0
    56.             );
    57.         }
    58.         return roundedPoints;
    59.     }
    60. }
    61.  

    ShadowCaster2D.SetShape comes from the bottom solution on this page.

    https://forum.unity.com/threads/can-we-modify-shadowcaster2ds-mesh-at-runtime.755498/