I needed this to use sprites with a normal map without having to redraw the ShadowCaster shape;
I made a small script that will simply mirror the ShadowCaster according to the Spriterenderer’s flipX and flipY values, hope someone else finds this useful
using UnityEngine;
using UnityEngine.Experimental.Rendering.Universal;
using System.Reflection;
[ExecuteInEditMode]
public class ShadowCasterFlip : MonoBehaviour
{
[SerializeField] [HideInInspector] private bool flipX = false;
[SerializeField] [HideInInspector] private bool flipY = false;
private SpriteRenderer spriteRenderer;
private ShadowCaster2D shadowCaster;
private static BindingFlags accessFlagsPrivate = BindingFlags.NonPublic | BindingFlags.Instance;
private static FieldInfo meshField = typeof(ShadowCaster2D).GetField("m_Mesh", accessFlagsPrivate);
private static FieldInfo shapePathField = typeof(ShadowCaster2D).GetField("m_ShapePath", accessFlagsPrivate);
private static MethodInfo onEnableMethod = typeof(ShadowCaster2D).GetMethod("OnEnable", accessFlagsPrivate);
//Bounds bounds => GetComponent<Renderer>()?.bounds ?? GetComponent<Collider2D>()?.bounds ?? new Bounds(transform.position, Vector3.one);
private void flipCaster(bool flipX, bool flipY) {
if (!flipX && !flipY) return;
var shapePath = shapePathField.GetValue(shadowCaster) as Vector3[];
var newShapePath = new Vector3[shapePath.Length];
int newStartIndex = 0;
float? lowestAvg = null;
for(int i = 0; i<shapePath.Length; i++) {
shapePath[i].x = shapePath[i].x * (flipX ? -1 : 1);
shapePath[i].y = shapePath[i].y * (flipY ? -1 : 1);
var newAvg = (shapePath[i].x+shapePath[i].y)/2;
if (lowestAvg == null || newAvg<lowestAvg) {
newStartIndex = i;
lowestAvg = newAvg;
}
}
if (flipX != flipY) for(int i = 0, ni = newStartIndex; i < shapePath.Length; i++, ni--) {
if (ni < 0) ni = shapePath.Length-1;
newShapePath[i] = shapePath[ni];
}
else for(int i = 0, ni = newStartIndex; i < shapePath.Length; i++, ni++) {
if (ni >= shapePath.Length) ni = 0;
newShapePath[i] = shapePath[ni];
}
shapePathField.SetValue(shadowCaster, newShapePath);
meshField.SetValue(shadowCaster, null);
onEnableMethod.Invoke(shadowCaster, new object[0]);
}
void Start() {
spriteRenderer = GetComponent<SpriteRenderer>();
shadowCaster = GetComponent<UnityEngine.Experimental.Rendering.Universal.ShadowCaster2D>();
}
void Update() {
flipCaster((flipX != spriteRenderer.flipX), (flipY != spriteRenderer.flipY));
flipX = spriteRenderer.flipX;
flipY = spriteRenderer.flipY;
}
}