Advertisement
Guest User

Auto Shadow on Closed Tilemap c#

a guest
Jul 29th, 2022
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.46 KB | None | 0 0
  1. using System.Linq;
  2. using System.Reflection;
  3. using UnityEngine;
  4. using UnityEngine.Rendering.Universal;
  5. using System.Collections.Generic;
  6.  
  7. [RequireComponent(typeof(CompositeCollider2D))]
  8. public class AutoShadowClosedTilemap : MonoBehaviour
  9. {
  10.  
  11.     [Space]
  12.     [SerializeField]
  13.     private bool selfShadows = true;
  14.  
  15.     private CompositeCollider2D tilemapCollider;
  16.     private List<Vector2> unionVertices = new();
  17.  
  18.  
  19.     static readonly FieldInfo meshField = typeof(ShadowCaster2D).GetField("m_Mesh", BindingFlags.NonPublic | BindingFlags.Instance);
  20.     static readonly FieldInfo shapePathField = typeof(ShadowCaster2D).GetField("m_ShapePath", BindingFlags.NonPublic | BindingFlags.Instance);
  21.     static readonly MethodInfo generateShadowMeshMethod = typeof(ShadowCaster2D)
  22.             .Assembly
  23.             .GetType("UnityEngine.Rendering.Universal.ShadowUtility")
  24.             .GetMethod("GenerateShadowMesh", BindingFlags.Public | BindingFlags.Static);
  25.  
  26.     [ContextMenu("Generate")]
  27.     public void Generate()
  28.     {
  29.         tilemapCollider = GetComponent<CompositeCollider2D>();
  30.  
  31.         if(tilemapCollider.pathCount != 2) {
  32.             print("Shadow must be used in one closed tiles. Please erase the other tiles to other Tilemap.");
  33.             return;
  34.         }
  35.  
  36.         unionVertices.Clear();
  37.         DestroyAllChildren();
  38.  
  39.  
  40.         Vector2[] pathVertices = new Vector2[tilemapCollider.GetPathPointCount(0)];
  41.         tilemapCollider.GetPath(0, unionVertices);
  42.         tilemapCollider.GetPath(1, pathVertices);
  43.  
  44.         var index = 0;
  45.         var endPath = unionVertices[unionVertices.Count - 1];
  46.         var length = Vector2.Distance(pathVertices[0], endPath);
  47.  
  48.         for(var i = 1; i < pathVertices.Length; i++) {
  49.             var path = pathVertices[i];
  50.             var curLen = Vector2.Distance(endPath, path);
  51.             if(curLen < length) {
  52.                 length = curLen;
  53.                 index = i;
  54.             }
  55.         }
  56.  
  57.         for(var i = 0; i < pathVertices.Length; i++) {
  58.             var path = pathVertices[(i + index) % pathVertices.Length];
  59.             unionVertices.Add(path);
  60.         }
  61.  
  62.         for(var i = 0; i < unionVertices.Count; i++) {
  63.             var cur = unionVertices[i];
  64.             var next = unionVertices[(i + 1) % unionVertices.Count];
  65.  
  66.             Debug.DrawLine(cur, cur + (next - cur) * 0.5f, Color.red);
  67.         }
  68.        
  69.         var shadowCaster = new GameObject("ShadowCaster");
  70.         shadowCaster.transform.parent = gameObject.transform;
  71.         shadowCaster.transform.position = Vector3.zero;
  72.         ShadowCaster2D shadowCasterComponent = shadowCaster.AddComponent<ShadowCaster2D>();
  73.         shadowCasterComponent.selfShadows = this.selfShadows;
  74.  
  75.         var testPath = new Vector3[unionVertices.Count];
  76.         var j = 0;
  77.         foreach (var path in unionVertices)
  78.         {
  79.             testPath[j++] = path;
  80.         }
  81.  
  82.         shapePathField.SetValue(shadowCasterComponent, testPath);
  83.         meshField.SetValue(shadowCasterComponent, new Mesh());
  84.         generateShadowMeshMethod.Invoke(shadowCasterComponent, new object[] { meshField.GetValue(shadowCasterComponent), shapePathField.GetValue(shadowCasterComponent) });
  85.  
  86.         Debug.Log("Shadow Generated");
  87.  
  88.     }
  89.     public void DestroyAllChildren()
  90.     {
  91.  
  92.         var tempList = transform.Cast<Transform>().ToList();
  93.         foreach (var child in tempList)
  94.         {
  95.             DestroyImmediate(child.gameObject);
  96.         }
  97.  
  98.     }
  99.  
  100. }
  101.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement