Files
2024-11-20 15:21:28 +01:00

290 lines
7.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
namespace EPOOutline
{
public enum CutoutDescriptionType
{
None,
Hash
}
public enum RendererType
{
Unknown,
MeshRenderer,
SkinnedMeshRenderer,
Other
}
[System.Serializable]
public class OutlineTarget
{
[SerializeField]
private float edgeDilateAmount = 5.0f;
[SerializeField]
private float frontEdgeDilateAmount = 5.0f;
[SerializeField]
private float backEdgeDilateAmount = 5.0f;
[SerializeField]
[FormerlySerializedAs("Renderer")]
public Renderer renderer;
[SerializeField]
private RendererType rendererType;
[SerializeField]
public int SubmeshIndex;
[SerializeField]
public BoundsMode BoundsMode = BoundsMode.Default;
[SerializeField]
public Bounds Bounds = new Bounds(Vector3.zero, Vector3.one);
[SerializeField]
public CutoutDescriptionType CutoutDescriptionType;
[SerializeField]
[Range(0.0f, 1.0f)]
public float CutoutThreshold = 0.5f;
[SerializeField]
public CullMode CullMode;
[SerializeField]
private string cutoutTextureName;
[SerializeField]
public DilateRenderMode DilateRenderingMode;
[SerializeField]
private int cutoutTextureIndex;
private int? cutoutTextureId;
private bool rendererIsNotNull;
private bool readyToRender;
public bool RendererIsNotNull
{
get
{
return rendererIsNotNull;
}
}
public Renderer Renderer
{
get
{
return renderer;
}
}
public RendererType RendererType
{
get
{
return rendererType;
}
}
public bool ReadyToRender
{
get
{
return readyToRender;
}
}
public bool UsesCutout
{
get
{
return !string.IsNullOrEmpty(cutoutTextureName);
}
}
public int CutoutTextureIndex
{
get
{
return cutoutTextureIndex;
}
set
{
cutoutTextureIndex = value;
if (cutoutTextureIndex < 0)
{
Debug.LogError("Trying to set cutout texture index less than zero");
cutoutTextureIndex = 0;
}
}
}
public bool CanUseEdgeDilateShift
{
get
{
return !UsesCutout && (renderer is MeshRenderer || renderer is SkinnedMeshRenderer) && (rendererIsNotNull && !renderer.isPartOfStaticBatch && !renderer.gameObject.isStatic);
}
}
public int ShiftedSubmeshIndex
{
get
{
return SubmeshIndex;
}
}
public int CutoutTextureId
{
get
{
if (!cutoutTextureId.HasValue)
cutoutTextureId = Shader.PropertyToID(cutoutTextureName);
return cutoutTextureId.Value;
}
}
public string CutoutTextureName
{
get
{
return cutoutTextureName;
}
set
{
cutoutTextureName = value;
cutoutTextureId = null;
}
}
public float EdgeDilateAmount
{
get
{
return edgeDilateAmount;
}
set
{
if (value < 0)
edgeDilateAmount = 0;
else
edgeDilateAmount = value;
}
}
public float FrontEdgeDilateAmount
{
get
{
return frontEdgeDilateAmount;
}
set
{
if (value < 0)
frontEdgeDilateAmount = 0;
else
frontEdgeDilateAmount = value;
}
}
public float BackEdgeDilateAmount
{
get
{
return backEdgeDilateAmount;
}
set
{
if (value < 0)
backEdgeDilateAmount = 0;
else
backEdgeDilateAmount = value;
}
}
public OutlineTarget()
{
}
public OutlineTarget(Renderer renderer, int submesh = 0)
{
SubmeshIndex = submesh;
this.renderer = renderer;
UpdateRendererType();
CutoutDescriptionType = CutoutDescriptionType.None;
CutoutThreshold = 0.5f;
cutoutTextureId = null;
cutoutTextureName = string.Empty;
CullMode = renderer is SpriteRenderer ? CullMode.Off : CullMode.Back;
DilateRenderingMode = DilateRenderMode.PostProcessing;
frontEdgeDilateAmount = 5.0f;
backEdgeDilateAmount = 5.0f;
edgeDilateAmount = 5.0f;
}
public OutlineTarget(Renderer renderer, string cutoutTextureName, float cutoutThreshold = 0.5f)
{
SubmeshIndex = 0;
this.renderer = renderer;
UpdateRendererType();
CutoutDescriptionType = CutoutDescriptionType.Hash;
cutoutTextureId = Shader.PropertyToID(cutoutTextureName);
CutoutThreshold = cutoutThreshold;
this.cutoutTextureName = cutoutTextureName;
CullMode = renderer is SpriteRenderer ? CullMode.Off : CullMode.Back;
DilateRenderingMode = DilateRenderMode.PostProcessing;
frontEdgeDilateAmount = 5.0f;
backEdgeDilateAmount = 5.0f;
edgeDilateAmount = 5.0f;
}
public void UpdateRendererType()
{
if (rendererType != RendererType.Unknown)
return;
if (renderer is SkinnedMeshRenderer)
rendererType = RendererType.SkinnedMeshRenderer;
else if (renderer is MeshRenderer)
rendererType = RendererType.MeshRenderer;
else
rendererType = RendererType.Other;
}
public void MakeIgnoreOcclusion()
{
if (!rendererIsNotNull)
return;
renderer.allowOcclusionWhenDynamic = false;
}
public void UpdateReadyToRender()
{
rendererIsNotNull = renderer != null;
readyToRender = rendererIsNotNull && renderer.enabled && renderer.gameObject.activeInHierarchy && renderer.isVisible;
}
}
}