Skip to content

Instantly share code, notes, and snippets.

@giacomelli
Last active January 14, 2022 09:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giacomelli/c208e20ecf75a77e0833f4c7671a0052 to your computer and use it in GitHub Desktop.
Save giacomelli/c208e20ecf75a77e0833f4c7671a0052 to your computer and use it in GitHub Desktop.
#unitytips: ShadowCaster2DFromCollider Component: http://diegogiacomelli.com.br/unitytips-shadowcaster2-from-collider-component
using System.Reflection;
using UnityEngine;
using UnityEngine.Experimental.Rendering.Universal;
/// <summary>
/// unitytips: ShadowCaster2DFromCollider Component
/// http://diegogiacomelli.com.br/unitytips-shadowcaster2-from-collider-component
/// <remarks>
/// Based on https://forum.unity.com/threads/can-2d-shadow-caster-use-current-sprite-silhouette.861256/
/// </remarks>
/// </summary>
[RequireComponent(typeof(ShadowCaster2D))]
[DefaultExecutionOrder(100)]
public class ShadowCaster2DFromCollider : MonoBehaviour
{
static readonly FieldInfo _meshField;
static readonly FieldInfo _shapePathField;
static readonly MethodInfo _generateShadowMeshMethod;
ShadowCaster2D _shadowCaster;
EdgeCollider2D _edgeCollider;
PolygonCollider2D _polygonCollider;
static ShadowCaster2DFromCollider()
{
_meshField = typeof(ShadowCaster2D).GetField("m_Mesh", BindingFlags.NonPublic | BindingFlags.Instance);
_shapePathField = typeof(ShadowCaster2D).GetField("m_ShapePath", BindingFlags.NonPublic | BindingFlags.Instance);
_generateShadowMeshMethod = typeof(ShadowCaster2D)
.Assembly
.GetType("UnityEngine.Experimental.Rendering.Universal.ShadowUtility")
.GetMethod("GenerateShadowMesh", BindingFlags.Public | BindingFlags.Static);
}
private void Start()
{
_shadowCaster = GetComponent<ShadowCaster2D>();
_edgeCollider = GetComponent<EdgeCollider2D>();
if (_edgeCollider == null)
_polygonCollider = GetComponent<PolygonCollider2D>();
UpdateShadow();
}
public void UpdateShadow()
{
var points = _polygonCollider == null
? _edgeCollider.points
: _polygonCollider.points;
_shapePathField.SetValue(_shadowCaster, points.ToVector3());
_meshField.SetValue(_shadowCaster, new Mesh());
_generateShadowMeshMethod.Invoke(_shadowCaster, new object[] { _meshField.GetValue(_shadowCaster), _shapePathField.GetValue(_shadowCaster) });
}
}
@GuilhermeGSousa
Copy link

Hi, thanks for the great script, it was super useful for me. I also had to fix the Vector2 to Vector3 array conversion, here's how I did it in case it might be helpful to you

    public void UpdateShadow()
    {
        var points = _polygonCollider == null
            ? _edgeCollider.points
            : _polygonCollider.points;

        _shapePathField.SetValue(_shadowCaster, System.Array.ConvertAll<Vector2, Vector3> (points, getV3FromV2));
        _meshField.SetValue(_shadowCaster, new Mesh());
        _generateShadowMeshMethod.Invoke(_shadowCaster, new object[] { _meshField.GetValue(_shadowCaster), _shapePathField.GetValue(_shadowCaster) });
    }

    private static Vector3 getV3FromV2 (Vector2 v2)
    {
    return v2;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment