683 lines
26 KiB
C#
683 lines
26 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Scripting.APIUpdating;
|
|
using Unity.Collections;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
using UnityEditor.EditorTools;
|
|
#endif
|
|
|
|
namespace UnityEngine.Rendering.Universal
|
|
{
|
|
/// <summary>
|
|
/// Class <c>ShadowCaster2D</c> contains properties used for shadow casting
|
|
/// </summary>
|
|
[CoreRPHelpURL("2DShadows", "com.unity.render-pipelines.universal")]
|
|
[ExecuteInEditMode]
|
|
[DisallowMultipleComponent]
|
|
[Icon("UnityEngine/UI/Shadow Icon")]
|
|
[AddComponentMenu("Rendering/2D/Shadow Caster 2D")]
|
|
[MovedFrom(false, "UnityEngine.Experimental.Rendering.Universal", "com.unity.render-pipelines.universal")]
|
|
|
|
public class ShadowCaster2D : ShadowCasterGroup2D, ISerializationCallbackReceiver
|
|
{
|
|
|
|
internal enum ComponentVersions
|
|
{
|
|
Version_Unserialized = 0,
|
|
Version_1 = 1,
|
|
Version_2 = 2,
|
|
Version_3 = 3,
|
|
Version_4 = 4,
|
|
Version_5 = 5,
|
|
Version_6 = 6,
|
|
}
|
|
|
|
const ComponentVersions k_CurrentComponentVersion = ComponentVersions.Version_6;
|
|
[SerializeField] ComponentVersions m_ComponentVersion = ComponentVersions.Version_Unserialized;
|
|
|
|
internal enum ShadowCastingSources
|
|
{
|
|
None,
|
|
ShapeEditor,
|
|
ShapeProvider
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Options for what type of shadows are cast.
|
|
/// </summary>
|
|
public enum ShadowCastingOptions
|
|
{
|
|
/// <summary>
|
|
/// Renders a shadows only for the sprite.
|
|
/// </summary>
|
|
SelfShadow,
|
|
|
|
/// <summary>
|
|
/// Renders a shadows only a cast shadow.
|
|
/// </summary>
|
|
CastShadow,
|
|
|
|
/// <summary>
|
|
/// Renders both a shadows for the sprite and a cast shadow.
|
|
/// </summary>
|
|
CastAndSelfShadow,
|
|
|
|
/// <summary>
|
|
/// Renders a sprite without shadow casting correctly on top of other shadow casting sprites
|
|
/// </summary>
|
|
NoShadow
|
|
}
|
|
|
|
internal enum EdgeProcessing
|
|
{
|
|
None = ShadowMesh2D.EdgeProcessing.None,
|
|
Clipping = ShadowMesh2D.EdgeProcessing.Clipping,
|
|
}
|
|
|
|
[SerializeField] bool m_HasRenderer = false;
|
|
[SerializeField] bool m_UseRendererSilhouette = true;
|
|
[SerializeField] bool m_CastsShadows = true;
|
|
[SerializeField] bool m_SelfShadows = false;
|
|
[Range(0, 1)]
|
|
[SerializeField] float m_AlphaCutoff = 0.1f;
|
|
[SerializeField] int[] m_ApplyToSortingLayers = null;
|
|
[SerializeField] Vector3[] m_ShapePath = null;
|
|
[SerializeField] int m_ShapePathHash = 0;
|
|
|
|
[SerializeField] int m_InstanceId;
|
|
[SerializeField] Component m_ShadowShape2DComponent;
|
|
[SerializeReference] ShadowShape2DProvider m_ShadowShape2DProvider;
|
|
[SerializeField] ShadowCastingSources m_ShadowCastingSource = (ShadowCastingSources)(-1);
|
|
|
|
[SerializeReference] internal ShadowMesh2D m_ShadowMesh;
|
|
[SerializeField] ShadowCastingOptions m_CastingOption = ShadowCastingOptions.CastShadow;
|
|
|
|
[SerializeField] internal float m_PreviousTrimEdge = 0;
|
|
[SerializeField] internal int m_PreviousEdgeProcessing;
|
|
[SerializeField] internal int m_PreviousShadowCastingSource;
|
|
[SerializeField] internal Component m_PreviousShadowShape2DSource = null;
|
|
[SerializeField] internal int m_PreviousShadowShape2DProviderHash;
|
|
|
|
#if UNITY_EDITOR
|
|
[SerializeReference] internal Shadow2DProviderSources m_SelectionSources = new Shadow2DProviderSources();
|
|
#endif
|
|
|
|
internal ShadowCasterGroup2D m_ShadowCasterGroup = null;
|
|
internal ShadowCasterGroup2D m_PreviousShadowCasterGroup = null;
|
|
|
|
internal bool isTransformable
|
|
{
|
|
get
|
|
{
|
|
if (m_ShadowMesh != null)
|
|
return m_ShadowMesh.isTransformable;
|
|
else
|
|
return true; // This is the old default
|
|
}
|
|
}
|
|
|
|
internal bool m_ForceShadowMeshRebuild;
|
|
|
|
internal EdgeProcessing edgeProcessing
|
|
{
|
|
get { return (EdgeProcessing)m_ShadowMesh.edgeProcessing; }
|
|
set { m_ShadowMesh.edgeProcessing = (ShadowMesh2D.EdgeProcessing)value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The mesh to draw with.
|
|
/// </summary>
|
|
public Mesh mesh => m_ShadowMesh.mesh;
|
|
|
|
/// <summary>
|
|
/// The bounding sphere for the shadow caster
|
|
/// </summary>
|
|
public BoundingSphere boundingSphere => m_ShadowMesh.boundingSphere;
|
|
|
|
/// <summary>
|
|
/// The amount the shadow's edge is trimed
|
|
/// </summary>
|
|
public float trimEdge
|
|
{
|
|
get { return m_ShadowMesh.trimEdge; } set { m_ShadowMesh.trimEdge = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The sets the renderer's shadow cutoff
|
|
/// </summary>
|
|
public float alphaCutoff
|
|
{
|
|
get { return m_AlphaCutoff; }
|
|
set { m_AlphaCutoff = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The path for the shape.
|
|
/// </summary>
|
|
public Vector3[] shapePath => m_ShapePath;
|
|
|
|
internal int shapePathHash { get { return m_ShapePathHash; } set { m_ShapePathHash = value; } }
|
|
|
|
internal ShadowCastingSources shadowCastingSource { get { return m_ShadowCastingSource; } set { m_ShadowCastingSource = value; } }
|
|
|
|
|
|
// Make this public if possible...
|
|
internal Component shadowShape2DComponent { get { return m_ShadowShape2DComponent; } set { m_ShadowShape2DComponent = value; } }
|
|
internal ShadowShape2DProvider shadowShape2DProvider { get { return m_ShadowShape2DProvider; } set { m_ShadowShape2DProvider = value; } }
|
|
|
|
int m_PreviousShadowGroup = 0;
|
|
bool m_PreviousCastsShadows = true;
|
|
int m_PreviousPathHash = 0;
|
|
|
|
int m_SpriteMaterialCount;
|
|
|
|
internal Vector3 m_CachedPosition;
|
|
internal Vector3 m_CachedLossyScale;
|
|
internal Quaternion m_CachedRotation;
|
|
internal Matrix4x4 m_CachedShadowMatrix;
|
|
internal Matrix4x4 m_CachedInverseShadowMatrix;
|
|
internal Matrix4x4 m_CachedLocalToWorldMatrix;
|
|
internal int spriteMaterialCount => m_SpriteMaterialCount;
|
|
|
|
internal override void CacheValues()
|
|
{
|
|
m_CachedPosition = transform.position;
|
|
m_CachedLossyScale = transform.lossyScale;
|
|
m_CachedRotation = transform.rotation;
|
|
|
|
bool flipX, flipY;
|
|
m_ShadowMesh.GetFlip(out flipX, out flipY);
|
|
Vector3 scale = new Vector3(flipX ? -1 : 1, flipY ? -1 : 1, 1);
|
|
|
|
m_CachedShadowMatrix = Matrix4x4.TRS(m_CachedPosition, m_CachedRotation, scale);
|
|
m_CachedInverseShadowMatrix = m_CachedShadowMatrix.inverse;
|
|
|
|
m_CachedLocalToWorldMatrix = transform.localToWorldMatrix;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the type of shadow cast.
|
|
/// </summary>
|
|
public ShadowCastingOptions castingOption
|
|
{
|
|
set { m_CastingOption = value; }
|
|
get { return m_CastingOption; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// This property is obsolete and no longer has any effect. Its functionality has been removed because it is no longer required.
|
|
/// To achieve similar behavior, add a ShadowCaster2D component to an empty parent GameObject instead.
|
|
/// </summary>
|
|
[Obsolete("useRendererSilhouette is obsolete and no longer has any effect. To achieve similar behavior, add a ShadowCaster2D component to an empty parent GameObject. #from(2023.1)")]
|
|
public bool useRendererSilhouette
|
|
{
|
|
set { m_UseRendererSilhouette = value; }
|
|
get { return m_UseRendererSilhouette && m_HasRenderer; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// If true, the shadow casting shape is included as part of the shadow. If false, the shadow casting shape is excluded from the shadow.
|
|
/// </summary>
|
|
public bool selfShadows
|
|
{
|
|
set
|
|
{
|
|
if (value)
|
|
{
|
|
if (castingOption == ShadowCastingOptions.CastShadow)
|
|
castingOption = ShadowCastingOptions.CastAndSelfShadow;
|
|
else if (castingOption == ShadowCastingOptions.NoShadow)
|
|
castingOption = ShadowCastingOptions.SelfShadow;
|
|
}
|
|
else
|
|
{
|
|
if (castingOption == ShadowCastingOptions.CastAndSelfShadow )
|
|
castingOption = ShadowCastingOptions.CastShadow;
|
|
else if(castingOption == ShadowCastingOptions.SelfShadow)
|
|
castingOption = ShadowCastingOptions.NoShadow;
|
|
}
|
|
|
|
}
|
|
get { return castingOption == ShadowCastingOptions.CastAndSelfShadow || castingOption == ShadowCastingOptions.SelfShadow; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Specifies if shadows will be cast.
|
|
/// </summary>
|
|
///
|
|
public bool castsShadows
|
|
{
|
|
set
|
|
{
|
|
if(value)
|
|
{
|
|
if (castingOption == ShadowCastingOptions.SelfShadow)
|
|
castingOption = ShadowCastingOptions.CastAndSelfShadow;
|
|
else if (castingOption == ShadowCastingOptions.NoShadow)
|
|
castingOption = ShadowCastingOptions.CastShadow;
|
|
}
|
|
else
|
|
{
|
|
if (castingOption == ShadowCastingOptions.CastAndSelfShadow)
|
|
castingOption = ShadowCastingOptions.SelfShadow;
|
|
else if (castingOption == ShadowCastingOptions.CastShadow)
|
|
castingOption = ShadowCastingOptions.NoShadow;
|
|
}
|
|
}
|
|
|
|
get { return castingOption == ShadowCastingOptions.CastShadow || castingOption == ShadowCastingOptions.CastAndSelfShadow; }
|
|
}
|
|
|
|
static int[] SetDefaultSortingLayers()
|
|
{
|
|
int layerCount = SortingLayer.layers.Length;
|
|
int[] allLayers = new int[layerCount];
|
|
|
|
for (int layerIndex = 0; layerIndex < layerCount; layerIndex++)
|
|
{
|
|
allLayers[layerIndex] = SortingLayer.layers[layerIndex].id;
|
|
}
|
|
|
|
return allLayers;
|
|
}
|
|
|
|
internal bool IsLit(Light2D light)
|
|
{
|
|
// Global lights do not cast shadows
|
|
if (light.lightType == Light2D.LightType.Global)
|
|
return false;
|
|
|
|
// Oddly adding and subtracting vectors is expensive here because of the new structures created...
|
|
Vector3 deltaPos;
|
|
deltaPos.x = light.boundingSphere.position.x - boundingSphere.position.x;
|
|
deltaPos.y = light.boundingSphere.position.y - boundingSphere.position.y;
|
|
deltaPos.z = light.boundingSphere.position.z - boundingSphere.position.z;
|
|
|
|
float distanceSq = Vector3.SqrMagnitude(deltaPos);
|
|
|
|
float radiiLength = light.boundingSphere.radius + boundingSphere.radius;
|
|
return distanceSq <= (radiiLength * radiiLength);
|
|
}
|
|
|
|
internal bool IsShadowedLayer(int layer)
|
|
{
|
|
return m_ApplyToSortingLayers != null ? Array.IndexOf(m_ApplyToSortingLayers, layer) >= 0 : false;
|
|
}
|
|
|
|
void SetShadowShape(ShadowMesh2D shadowMesh)
|
|
{
|
|
m_ForceShadowMeshRebuild = false;
|
|
|
|
if (m_ShadowCastingSource == ShadowCastingSources.ShapeEditor)
|
|
{
|
|
NativeArray<Vector3> nativePath = new NativeArray<Vector3>(m_ShapePath, Allocator.Temp);
|
|
NativeArray<int> nativeIndices = new NativeArray<int>(2 * m_ShapePath.Length, Allocator.Temp);
|
|
|
|
int lastIndex = m_ShapePath.Length - 1;
|
|
for (int i = 0; i < m_ShapePath.Length; i++)
|
|
{
|
|
int startingIndex = i << 1;
|
|
nativeIndices[startingIndex] = lastIndex;
|
|
nativeIndices[startingIndex + 1] = i;
|
|
lastIndex = i;
|
|
}
|
|
|
|
shadowMesh.SetShapeWithLines(nativePath, nativeIndices, false);
|
|
|
|
nativePath.Dispose();
|
|
nativeIndices.Dispose();
|
|
}
|
|
if (m_ShadowCastingSource == ShadowCastingSources.ShapeProvider)
|
|
{
|
|
ShapeProviderUtility.PersistantDataCreated(m_ShadowShape2DProvider, m_ShadowShape2DComponent, shadowMesh);
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (m_ShadowCastingSource < 0)
|
|
{
|
|
#if UNITY_EDITOR
|
|
ShapeProviderUtility.TryGetDefaultShadowShapeProviderSource(gameObject, out var component, out var provider);
|
|
if (component != null && provider != null && (shapePath == null || shapePath.Length == 0))
|
|
{
|
|
m_ShadowShape2DComponent = component;
|
|
m_ShadowShape2DProvider = provider;
|
|
m_ShadowCastingSource = ShadowCastingSources.ShapeProvider;
|
|
}
|
|
else
|
|
{
|
|
m_ShadowCastingSource = ShadowCastingSources.ShapeEditor;
|
|
}
|
|
#else
|
|
m_ShadowCastingSource = ShadowCastingSources.ShapeEditor;
|
|
#endif
|
|
}
|
|
|
|
Vector3 inverseScale = Vector3.zero;
|
|
Vector3 relOffset = transform.position;
|
|
|
|
if (transform.lossyScale.x != 0 && transform.lossyScale.y != 0)
|
|
{
|
|
inverseScale = new Vector3(1 / transform.lossyScale.x, 1 / transform.lossyScale.y);
|
|
relOffset = new Vector3(inverseScale.x * -transform.position.x, inverseScale.y * -transform.position.y);
|
|
}
|
|
|
|
|
|
if (m_ApplyToSortingLayers == null)
|
|
m_ApplyToSortingLayers = SetDefaultSortingLayers();
|
|
|
|
|
|
Bounds bounds = new Bounds(transform.position, Vector3.one);
|
|
Renderer renderer = GetComponent<Renderer>();
|
|
if (renderer != null)
|
|
{
|
|
bounds = renderer.bounds;
|
|
m_SpriteMaterialCount = renderer.sharedMaterials.Length;
|
|
}
|
|
|
|
if (m_ShapePath == null || m_ShapePath.Length == 0)
|
|
{
|
|
m_ShapePath = new Vector3[]
|
|
{
|
|
relOffset + new Vector3(inverseScale.x * bounds.min.x, inverseScale.y * bounds.min.y),
|
|
relOffset + new Vector3(inverseScale.x * bounds.min.x, inverseScale.y * bounds.max.y),
|
|
relOffset + new Vector3(inverseScale.x * bounds.max.x, inverseScale.y * bounds.max.y),
|
|
relOffset + new Vector3(inverseScale.x * bounds.max.x, inverseScale.y * bounds.min.y),
|
|
};
|
|
}
|
|
|
|
|
|
if (m_ShadowMesh == null)
|
|
{
|
|
m_ShadowMesh = new ShadowMesh2D();
|
|
}
|
|
#if USING_PHYSICS2D_MODULE
|
|
else
|
|
{
|
|
Collider2D collider = GetComponent<Collider2D>();
|
|
if (collider != null)
|
|
bounds = collider.bounds;
|
|
}
|
|
#endif
|
|
|
|
if (m_ShadowMesh.trimEdge == ShadowMesh2D.k_TrimEdgeUninitialized)
|
|
SetShadowShape(m_ShadowMesh);
|
|
}
|
|
|
|
internal void EnsureMeshInitialized()
|
|
{
|
|
if (m_ShadowMesh == null)
|
|
m_ShadowMesh = new ShadowMesh2D();
|
|
|
|
if (m_ShadowMesh.trimEdge == ShadowMesh2D.k_TrimEdgeUninitialized)
|
|
SetShadowShape(m_ShadowMesh);
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function is called when the object becomes enabled and active.
|
|
/// </summary>
|
|
protected void OnEnable()
|
|
{
|
|
if (m_ShadowShape2DProvider != null && m_ShadowShape2DComponent != null)
|
|
m_ShadowShape2DProvider.Enabled(m_ShadowShape2DComponent, m_ShadowMesh);
|
|
|
|
m_ShadowCasterGroup = null;
|
|
|
|
#if UNITY_EDITOR
|
|
SortingLayer.onLayerAdded += OnSortingLayerAdded;
|
|
SortingLayer.onLayerRemoved += OnSortingLayerRemoved;
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function is called when the behaviour becomes disabled.
|
|
/// </summary>
|
|
protected void OnDisable()
|
|
{
|
|
ShadowCasterGroup2DManager.RemoveFromShadowCasterGroup(this, m_ShadowCasterGroup);
|
|
|
|
if (m_ShadowShape2DProvider != null && m_ShadowShape2DComponent != null)
|
|
m_ShadowShape2DProvider.Disabled(m_ShadowShape2DComponent, m_ShadowMesh);
|
|
|
|
#if UNITY_EDITOR
|
|
SortingLayer.onLayerAdded -= OnSortingLayerAdded;
|
|
SortingLayer.onLayerRemoved -= OnSortingLayerRemoved;
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update is called every frame, if the MonoBehaviour is enabled.
|
|
/// </summary>
|
|
public void Update()
|
|
{
|
|
Renderer renderer;
|
|
m_HasRenderer = TryGetComponent<Renderer>(out renderer);
|
|
|
|
bool rebuildMesh = LightUtility.CheckForChange((int)m_ShadowCastingSource, ref m_PreviousShadowCastingSource);
|
|
rebuildMesh |= LightUtility.CheckForChange((int)edgeProcessing, ref m_PreviousEdgeProcessing);
|
|
rebuildMesh |= edgeProcessing != EdgeProcessing.None && LightUtility.CheckForChange(trimEdge, ref m_PreviousTrimEdge);
|
|
int providerHash = m_ShadowShape2DProvider != null ? m_ShadowShape2DProvider.TypeIdentifierHash : 0;
|
|
rebuildMesh |= LightUtility.CheckForChange(providerHash, ref m_PreviousShadowShape2DProviderHash);
|
|
rebuildMesh |= m_ForceShadowMeshRebuild;
|
|
|
|
if (m_ShadowCastingSource == ShadowCastingSources.ShapeEditor)
|
|
{
|
|
rebuildMesh |= LightUtility.CheckForChange(m_ShapePathHash, ref m_PreviousPathHash);
|
|
if (rebuildMesh)
|
|
{
|
|
SetShadowShape(m_ShadowMesh);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((rebuildMesh || LightUtility.CheckForChange(m_ShadowShape2DComponent, ref m_PreviousShadowShape2DSource)) && m_ShadowShape2DComponent != null)
|
|
{
|
|
SetShadowShape(m_ShadowMesh);
|
|
}
|
|
}
|
|
|
|
m_PreviousShadowCasterGroup = m_ShadowCasterGroup;
|
|
bool addedToNewGroup = ShadowCasterGroup2DManager.AddToShadowCasterGroup(this, ref m_ShadowCasterGroup, ref m_Priority);
|
|
if (addedToNewGroup && m_ShadowCasterGroup != null)
|
|
{
|
|
if (m_PreviousShadowCasterGroup == this)
|
|
ShadowCasterGroup2DManager.RemoveGroup(this);
|
|
|
|
ShadowCasterGroup2DManager.RemoveFromShadowCasterGroup(this, m_PreviousShadowCasterGroup);
|
|
if (m_ShadowCasterGroup == this)
|
|
ShadowCasterGroup2DManager.AddGroup(this);
|
|
}
|
|
|
|
if (LightUtility.CheckForChange(m_ShadowGroup, ref m_PreviousShadowGroup))
|
|
{
|
|
ShadowCasterGroup2DManager.RemoveGroup(this);
|
|
ShadowCasterGroup2DManager.AddGroup(this);
|
|
}
|
|
|
|
if (LightUtility.CheckForChange(m_CastsShadows, ref m_PreviousCastsShadows))
|
|
{
|
|
ShadowCasterGroup2DManager.AddGroup(this);
|
|
}
|
|
|
|
if(m_ShadowMesh != null)
|
|
m_ShadowMesh.UpdateBoundingSphere(transform);
|
|
}
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
internal void DrawPreviewOutline(Matrix4x4 previewMat, float trimionDistance)
|
|
{
|
|
Vector3[] vertices = mesh.vertices;
|
|
int[] triangles = mesh.triangles;
|
|
Vector4[] tangents = mesh.tangents;
|
|
|
|
Handles.color = Color.white;
|
|
for (int i = 0; i < triangles.Length; i += 3)
|
|
{
|
|
int v0 = triangles[i];
|
|
int v1 = triangles[i + 1];
|
|
int v2 = triangles[i + 2];
|
|
|
|
Vector3 pt0 = vertices[v0];
|
|
Vector3 pt1 = vertices[v1];
|
|
Vector3 pt2 = vertices[v2];
|
|
|
|
Vector4 tan0 = tangents[v0];
|
|
Vector4 tan1 = tangents[v1];
|
|
Vector4 tan2 = tangents[v2];
|
|
|
|
Vector3 trimPt0 = new Vector3(pt0.x + trimionDistance * tan0.x, pt0.y + trimionDistance * tan0.y, 0);
|
|
Vector3 trimPt1 = new Vector3(pt1.x + trimionDistance * tan1.x, pt1.y + trimionDistance * tan1.y, 0);
|
|
Vector3 trimPt2 = new Vector3(pt2.x + trimionDistance * tan2.x, pt2.y + trimionDistance * tan2.y, 0);
|
|
|
|
trimPt0 = previewMat.MultiplyPoint(trimPt0);
|
|
trimPt1 = previewMat.MultiplyPoint(trimPt1);
|
|
trimPt2 = previewMat.MultiplyPoint(trimPt2);
|
|
|
|
if (pt0.z == 0 && pt1.z == 0)
|
|
Handles.DrawAAPolyLine(4, new Vector3[] { trimPt0, trimPt1 });
|
|
if (pt1.z == 0 && pt2.z == 0)
|
|
Handles.DrawAAPolyLine(4, new Vector3[] { trimPt1, trimPt2 });
|
|
if (pt2.z == 0 && pt0.z == 0)
|
|
Handles.DrawAAPolyLine(4, new Vector3[] { trimPt2, trimPt0 });
|
|
}
|
|
}
|
|
|
|
internal void DrawPreviewOutline()
|
|
{
|
|
if (m_ShadowMesh != null && mesh != null && m_ShadowCastingSource != ShadowCastingSources.None && enabled)
|
|
{
|
|
|
|
Matrix4x4 outlineMat = Matrix4x4.identity;
|
|
if (isTransformable)
|
|
{
|
|
bool flipX, flipY;
|
|
m_ShadowMesh.GetFlip(out flipX, out flipY);
|
|
Vector3 scale = new Vector3(transform.lossyScale.x * (flipX ? -1 : 1), transform.lossyScale.y * (flipY ? -1 : 1), 1);
|
|
outlineMat = Matrix4x4.TRS(transform.position, transform.rotation, scale);
|
|
}
|
|
|
|
if (edgeProcessing == EdgeProcessing.None)
|
|
DrawPreviewOutline(outlineMat, trimEdge);
|
|
else
|
|
DrawPreviewOutline(outlineMat, 0);
|
|
}
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
ShadowCasterGroup2DManager.RemoveFromShadowCasterGroup(this, m_ShadowCasterGroup);
|
|
|
|
m_ShadowCasterGroup = null;
|
|
m_PreviousShadowCasterGroup = null;
|
|
m_PreviousShadowCastingSource = -1;
|
|
m_PreviousShadowShape2DSource = null;
|
|
m_PreviousShadowShape2DProviderHash = 0;
|
|
m_PreviousTrimEdge = 0;
|
|
m_PreviousEdgeProcessing = -1;
|
|
m_ForceShadowMeshRebuild = true;
|
|
|
|
m_HasRenderer = false;
|
|
m_UseRendererSilhouette = true;
|
|
m_CastsShadows = true;
|
|
m_SelfShadows = false;
|
|
m_ApplyToSortingLayers = null;
|
|
m_ShapePath = null;
|
|
m_ShapePathHash = 0;
|
|
|
|
m_ShadowShape2DComponent = null;
|
|
m_ShadowShape2DProvider = null;
|
|
m_ShadowCastingSource = (ShadowCastingSources)(-1);
|
|
|
|
m_ShadowMesh = null;
|
|
m_CastingOption = ShadowCastingOptions.CastShadow;
|
|
|
|
ToolManager.RestorePreviousTool(); // This is needed in case you have the shape editor active
|
|
|
|
Awake();
|
|
OnEnable();
|
|
}
|
|
#endif
|
|
|
|
#if UNITY_EDITOR
|
|
private void OnSortingLayerAdded(SortingLayer layer)
|
|
{
|
|
var newArray = new int[m_ApplyToSortingLayers.Length + 1];
|
|
for (int i = 0; i < m_ApplyToSortingLayers.Length; i++)
|
|
{
|
|
newArray[i] = m_ApplyToSortingLayers[i];
|
|
}
|
|
newArray[m_ApplyToSortingLayers.Length] = layer.id;
|
|
m_ApplyToSortingLayers = newArray;
|
|
}
|
|
|
|
private void OnSortingLayerRemoved(SortingLayer layer)
|
|
{
|
|
var tempList = new System.Collections.Generic.List<int>();
|
|
foreach (var x in m_ApplyToSortingLayers)
|
|
{
|
|
if (x != layer.id && SortingLayer.IsValid(x))
|
|
tempList.Add(x);
|
|
}
|
|
m_ApplyToSortingLayers = tempList.ToArray();
|
|
}
|
|
#endif
|
|
|
|
|
|
/// <inheritdoc/>
|
|
public void OnBeforeSerialize()
|
|
{
|
|
m_ComponentVersion = k_CurrentComponentVersion;
|
|
|
|
if (m_ShadowMesh != null)
|
|
m_ShadowMesh.OnBeforeSerialize();
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public void OnAfterDeserialize()
|
|
{
|
|
if (m_ComponentVersion < ComponentVersions.Version_2)
|
|
{
|
|
// ----------------------------------------------------
|
|
// m_SelfShadows | m_CastsShadows | m_CastingOption
|
|
// ----------------------------------------------------
|
|
// 0 | 0 | DontCast
|
|
// 0 | 1 | Renderer Only
|
|
// 1 | 0 | Cast Only
|
|
// 1 | 1 | CastAndSelfShadow
|
|
// ----------------------------------------------------
|
|
if (m_SelfShadows && m_CastsShadows)
|
|
m_CastingOption = ShadowCastingOptions.CastAndSelfShadow;
|
|
else if (m_SelfShadows)
|
|
m_CastingOption = ShadowCastingOptions.SelfShadow;
|
|
else if (m_CastsShadows)
|
|
m_CastingOption = ShadowCastingOptions.CastShadow;
|
|
else
|
|
m_CastingOption = ShadowCastingOptions.NoShadow;
|
|
}
|
|
if (m_ComponentVersion < ComponentVersions.Version_3)
|
|
{
|
|
m_ShadowMesh = null;
|
|
m_ForceShadowMeshRebuild = true;
|
|
}
|
|
|
|
if (m_ComponentVersion < ComponentVersions.Version_6)
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (m_ShadowCastingSource == ShadowCastingSources.ShapeProvider)
|
|
m_SelectionSources.selectedHashCode = LightUtility.ProviderToHash(shadowShape2DProvider, shadowShape2DComponent);
|
|
else
|
|
m_SelectionSources.selectedHashCode = (int)m_ShadowCastingSource;
|
|
#endif
|
|
}
|
|
|
|
if(m_ShadowMesh != null)
|
|
m_ShadowMesh.OnAfterDeserialize();
|
|
}
|
|
}
|
|
}
|