Files
Crash-Course/Assets/Scripts/Game/TilemapShadowCaster2D.cs

88 lines
2.8 KiB
C#
Raw Permalink Normal View History

2025-04-20 22:23:34 -04:00
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
namespace TilemapShadowCaster.Runtime
{
[ExecuteInEditMode]
[DisallowMultipleComponent]
[AddComponentMenu("Rendering/2D/Tilemap Shadow Caster")]
public class TilemapShadowCaster2D : MonoBehaviour
{
[SerializeField] private uint colliderHash;
[SerializeField] private bool m_SelfShadows = false;
[SerializeField] private int m_ApplyToSortingLayers = -1;
private void Update()
{
CompositeCollider2D collider = GetComponent<CompositeCollider2D>();
uint shapeHash = collider.GetShapeHash();
if (shapeHash == colliderHash) return;
colliderHash = shapeHash;
ReinitializeShapes(collider);
}
private int[] getLayers(){
int[] values = SortingLayer.layers.Select(l => l.id).ToArray();
List<int> sortingLayers = new List<int>();
int propCount = 0;
for (int i = 0; i < values.Length; i++)
{
int layer = 1 << i;
if ((m_ApplyToSortingLayers & layer) != 0)
{
sortingLayers.Add(values[propCount]);
propCount ++;
}
}
int[] layerArray = sortingLayers.ToArray();
return layerArray;
}
private void ReinitializeShapes(CompositeCollider2D collider)
{
RemoveCurrentShadows();
for (int i = 0; i < collider.pathCount; i++)
{
List<Vector2> points = new List<Vector2>();
collider.GetPath(i, points);
GameObject go = new GameObject("AutogeneratedShadowPath", typeof(MeshRenderer));
go.transform.parent = transform;
PathShadow path = go.AddComponent<PathShadow>();
path.useRendererSilhouette = false;
path.selfShadows = m_SelfShadows;
path.SetShape(points, getLayers());
}
}
private void RemoveCurrentShadows()
{
new List<PathShadow>(GetComponentsInChildren<PathShadow>())
.ConvertAll(comp => comp.transform.gameObject)
.ForEach(gameObject =>
{
if (Application.isEditor)
{
DestroyImmediate(gameObject);
}
else
{
Destroy(gameObject);
}
});
}
public void ReinitializeShapes()
{
ReinitializeShapes(GetComponent<CompositeCollider2D>());
}
public void OnDestroy()
{
RemoveCurrentShadows();
}
}
}