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(); 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 sortingLayers = new List(); 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 points = new List(); collider.GetPath(i, points); GameObject go = new GameObject("AutogeneratedShadowPath", typeof(MeshRenderer)); go.transform.parent = transform; PathShadow path = go.AddComponent(); path.useRendererSilhouette = false; path.selfShadows = m_SelfShadows; path.SetShape(points, getLayers()); } } private void RemoveCurrentShadows() { new List(GetComponentsInChildren()) .ConvertAll(comp => comp.transform.gameObject) .ForEach(gameObject => { if (Application.isEditor) { DestroyImmediate(gameObject); } else { Destroy(gameObject); } }); } public void ReinitializeShapes() { ReinitializeShapes(GetComponent()); } public void OnDestroy() { RemoveCurrentShadows(); } } }