86 lines
3.0 KiB
C#
86 lines
3.0 KiB
C#
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);
|
|
private static bool isInspector =>
|
|
#if UNITY_EDITOR
|
|
!UnityEditor.EditorApplication.isPlaying;
|
|
#else
|
|
false;
|
|
#endif
|
|
|
|
//Bounds bounds => GetComponent<Renderer>()?.bounds ?? GetComponent<Collider2D>()?.bounds ?? new Bounds(transform.position, Vector3.one);
|
|
|
|
private bool flipCaster(bool flipX, bool flipY)
|
|
{
|
|
if (!flipX && !flipY) return false;
|
|
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);
|
|
shadowCaster.enabled = false;
|
|
meshField.SetValue(shadowCaster, null);
|
|
shadowCaster.enabled = true;
|
|
return true;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
void Start()
|
|
{
|
|
if (isInspector)
|
|
{
|
|
spriteRenderer = GetComponent<SpriteRenderer>();
|
|
shadowCaster = GetComponent<UnityEngine.Experimental.Rendering.Universal.ShadowCaster2D>();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if UNITY_EDITOR
|
|
void Update()
|
|
{
|
|
if (isInspector && flipCaster(flipX != spriteRenderer.flipX, flipY != spriteRenderer.flipY))
|
|
{
|
|
flipX = spriteRenderer.flipX;
|
|
flipY = spriteRenderer.flipY;
|
|
UnityEditor.EditorUtility.SetDirty(shadowCaster);
|
|
UnityEditor.EditorUtility.SetDirty(this);
|
|
}
|
|
}
|
|
#endif
|
|
} |