123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- using System.Collections.Generic;
- using UnityEngine;
- using System;
- using System.Security.Cryptography;
- namespace EPOOutline
- {
- public enum DilateRenderMode
- {
- PostProcessing,
- EdgeShift
- }
- public enum RenderStyle
- {
- Single = 1,
- FrontBack = 2
- }
- [Flags]
- public enum OutlinableDrawingMode
- {
- Normal = 1,
- ZOnly = 2,
- GenericMask = 4,
- Obstacle = 8,
- Mask = 16
- }
- [Flags]
- public enum RenderersAddingMode
- {
- All = -1,
- None = 0,
- MeshRenderer = 1,
- SkinnedMeshRenderer = 2,
- SpriteRenderer = 4,
- Others = 4096
- }
- public enum BoundsMode
- {
- Default,
- ForceRecalculate,
- Manual
- }
- public enum ComplexMaskingMode
- {
- None,
- ObstaclesMode,
- MaskingMode
- }
- [ExecuteAlways]
- public class Outlinable : MonoBehaviour
- {
- private static List<TargetStateListener> tempListeners = new List<TargetStateListener>();
-
- private static HashSet<Outlinable> outlinables = new HashSet<Outlinable>();
- [System.Serializable]
- public class OutlineProperties
- {
- #pragma warning disable CS0649
- [SerializeField]
- private bool enabled = true;
- public bool Enabled
- {
- get
- {
- return enabled;
- }
- set
- {
- enabled = value;
- }
- }
- [SerializeField]
- private Color color = Color.yellow;
- public Color Color
- {
- get
- {
- return color;
- }
- set
- {
- color = value;
- }
- }
- [SerializeField]
- [Range(0.0f, 1.0f)]
- private float dilateShift = 1.0f;
- public float DilateShift
- {
- get
- {
- return dilateShift;
- }
- set
- {
- dilateShift = value;
- }
- }
- [SerializeField]
- [Range(0.0f, 1.0f)]
- private float blurShift = 1.0f;
- public float BlurShift
- {
- get
- {
- return blurShift;
- }
- set
- {
- blurShift = value;
- }
- }
- [SerializeField, SerializedPassInfo("Fill style", "Hidden/EPO/Fill/")]
- private SerializedPass fillPass = new SerializedPass();
- public SerializedPass FillPass
- {
- get
- {
- return fillPass;
- }
- }
- public void SetFillPass(SerializedPass pass)
- {
- fillPass = pass;
- }
- #pragma warning restore CS0649
- }
- [SerializeField]
- private ComplexMaskingMode complexMaskingMode;
-
- [SerializeField]
- private OutlinableDrawingMode drawingMode = OutlinableDrawingMode.Normal;
- [SerializeField]
- private int outlineLayer = 0;
- [SerializeField]
- private List<OutlineTarget> outlineTargets = new List<OutlineTarget>();
- [SerializeField]
- private RenderStyle renderStyle = RenderStyle.Single;
- #pragma warning disable CS0649
- [SerializeField]
- private OutlineProperties outlineParameters = new OutlineProperties();
- [SerializeField]
- private OutlineProperties backParameters = new OutlineProperties();
- [SerializeField]
- private OutlineProperties frontParameters = new OutlineProperties();
- private bool shouldValidateTargets = false;
- [SerializeField]
- private bool showOutlineTargets=false;
- #pragma warning restore CS0649
- public bool ShowOutLineTargets
- {
- get
- {
- return showOutlineTargets;
- }
- set
- {
- showOutlineTargets = value;
- }
- }
- public RenderStyle RenderStyle
- {
- get
- {
- return renderStyle;
- }
- set
- {
- renderStyle = value;
- }
- }
- public ComplexMaskingMode ComplexMaskingMode
- {
- get
- {
- return complexMaskingMode;
- }
- set
- {
- complexMaskingMode = value;
- }
- }
- public bool ComplexMaskingEnabled
- {
- get
- {
- return complexMaskingMode != ComplexMaskingMode.None;
- }
- }
- public OutlinableDrawingMode DrawingMode
- {
- get
- {
- return drawingMode;
- }
- set
- {
- drawingMode = value;
- }
- }
- public int OutlineLayer
- {
- get
- {
- return outlineLayer;
- }
- set
- {
- outlineLayer = value;
- }
- }
- public IReadOnlyList<OutlineTarget> OutlineTargets
- {
- get
- {
- return outlineTargets;
- }
- }
- public OutlineProperties OutlineParameters
- {
- get
- {
- return outlineParameters;
- }
- }
- public OutlineProperties BackParameters
- {
- get
- {
- return backParameters;
- }
- }
-
- public bool NeedFillMask
- {
- get
- {
- if ((drawingMode & OutlinableDrawingMode.Normal) == 0)
- return false;
- if (renderStyle == RenderStyle.FrontBack)
- return (frontParameters.Enabled || backParameters.Enabled) && (frontParameters.FillPass.Material != null || backParameters.FillPass.Material != null);
- else
- return false;
- }
- }
- public OutlineProperties FrontParameters
- {
- get
- {
- return frontParameters;
- }
- }
- public bool IsObstacle
- {
- get
- {
- return (drawingMode & OutlinableDrawingMode.Obstacle) != 0;
- }
- }
- public bool TryAddTarget(OutlineTarget target)
- {
- outlineTargets.Add(target);
- ValidateTargets();
- return true;
- }
- public void RemoveTarget(OutlineTarget target)
- {
- outlineTargets.Remove(target);
- if (target.renderer != null)
- {
- var listener = target.renderer.GetComponent<TargetStateListener>();
- if (listener == null)
- return;
-
- listener.RemoveCallback(this, UpdateVisibility);
- }
- }
-
- public OutlineTarget this[int index]
- {
- get
- {
- return outlineTargets[index];
- }
- set
- {
- outlineTargets[index] = value;
- ValidateTargets();
- }
- }
- private void Reset()
- {
- AddAllChildRenderersToRenderingList(RenderersAddingMode.SkinnedMeshRenderer | RenderersAddingMode.MeshRenderer | RenderersAddingMode.SpriteRenderer);
- }
- private void OnValidate()
- {
- outlineLayer = Mathf.Clamp(outlineLayer, 0, 63);
- shouldValidateTargets = true;
- }
- private void SubscribeToVisibilityChange(GameObject go)
- {
- var listener = go.GetComponent<TargetStateListener>();
- if (listener == null)
- {
- listener = go.AddComponent<TargetStateListener>();
- #if UNITY_EDITOR
- UnityEditor.EditorUtility.SetDirty(listener);
- UnityEditor.EditorUtility.SetDirty(go);
- #endif
- }
- listener.RemoveCallback(this, UpdateVisibility);
- listener.AddCallback(this, UpdateVisibility);
- listener.ForceUpdate();
- }
- private void UpdateVisibility()
- {
- if (!enabled)
- {
- outlinables.Remove(this);
- return;
- }
- outlineTargets.RemoveAll(x => x.renderer == null);
- foreach (var target in OutlineTargets)
- target.IsVisible = target.renderer.isVisible;
- outlineTargets.RemoveAll(x => x.renderer == null);
- foreach (var target in outlineTargets)
- {
- if (target.IsVisible)
- {
- outlinables.Add(this);
- return;
- }
- }
- outlinables.Remove(this);
- }
- private void OnEnable()
- {
- UpdateVisibility();
- }
- private void OnDisable()
- {
- outlinables.Remove(this);
- }
- private void Awake()
- {
- ValidateTargets();
- }
- private void ValidateTargets()
- {
- outlineTargets.RemoveAll(x => x.renderer == null);
- foreach (var target in outlineTargets)
- SubscribeToVisibilityChange(target.renderer.gameObject);
- }
- private void OnDestroy()
- {
- outlinables.Remove(this);
- }
-
- public static void GetAllActiveOutlinables(Camera camera, List<Outlinable> outlinablesList)
- {
- outlinablesList.Clear();
- foreach (var outlinable in outlinables)
- outlinablesList.Add(outlinable);
- }
- private int GetSubmeshCount(Renderer renderer)
- {
- if (renderer is MeshRenderer)
- return renderer.GetComponent<MeshFilter>().sharedMesh.subMeshCount;
- else if (renderer is SkinnedMeshRenderer)
- return (renderer as SkinnedMeshRenderer).sharedMesh.subMeshCount;
- else
- return 1;
- }
- [ContextMenu("ResetRenderer")]
- public void AddAllChildRenderersToRenderingList(RenderersAddingMode renderersAddingMode = RenderersAddingMode.All)
- {
- outlineTargets.Clear();
- var renderers = GetComponentsInChildren<Renderer>(true);
- foreach (var renderer in renderers)
- {
- if (!MatchingMode(renderer, renderersAddingMode))
- continue;
- var submeshesCount = GetSubmeshCount(renderer);
- for (var index = 0; index < submeshesCount; index++)
- TryAddTarget(new OutlineTarget(renderer, index));
- }
- }
- private void Update()
- {
- if (!shouldValidateTargets)
- return;
- shouldValidateTargets = false;
- ValidateTargets();
- }
- private bool MatchingMode(Renderer renderer, RenderersAddingMode mode)
- {
- return
- (!(renderer is MeshRenderer) && !(renderer is SkinnedMeshRenderer) && !(renderer is SpriteRenderer) && (mode & RenderersAddingMode.Others) != RenderersAddingMode.None) ||
- (renderer is MeshRenderer && (mode & RenderersAddingMode.MeshRenderer) != RenderersAddingMode.None) ||
- (renderer is SpriteRenderer && (mode & RenderersAddingMode.SpriteRenderer) != RenderersAddingMode.None) ||
- (renderer is SkinnedMeshRenderer && (mode & RenderersAddingMode.SkinnedMeshRenderer) != RenderersAddingMode.None);
- }
- #if UNITY_EDITOR
- public void OnDrawGizmosSelected()
- {
- foreach (var target in outlineTargets)
- {
- if (target.Renderer == null || target.BoundsMode != BoundsMode.Manual)
- continue;
- Gizmos.matrix = target.Renderer.transform.localToWorldMatrix;
- Gizmos.color = new Color(1.0f, 0.5f, 0.0f, 0.2f);
- var size = target.Bounds.size;
- var scale = target.Renderer.transform.localScale;
- size.x /= scale.x;
- size.y /= scale.y;
- size.z /= scale.z;
- Gizmos.DrawCube(target.Bounds.center, size);
- Gizmos.DrawWireCube(target.Bounds.center, size);
- }
- }
- #endif
- }
- }
|