From 03465e641e65f823e948e6077cd3db0350e969d0 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Tue, 10 Sep 2019 11:39:45 +0300 Subject: [PATCH 01/20] Added enabled flag to OutlineLayer --- .../Examples/Prefabs/TestOutlineLayers.asset | 3 ++ .../Editor/Scripts/OutlineEditorUtility.cs | 13 +++++-- .../Scripts/OutlineLayerCollectionEditor.cs | 18 +++++++++- .../Runtime/Scripts/OutlineLayer.cs | 34 ++++++++++++++++--- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/Assets/Examples/Prefabs/TestOutlineLayers.asset b/Assets/Examples/Prefabs/TestOutlineLayers.asset index 4cb159e..4db7174 100644 --- a/Assets/Examples/Prefabs/TestOutlineLayers.asset +++ b/Assets/Examples/Prefabs/TestOutlineLayers.asset @@ -19,15 +19,18 @@ MonoBehaviour: _outlineWidth: 5 _outlineIntensity: 2 _outlineMode: 0 + _enabled: 1 - _settings: _outlineSettings: {fileID: 0} _outlineColor: {r: 1, g: 1, b: 0, a: 1} _outlineWidth: 15 _outlineIntensity: 2 _outlineMode: 1 + _enabled: 1 - _settings: _outlineSettings: {fileID: 0} _outlineColor: {r: 1, g: 0, b: 1, a: 1} _outlineWidth: 4 _outlineIntensity: 2 _outlineMode: 0 + _enabled: 1 diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs index 6e04ee0..5b8ff8f 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs @@ -106,8 +106,17 @@ public static void RenderPreview(OutlineLayer layer, int layerIndex, bool showOb EditorGUI.indentLevel += 1; EditorGUILayout.PrefixLabel("Layer #" + layerIndex.ToString()); EditorGUI.indentLevel -= 1; - EditorGUILayout.IntField(layer.OutlineWidth, GUILayout.MaxWidth(100)); - EditorGUILayout.ColorField(layer.OutlineColor, GUILayout.MinWidth(100)); + + if (layer.Enabled) + { + EditorGUILayout.IntField(layer.OutlineWidth, GUILayout.MaxWidth(100)); + EditorGUILayout.ColorField(layer.OutlineColor, GUILayout.MinWidth(100)); + } + else + { + EditorGUILayout.LabelField("Disabled."); + } + EditorGUILayout.EndHorizontal(); if (showObjects) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs index a3fc6bb..e1d7dd6 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs @@ -30,7 +30,23 @@ public override void OnInspectorGUI() { EditorGUILayout.Space(); var rect = EditorGUILayout.BeginHorizontal(); - EditorGUILayout.PrefixLabel("Layer #" + i.ToString()); + //EditorGUILayout.PrefixLabel("Layer #" + i.ToString()); + + var enabled = EditorGUILayout.ToggleLeft("Layer #" + i.ToString(), _layers[i].Enabled); + + if (enabled != _layers[i].Enabled) + { + if (enabled) + { + Undo.RecordObject(_layers, "Enable Layer"); + } + else + { + Undo.RecordObject(_layers, "Disable Layer"); + } + + _layers[i].Enabled = enabled; + } GUILayout.FlexibleSpace(); diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 5fb6bc3..3f850c3 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -22,6 +22,8 @@ public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, [SerializeField, HideInInspector] private OutlineSettingsInstance _settings = new OutlineSettingsInstance(); + [SerializeField, HideInInspector] + private bool _enabled = true; private OutlineLayerCollection _parentCollection; private Dictionary _outlineObjects = new Dictionary(); @@ -31,6 +33,25 @@ public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, #region interface + /// + /// Gets or sets a value indicating whether the layer is enabled. + /// + public bool Enabled + { + get + { + return _enabled; + } + set + { + if (_enabled != value) + { + _enabled = value; + _changed = true; + } + } + } + /// /// Initializes a new instance of the class. /// @@ -131,13 +152,16 @@ internal void SetCollection(OutlineLayerCollection collection) internal void Render(OutlineRenderer renderer, OutlineResources resources) { - _settings.SetResources(resources); - - foreach (var kvp in _outlineObjects) + if (_enabled) { - if (kvp.Key) + _settings.SetResources(resources); + + foreach (var kvp in _outlineObjects) { - renderer.RenderSingleObject(kvp.Value, _settings.OutlineMaterials); + if (kvp.Key) + { + renderer.RenderSingleObject(kvp.Value, _settings.OutlineMaterials); + } } } } From 34b66d320db4bb5b9447407668990fce85ae826f Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Tue, 10 Sep 2019 11:50:36 +0300 Subject: [PATCH 02/20] Added more info to outline layer preview --- .../UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs index 5b8ff8f..10ee383 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEditorUtility.cs @@ -109,6 +109,7 @@ public static void RenderPreview(OutlineLayer layer, int layerIndex, bool showOb if (layer.Enabled) { + EditorGUILayout.LabelField(layer.OutlineMode == OutlineMode.Solid ? layer.OutlineMode.ToString() : string.Format("Blurred ({0})", layer.OutlineIntensity), GUILayout.MaxWidth(70)); EditorGUILayout.IntField(layer.OutlineWidth, GUILayout.MaxWidth(100)); EditorGUILayout.ColorField(layer.OutlineColor, GUILayout.MinWidth(100)); } From 4546795350d7b7ff0ec582c83a39a6000195bd94 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Tue, 10 Sep 2019 15:04:22 +0300 Subject: [PATCH 03/20] OutlineLayer properties now throw if OutlineSettings is assigned --- .../Scripts/OutlineSettingsInstance.cs | 17 ++++++++++++++++ .../Helpers/IOutlineSettingsExTests.cs | 20 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs index cb982da..b8509da 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineSettingsInstance.cs @@ -131,6 +131,8 @@ public Color OutlineColor } set { + ThrowIfSettingsAssigned(); + if (_outlineColor != value) { _outlineColor = value; @@ -153,6 +155,8 @@ public int OutlineWidth } set { + ThrowIfSettingsAssigned(); + value = Mathf.Clamp(value, OutlineRenderer.MinWidth, OutlineRenderer.MaxWidth); if (_outlineWidth != value) @@ -177,6 +181,8 @@ public float OutlineIntensity } set { + ThrowIfSettingsAssigned(); + value = Mathf.Clamp(value, OutlineRenderer.MinIntensity, OutlineRenderer.MaxIntensity); if (_outlineIntensity != value) @@ -201,6 +207,8 @@ public OutlineMode OutlineMode } set { + ThrowIfSettingsAssigned(); + if (_outlineMode != value) { _outlineMode = value; @@ -249,6 +257,15 @@ public void Dispose() #endregion #region implementation + + private void ThrowIfSettingsAssigned() + { + if (_outlineSettings) + { + throw new InvalidOperationException("The outline parameters cannot be altered when OutlineSettings is set."); + } + } + #endregion } } diff --git a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/Helpers/IOutlineSettingsExTests.cs b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/Helpers/IOutlineSettingsExTests.cs index 0f38e19..c39e3bb 100644 --- a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/Helpers/IOutlineSettingsExTests.cs +++ b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/Helpers/IOutlineSettingsExTests.cs @@ -74,5 +74,25 @@ public void OutlineSettings_DoesNotSetsChangedOnSameValue() Assert.IsFalse(_changeTracking.IsChanged); } } + + [Test] + public void OutlineSettings_MakesOtherSettersThrow() + { + var settings = ScriptableObject.CreateInstance(); + + try + { + _settings.OutlineSettings = settings; + + Assert.Throws(() => _settings.OutlineColor = Color.blue); + Assert.Throws(() => _settings.OutlineWidth = 12); + Assert.Throws(() => _settings.OutlineMode = OutlineMode.Blurred); + Assert.Throws(() => _settings.OutlineIntensity = 17); + } + finally + { + UnityEngine.Object.DestroyImmediate(settings); + } + } } } From da29b57863b5061e9c1763060d24461f5aa1dc54 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Tue, 10 Sep 2019 15:07:54 +0300 Subject: [PATCH 04/20] CHANGELOG update --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f485942..08181a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/). +## [0.6.0] - unreleased + +### Added +- Added `OutlineLayer.Enabled` flag. +- Added more info to the `OutlineLayer` preview inspector. + +### Changed +- `IOutilneSettings` setters now throw if overriden. + ## [0.5.0] - 2019.09.09 Features editor UI and unit tests. @@ -18,7 +27,7 @@ Features editor UI and unit tests. ## [0.4.0] - 2019.08.31 -Features blurred otulines. +Features blurred outlines. ### Added - Added Gauss blurring to outlines. From f6d145ee60194a1e544b3acdefb9bfe80c50d636 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Wed, 11 Sep 2019 18:11:57 +0300 Subject: [PATCH 05/20] Added OutlineLayer.Priority --- .../Scripts/OutlineLayerCollectionEditor.cs | 11 ++++-- .../Runtime/Scripts/OutlineEffect.cs | 29 ++++++--------- .../Runtime/Scripts/OutlineLayer.cs | 36 ++++++++++++++++++- .../Runtime/Scripts/OutlineLayerCollection.cs | 9 +++++ 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs index e1d7dd6..2fa93cc 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs @@ -29,9 +29,8 @@ public override void OnInspectorGUI() for (var i = 0; i < _layers.Count; i++) { EditorGUILayout.Space(); - var rect = EditorGUILayout.BeginHorizontal(); - //EditorGUILayout.PrefixLabel("Layer #" + i.ToString()); + var rect = EditorGUILayout.BeginHorizontal(); var enabled = EditorGUILayout.ToggleLeft("Layer #" + i.ToString(), _layers[i].Enabled); if (enabled != _layers[i].Enabled) @@ -65,6 +64,14 @@ public override void OnInspectorGUI() GUI.Box(rect, GUIContent.none); + var priority = EditorGUILayout.IntField("Layer Priority", _layers[i].Priority); + + if (priority != _layers[i].Priority) + { + Undo.RecordObject(_layers, "Set Layer Priority"); + _layers[i].Priority = priority; + } + OutlineEditorUtility.Render(_layers[i], _layers); } } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index a5bfc3f..1a035ff 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -2,7 +2,7 @@ // See the LICENSE.md file in the project root for more information. using System; -using System.Collections.Generic; +using System.Runtime.CompilerServices; using UnityEngine; using UnityEngine.Rendering; @@ -67,11 +67,7 @@ public OutlineLayerCollection OutlineLayers { get { - if (_outlineLayers == null) - { - _outlineLayers = ScriptableObject.CreateInstance(); - } - + CreateLayersIfNeeded(); return _outlineLayers; } set @@ -98,10 +94,7 @@ public void ShareLayersWith(OutlineEffect other) { if (other) { - if (_outlineLayers == null) - { - _outlineLayers = ScriptableObject.CreateInstance(); - } + CreateLayersIfNeeded(); other._outlineLayers = _outlineLayers; other._changed = true; @@ -213,13 +206,7 @@ private void FillCommandBuffer() { using (var renderer = new OutlineRenderer(_commandBuffer, BuiltinRenderTextureType.CameraTarget)) { - for (var i = 0; i < _outlineLayers.Count; ++i) - { - if (_outlineLayers[i] != null) - { - _outlineLayers[i].Render(renderer, _outlineResources); - } - } + _outlineLayers.Render(renderer, _outlineResources); } } else @@ -230,9 +217,13 @@ private void FillCommandBuffer() _changed = false; } - private void OnChanged(object sender, EventArgs args) + private void CreateLayersIfNeeded() { - _changed = true; + if (ReferenceEquals(_outlineLayers, null)) + { + _outlineLayers = ScriptableObject.CreateInstance(); + _outlineLayers.name = "OutlineLayers"; + } } #endregion diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 3f850c3..0f0d231 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -16,13 +16,15 @@ namespace UnityFx.Outline /// /// [Serializable] - public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, IChangeTracking + public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, IChangeTracking, IComparable { #region data [SerializeField, HideInInspector] private OutlineSettingsInstance _settings = new OutlineSettingsInstance(); [SerializeField, HideInInspector] + private int _zOrder; + [SerializeField, HideInInspector] private bool _enabled = true; private OutlineLayerCollection _parentCollection; @@ -36,6 +38,7 @@ public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, /// /// Gets or sets a value indicating whether the layer is enabled. /// + /// public bool Enabled { get @@ -52,6 +55,27 @@ public bool Enabled } } + /// + /// Gets or sets the layer priority. Layers with greater values are rendered on top of layers with lower priority. + /// Layers with equal priorities are rendered according to index in parent collection. + /// + /// + public int Priority + { + get + { + return _zOrder; + } + set + { + if (_zOrder != value) + { + _zOrder = value; + _changed = true; + } + } + } + /// /// Initializes a new instance of the class. /// @@ -345,6 +369,16 @@ public void AcceptChanges() #endregion + #region IComparable + + /// + public int CompareTo(OutlineLayer other) + { + throw new NotImplementedException(); + } + + #endregion + #region implementation #endregion } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs index 9722da1..0ccc73e 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs @@ -45,6 +45,15 @@ internal void UpdateChanged() } } + internal void Render(OutlineRenderer renderer, OutlineResources resources) + { + // TODO: Render layers in order defined with layer priorities. + for (var i = 0; i < _layers.Count; ++i) + { + _layers[i].Render(renderer, resources); + } + } + #endregion #region ScriptableObject From 33e9ec89233c417491adee27f8c2d67a72c74840 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 12 Sep 2019 13:26:06 +0300 Subject: [PATCH 06/20] Implemeted lazy layer sorting --- .../Runtime/Scripts/OutlineLayerCollection.cs | 57 ++++++++++++++++++- .../Scripts/OutlineLayerCollectionTests.cs | 20 +++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs index 0ccc73e..91a237e 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs @@ -20,15 +20,42 @@ public sealed class OutlineLayerCollection : ScriptableObject, IList + { + public int Compare(OutlineLayer x, OutlineLayer y) + { + return x.Priority - y.Priority; + } + } + [SerializeField, HideInInspector] private List _layers = new List(); + private List _sortedLayers = new List(); + private OutlineLayerComparer _sortComparer = new OutlineLayerComparer(); + private bool _orderChanged = true; private bool _changed = true; #endregion #region interface + /// + /// Gets layers ordered by . + /// + public OutlineLayer[] SortedLayers + { + get + { + UpdateSortedLayersIdNeeded(); + return _sortedLayers.ToArray(); + } + } + + #endregion + + #region internals + internal void Reset() { foreach (var layer in _layers) @@ -47,10 +74,11 @@ internal void UpdateChanged() internal void Render(OutlineRenderer renderer, OutlineResources resources) { - // TODO: Render layers in order defined with layer priorities. - for (var i = 0; i < _layers.Count; ++i) + UpdateSortedLayersIdNeeded(); + + foreach (var layer in _sortedLayers) { - _layers[i].Render(renderer, resources); + layer.Render(renderer, resources); } } @@ -95,6 +123,8 @@ public OutlineLayer this[int layerIndex] _layers[layerIndex].SetCollection(null); _layers[layerIndex] = value; + + _orderChanged = true; _changed = true; } } @@ -124,6 +154,8 @@ public void Insert(int index, OutlineLayer layer) layer.SetCollection(this); _layers.Insert(index, layer); + + _orderChanged = true; _changed = true; } } @@ -135,6 +167,8 @@ public void RemoveAt(int index) { _layers[index].SetCollection(null); _layers.RemoveAt(index); + + _orderChanged = true; _changed = true; } } @@ -174,6 +208,8 @@ public void Add(OutlineLayer layer) layer.SetCollection(this); _layers.Add(layer); + + _orderChanged = true; _changed = true; } } @@ -185,7 +221,9 @@ public bool Remove(OutlineLayer layer) { layer.SetCollection(null); + _sortedLayers.Remove(layer); _changed = true; + return true; } @@ -203,6 +241,7 @@ public void Clear() } _layers.Clear(); + _sortedLayers.Clear(); _changed = true; } } @@ -279,6 +318,18 @@ public void AcceptChanges() #endregion #region implementation + + private void UpdateSortedLayersIdNeeded() + { + if (_orderChanged) + { + _sortedLayers.Clear(); + _sortedLayers.AddRange(_layers); + _sortedLayers.Sort(_sortComparer); + _orderChanged = false; + } + } + #endregion } } diff --git a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerCollectionTests.cs b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerCollectionTests.cs index d3cc51e..78177c6 100644 --- a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerCollectionTests.cs +++ b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerCollectionTests.cs @@ -295,5 +295,25 @@ public void AcceptChanges_ResetsChanged() Assert.IsFalse(_layerCollection.IsChanged); } + + [Test] + public void SortedLayers_IsSortedByPriority() + { + var layer1 = new OutlineLayer() + { + Priority = 2 + }; + + var layer2 = new OutlineLayer(); + var layer3 = new OutlineLayer(); + + _layerCollection.Add(layer1); + _layerCollection.Add(layer2); + _layerCollection.Add(layer3); + + Assert.AreEqual(layer2, _layerCollection.SortedLayers[0]); + Assert.AreEqual(layer3, _layerCollection.SortedLayers[1]); + Assert.AreEqual(layer1, _layerCollection.SortedLayers[2]); + } } } From d286dfeff5b7f78291aa5a10040d2856c13438e7 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 13 Sep 2019 11:01:10 +0300 Subject: [PATCH 07/20] Added possibility to edit renderers for a layer gameobject --- .../Scripts/OutlineBehaviour.Renderers.cs | 54 +----- .../Runtime/Scripts/OutlineLayer.Renderers.cs | 155 ++++++++++++++++++ .../Scripts/OutlineLayer.Renderers.cs.meta | 11 ++ .../Runtime/Scripts/OutlineLayer.cs | 61 +++---- .../Runtime/Scripts/OutlineRenderer.cs | 8 +- 5 files changed, 195 insertions(+), 94 deletions(-) create mode 100644 Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs create mode 100644 Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs.meta diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.Renderers.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.Renderers.cs index d2304d6..70989b9 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.Renderers.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.Renderers.cs @@ -35,7 +35,7 @@ private void OnWillRenderObject() } } - private sealed class RendererCollection : IList + private sealed class RendererCollection : ICollection { #region data @@ -73,58 +73,6 @@ public void Reset() #endregion - #region IList - - public Renderer this[int index] - { - get - { - return _renderers[index]; - } - set - { - if (index < 0 || index >= _renderers.Count) - { - throw new ArgumentOutOfRangeException("index"); - } - - Validate(value); - Release(_renderers[index]); - Init(value); - - _renderers[index] = value; - } - } - - public int IndexOf(Renderer renderer) - { - return _renderers.IndexOf(renderer); - } - - public void Insert(int index, Renderer renderer) - { - if (index < 0 || index >= _renderers.Count) - { - throw new ArgumentOutOfRangeException("index"); - } - - Validate(renderer); - Init(renderer); - - _renderers.Insert(index, renderer); - } - - public void RemoveAt(int index) - { - if (index >= 0 && index < _renderers.Count) - { - Release(_renderers[index]); - _renderers.RemoveAt(index); - } - } - - #endregion - #region ICollection public int Count diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs new file mode 100644 index 0000000..d84b264 --- /dev/null +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs @@ -0,0 +1,155 @@ +// Copyright (C) 2019 Alexander Bogarsukov. All rights reserved. +// See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using UnityEngine; + +namespace UnityFx.Outline +{ + partial class OutlineLayer + { + #region interface + #endregion + + #region implementation + + private sealed class RendererCollection : ICollection + { + #region data + + private readonly List _renderers = new List(); + private readonly GameObject _go; + + #endregion + + #region interface + + internal RendererCollection(GameObject parent) + { + Debug.Assert(parent); + _go = parent; + } + + internal RendererCollection(GameObject parent, int ignoreMask) + { + Debug.Assert(parent); + + _go = parent; + Reset(ignoreMask); + } + + public void Reset(int ignoreLayerMask) + { + _renderers.Clear(); + + var renderers = _go.GetComponentsInChildren(); + + if (renderers != null) + { + if (ignoreLayerMask != 0) + { + foreach (var renderer in renderers) + { + if ((renderer.gameObject.layer & ignoreLayerMask) == 0) + { + _renderers.Add(renderer); + } + } + } + else + { + foreach (var renderer in renderers) + { + _renderers.Add(renderer); + } + } + } + } + + #endregion + + #region ICollection + + public int Count + { + get + { + return _renderers.Count; + } + } + + public bool IsReadOnly + { + get + { + return false; + } + } + + public void Add(Renderer renderer) + { + Validate(renderer); + + _renderers.Add(renderer); + } + + public bool Remove(Renderer renderer) + { + return _renderers.Remove(renderer); + } + + public void Clear() + { + _renderers.Clear(); + } + + public bool Contains(Renderer renderer) + { + return _renderers.Contains(renderer); + } + + public void CopyTo(Renderer[] array, int arrayIndex) + { + _renderers.CopyTo(array, arrayIndex); + } + + #endregion + + #region IEnumerable + + public IEnumerator GetEnumerator() + { + return _renderers.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _renderers.GetEnumerator(); + } + + #endregion + + #region implementation + + private void Validate(Renderer renderer) + { + if (renderer == null) + { + throw new ArgumentNullException("renderer"); + } + + if (!renderer.transform.IsChildOf(_go.transform)) + { + throw new ArgumentException(string.Format("Only children of the {0} are allowed.", _go.name), "renderer"); + } + } + + #endregion + } + + #endregion + } +} diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs.meta b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs.meta new file mode 100644 index 0000000..a2ecbf0 --- /dev/null +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f98c44e515873c54180f1d3b1037f999 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 0f0d231..7c23d7a 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -16,7 +16,7 @@ namespace UnityFx.Outline /// /// [Serializable] - public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, IChangeTracking, IComparable + public sealed partial class OutlineLayer : ICollection, IOutlineSettingsEx, IChangeTracking { #region data @@ -28,7 +28,7 @@ public sealed class OutlineLayer : ICollection, IOutlineSettingsEx, private bool _enabled = true; private OutlineLayerCollection _parentCollection; - private Dictionary _outlineObjects = new Dictionary(); + private Dictionary _outlineObjects = new Dictionary(); private bool _changed; #endregion @@ -110,33 +110,32 @@ public void Add(GameObject go, int ignoreLayerMask) if (!_outlineObjects.ContainsKey(go)) { - var renderers = go.GetComponentsInChildren(); - - if (renderers != null) - { - if (renderers.Length > 0 && ignoreLayerMask != 0) - { - var filteredRenderers = new List(renderers.Length); + _outlineObjects.Add(go, new RendererCollection(go, ignoreLayerMask)); + _changed = true; + } + } - for (var i = 0; i < renderers.Length; ++i) - { - if ((renderers[i].gameObject.layer & ignoreLayerMask) == 0) - { - filteredRenderers.Add(renderers[i]); - } - } + /// + /// Attempts to get renderers assosiated with the specified . + /// + /// Thrown if is . + public bool TryGetRenderers(GameObject go, out ICollection renderers) + { + if (go == null) + { + throw new ArgumentNullException("go"); + } - renderers = filteredRenderers.ToArray(); - } - } - else - { - renderers = new Renderer[0]; - } + RendererCollection result; - _outlineObjects.Add(go, renderers); - _changed = true; + if (_outlineObjects.TryGetValue(go, out result)) + { + renderers = result; + return true; } + + renderers = null; + return false; } #endregion @@ -182,7 +181,7 @@ internal void Render(OutlineRenderer renderer, OutlineResources resources) foreach (var kvp in _outlineObjects) { - if (kvp.Key) + if (kvp.Key && kvp.Key.activeInHierarchy) { renderer.RenderSingleObject(kvp.Value, _settings.OutlineMaterials); } @@ -369,16 +368,6 @@ public void AcceptChanges() #endregion - #region IComparable - - /// - public int CompareTo(OutlineLayer other) - { - throw new NotImplementedException(); - } - - #endregion - #region implementation #endregion } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index c0bc1e4..5ba1ab8 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -103,7 +103,7 @@ public OutlineRenderer(CommandBuffer commandBuffer, RenderTargetIdentifier dst) /// /// Adds commands for rendering single outline object. /// - public void RenderSingleObject(IList renderers, OutlineMaterialSet materials) + public void RenderSingleObject(IEnumerable renderers, OutlineMaterialSet materials) { if (renderers == null) { @@ -118,11 +118,9 @@ public void RenderSingleObject(IList renderers, OutlineMaterialSet mat _commandBuffer.SetRenderTarget(_maskRtId); _commandBuffer.ClearRenderTarget(false, true, Color.black); - for (var i = 0; i < renderers.Count; ++i) + foreach (var renderer in renderers) { - var renderer = renderers[i]; - - if (renderer && renderer.gameObject.activeInHierarchy && renderer.enabled) + if (renderer && renderer.enabled && renderer.gameObject.activeInHierarchy) { for (var j = 0; j < renderer.sharedMaterials.Length; ++j) { From ce3e2dac60e0b578a6b428cab76c0e7b3b31a5c2 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 13 Sep 2019 12:20:57 +0300 Subject: [PATCH 08/20] Added RenderEvent property to OutlineEffect --- .../Editor/Scripts/OutlineEffectEditor.cs | 22 +++++++++- .../Runtime/Scripts/OutlineEffect.cs | 42 +++++++++++++++++-- .../Runtime/Scripts/OutlineLayer.cs | 5 +++ .../Runtime/Scripts/OutlineLayerCollection.cs | 8 ++++ .../Runtime/Scripts/OutlineRenderer.cs | 8 ++-- 5 files changed, 76 insertions(+), 9 deletions(-) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs index f6fb00d..566ff73 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs @@ -5,7 +5,8 @@ using System.Collections; using System.Collections.Generic; using UnityEditor; -using UnityEngine; +using UnityEditor.SceneManagement; +using UnityEngine.Rendering; namespace UnityFx.Outline { @@ -24,6 +25,25 @@ public override void OnInspectorGUI() { base.OnInspectorGUI(); + EditorGUI.BeginChangeCheck(); + var e = (CameraEvent)EditorGUILayout.EnumPopup("Render Event", _effect.RenderEvent); + + if (e != _effect.RenderEvent) + { + Undo.RecordObject(_effect, "Set Render Event"); + _effect.RenderEvent = e; + } + + if (EditorGUI.EndChangeCheck()) + { + EditorUtility.SetDirty(_effect.gameObject); + + if (!EditorApplication.isPlayingOrWillChangePlaymode) + { + EditorSceneManager.MarkSceneDirty(_effect.gameObject.scene); + } + } + if (_effect.OutlineLayers.Count > 0) { _previewOpened = EditorGUILayout.Foldout(_previewOpened, "Preview", true); diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index 1a035ff..eab5540 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -25,6 +25,8 @@ public sealed partial class OutlineEffect : MonoBehaviour private OutlineResources _outlineResources; [SerializeField] private OutlineLayerCollection _outlineLayers; + [SerializeField, HideInInspector] + private CameraEvent _cameraEvent = OutlineRenderer.RenderEvent; private CommandBuffer _commandBuffer; private bool _changed; @@ -85,6 +87,35 @@ public OutlineLayerCollection OutlineLayers } } + /// + /// Gets or sets used to render the outlines. + /// + public CameraEvent RenderEvent + { + get + { + return _cameraEvent; + } + set + { + if (_cameraEvent != value) + { + if (_commandBuffer != null) + { + var camera = GetComponent(); + + if (camera) + { + camera.RemoveCommandBuffer(_cameraEvent, _commandBuffer); + camera.AddCommandBuffer(value, _commandBuffer); + } + } + + _cameraEvent = value; + } + } + } + /// /// Shares with another instance. /// @@ -126,11 +157,14 @@ private void OnEnable() if (camera) { - _commandBuffer = new CommandBuffer(); - _commandBuffer.name = string.Format("{0} - {1}", GetType().Name, name); + _commandBuffer = new CommandBuffer + { + name = string.Format("{0} - {1}", GetType().Name, name) + }; + _changed = true; - camera.AddCommandBuffer(OutlineRenderer.RenderEvent, _commandBuffer); + camera.AddCommandBuffer(_cameraEvent, _commandBuffer); } } @@ -140,7 +174,7 @@ private void OnDisable() if (camera) { - camera.RemoveCommandBuffer(OutlineRenderer.RenderEvent, _commandBuffer); + camera.RemoveCommandBuffer(_cameraEvent, _commandBuffer); } if (_commandBuffer != null) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 7c23d7a..c86b21c 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -70,6 +70,11 @@ public int Priority { if (_zOrder != value) { + if (_parentCollection != null) + { + _parentCollection.SetOrderChanged(); + } + _zOrder = value; _changed = true; } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs index 91a237e..77b8a65 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayerCollection.cs @@ -56,6 +56,12 @@ public OutlineLayer[] SortedLayers #region internals + internal void SetOrderChanged() + { + _orderChanged = true; + _changed = true; + } + internal void Reset() { foreach (var layer in _layers) @@ -92,6 +98,8 @@ private void OnEnable() { layer.SetCollection(this); } + + _orderChanged = true; } #endregion diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs index 5ba1ab8..0866684 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineRenderer.cs @@ -118,13 +118,13 @@ public void RenderSingleObject(IEnumerable renderers, OutlineMaterialS _commandBuffer.SetRenderTarget(_maskRtId); _commandBuffer.ClearRenderTarget(false, true, Color.black); - foreach (var renderer in renderers) + foreach (var r in renderers) { - if (renderer && renderer.enabled && renderer.gameObject.activeInHierarchy) + if (r && r.enabled && r.gameObject.activeInHierarchy) { - for (var j = 0; j < renderer.sharedMaterials.Length; ++j) + for (var j = 0; j < r.sharedMaterials.Length; ++j) { - _commandBuffer.DrawRenderer(renderer, materials.RenderMaterial, j); + _commandBuffer.DrawRenderer(r, materials.RenderMaterial, j); } } } From e5f625958f9755423d10b7fdcce0b33e5297b31b Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 13 Sep 2019 12:48:12 +0300 Subject: [PATCH 09/20] Added OutlineLayer name --- .../Scripts/OutlineLayerCollectionEditor.cs | 8 ++ .../Runtime/Scripts/OutlineLayer.cs | 103 ++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs index 2fa93cc..1c6f835 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs @@ -64,6 +64,14 @@ public override void OnInspectorGUI() GUI.Box(rect, GUIContent.none); + var name = EditorGUILayout.TextField("Layer Name", _layers[i].Name); + + if (name != _layers[i].Name) + { + Undo.RecordObject(_layers, "Set Layer Name"); + _layers[i].Name = name; + } + var priority = EditorGUILayout.IntField("Layer Priority", _layers[i].Priority); if (priority != _layers[i].Priority) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index c86b21c..6a38fca 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.Text; using UnityEngine; namespace UnityFx.Outline @@ -23,6 +24,8 @@ public sealed partial class OutlineLayer : ICollection, IOutlineSett [SerializeField, HideInInspector] private OutlineSettingsInstance _settings = new OutlineSettingsInstance(); [SerializeField, HideInInspector] + private string _name; + [SerializeField, HideInInspector] private int _zOrder; [SerializeField, HideInInspector] private bool _enabled = true; @@ -35,6 +38,21 @@ public sealed partial class OutlineLayer : ICollection, IOutlineSett #region interface + /// + /// Gets or sets layer name. + /// + public string Name + { + get + { + return _name; + } + set + { + _name = value; + } + } + /// /// Gets or sets a value indicating whether the layer is enabled. /// @@ -81,6 +99,22 @@ public int Priority } } + /// + /// Gets index of the layer in parent collection. + /// + public int Index + { + get + { + if (_parentCollection != null) + { + return _parentCollection.IndexOf(this); + } + + return -1; + } + } + /// /// Initializes a new instance of the class. /// @@ -88,6 +122,14 @@ public OutlineLayer() { } + /// + /// Initializes a new instance of the class. + /// + public OutlineLayer(string name) + { + _name = name; + } + /// /// Initializes a new instance of the class. /// @@ -102,6 +144,21 @@ public OutlineLayer(OutlineSettings settings) _settings.OutlineSettings = settings; } + /// + /// Initializes a new instance of the class. + /// + /// Thrown if is . + public OutlineLayer(string name, OutlineSettings settings) + { + if (settings == null) + { + throw new ArgumentNullException("settings"); + } + + _name = name; + _settings.OutlineSettings = settings; + } + /// /// Adds a new object to the layer. /// @@ -373,6 +430,52 @@ public void AcceptChanges() #endregion + #region Object + + public override string ToString() + { + var text = new StringBuilder(); + + if (string.IsNullOrEmpty(_name)) + { + text.Append("OutlineLayer"); + } + else + { + text.Append(_name); + } + + if (_parentCollection != null) + { + text.Append(" #"); + text.Append(_parentCollection.IndexOf(this)); + } + + if (_zOrder > 0) + { + text.Append(" z"); + text.Append(_zOrder); + } + + if (_outlineObjects.Count > 0) + { + text.Append(" ("); + + foreach (var go in _outlineObjects.Keys) + { + text.Append(go.name); + text.Append(", "); + } + + text.Remove(text.Length - 2, 2); + text.Append(")"); + } + + return string.Format("{0}", text); + } + + #endregion + #region implementation #endregion } From 3e6bd1a7c4f70521e1fee6e19ad64044ead99a9b Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Fri, 13 Sep 2019 12:51:16 +0300 Subject: [PATCH 10/20] CHANGELOG update --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08181a7..b9575ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/); this proj ## [0.6.0] - unreleased ### Added -- Added `OutlineLayer.Enabled` flag. +- Added `OutlineLayer.Enabled`. +- Added `OutlineLayer.Name`. +- Added possibility to change render order of layers via `OutlineLayer.Priority`. +- Added possibility to edit renderers of an `OutlineLayer`. +- Added possibility to alter `CameraEvent` used to render `OutlineEffect`. - Added more info to the `OutlineLayer` preview inspector. ### Changed From 7dacdba7571603966b7b9499cd12fbf3c7d2a80f Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Wed, 18 Sep 2019 18:37:42 +0300 Subject: [PATCH 11/20] Added command buffer update counters --- .../UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs | 3 +++ .../Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index ad60cec..b1c0878 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -33,6 +33,7 @@ public sealed partial class OutlineBehaviour : MonoBehaviour, IOutlineSettingsEx private Dictionary _cameraMap = new Dictionary(); private float _cameraMapUpdateTimer; + private int _commandBufferUpdateCounter; #endregion @@ -156,6 +157,7 @@ private void Update() } _outlineSettings.AcceptChanges(); + _commandBufferUpdateCounter++; } } @@ -306,6 +308,7 @@ private void CreateCommandBufferIfNeeded() { _commandBuffer = new CommandBuffer(); _commandBuffer.name = string.Format("{0} - {1}", GetType().Name, name); + _commandBufferUpdateCounter = 0; } } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index eab5540..3f4d61e 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -29,6 +29,7 @@ public sealed partial class OutlineEffect : MonoBehaviour private CameraEvent _cameraEvent = OutlineRenderer.RenderEvent; private CommandBuffer _commandBuffer; + private int _commandBufferUpdateCounter; private bool _changed; #endregion @@ -162,6 +163,7 @@ private void OnEnable() name = string.Format("{0} - {1}", GetType().Name, name) }; + _commandBufferUpdateCounter = 0; _changed = true; camera.AddCommandBuffer(_cameraEvent, _commandBuffer); @@ -209,6 +211,7 @@ private void LateUpdate() private void OnDestroy() { + // TODO: Find a way to do this once per OutlineLayerCollection instance. if (_outlineLayers) { _outlineLayers.Reset(); @@ -248,6 +251,7 @@ private void FillCommandBuffer() _commandBuffer.Clear(); } + _commandBufferUpdateCounter++; _changed = false; } From d9e869ba7eb925ca5129bb3a4b8f580eb9faa799 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Mon, 23 Sep 2019 19:03:33 +0300 Subject: [PATCH 12/20] Added number of updates value to inspector --- .../Editor/Scripts/OutlineBehaviourEditor.cs | 13 +++++++ .../Editor/Scripts/OutlineEffectEditor.cs | 12 +++++++ .../Runtime/Scripts/OutlineBehaviour.cs | 32 ++++++++++++++++- .../Runtime/Scripts/OutlineEffect.cs | 36 +++++++++++++++++-- 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs index 4716161..ea92d3c 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineBehaviourEditor.cs @@ -12,6 +12,7 @@ namespace UnityFx.Outline public class OutlineBehaviourEditor : Editor { private OutlineBehaviour _effect; + private bool _debugOpened; private bool _renderersOpened; private bool _camerasOpened; @@ -78,6 +79,18 @@ public override void OnInspectorGUI() EditorGUI.indentLevel -= 1; EditorGUI.EndDisabledGroup(); } + + // 4) Debug info. + _debugOpened = EditorGUILayout.Foldout(_debugOpened, "Debug", true); + + if (_debugOpened) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUI.indentLevel += 1; + EditorGUILayout.IntField("Command buffer updates", _effect.NumberOfCommandBufferUpdates); + EditorGUI.indentLevel -= 1; + EditorGUI.EndDisabledGroup(); + } } } } diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs index 566ff73..464e492 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineEffectEditor.cs @@ -14,6 +14,7 @@ namespace UnityFx.Outline public class OutlineEffectEditor : Editor { private OutlineEffect _effect; + private bool _debugOpened; private bool _previewOpened; private void OnEnable() @@ -53,6 +54,17 @@ public override void OnInspectorGUI() OutlineEditorUtility.RenderPreview(_effect.OutlineLayers, true); } } + + _debugOpened = EditorGUILayout.Foldout(_debugOpened, "Debug", true); + + if (_debugOpened) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUI.indentLevel += 1; + EditorGUILayout.IntField("Command buffer updates", _effect.NumberOfCommandBufferUpdates); + EditorGUI.indentLevel -= 1; + EditorGUI.EndDisabledGroup(); + } } } } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs index b1c0878..4f41843 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineBehaviour.cs @@ -33,12 +33,32 @@ public sealed partial class OutlineBehaviour : MonoBehaviour, IOutlineSettingsEx private Dictionary _cameraMap = new Dictionary(); private float _cameraMapUpdateTimer; + +#if UNITY_EDITOR + private int _commandBufferUpdateCounter; +#endif + #endregion #region interface +#if UNITY_EDITOR + + /// + /// Gets number of the command buffer updates since its creation. Only available in editor. + /// + public int NumberOfCommandBufferUpdates + { + get + { + return _commandBufferUpdateCounter; + } + } + +#endif + /// /// Gets or sets resources used by the effect implementation. /// @@ -149,7 +169,7 @@ private void Update() #endif - if (_outlineResources != null && _renderers != null && _outlineSettings.IsChanged) + if (_outlineResources != null && _renderers != null && (_outlineSettings.IsChanged || _commandBuffer.sizeInBytes == 0)) { using (var renderer = new OutlineRenderer(_commandBuffer, BuiltinRenderTextureType.CameraTarget)) { @@ -157,7 +177,12 @@ private void Update() } _outlineSettings.AcceptChanges(); + +#if UNITY_EDITOR + _commandBufferUpdateCounter++; + +#endif } } @@ -308,7 +333,12 @@ private void CreateCommandBufferIfNeeded() { _commandBuffer = new CommandBuffer(); _commandBuffer.name = string.Format("{0} - {1}", GetType().Name, name); + +#if UNITY_EDITOR + _commandBufferUpdateCounter = 0; + +#endif } } diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs index 3f4d61e..c5f9e75 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineEffect.cs @@ -29,13 +29,33 @@ public sealed partial class OutlineEffect : MonoBehaviour private CameraEvent _cameraEvent = OutlineRenderer.RenderEvent; private CommandBuffer _commandBuffer; - private int _commandBufferUpdateCounter; private bool _changed; +#if UNITY_EDITOR + + private int _commandBufferUpdateCounter; + +#endif + #endregion #region interface +#if UNITY_EDITOR + + /// + /// Gets number of the command buffer updates since its creation. Only available in editor. + /// + public int NumberOfCommandBufferUpdates + { + get + { + return _commandBufferUpdateCounter; + } + } + +#endif + /// /// Gets or sets resources used by the effect implementation. /// @@ -163,9 +183,14 @@ private void OnEnable() name = string.Format("{0} - {1}", GetType().Name, name) }; - _commandBufferUpdateCounter = 0; _changed = true; +#if UNITY_EDITOR + + _commandBufferUpdateCounter = 0; + +#endif + camera.AddCommandBuffer(_cameraEvent, _commandBuffer); } } @@ -251,8 +276,13 @@ private void FillCommandBuffer() _commandBuffer.Clear(); } - _commandBufferUpdateCounter++; _changed = false; + +#if UNITY_EDITOR + + _commandBufferUpdateCounter++; + +#endif } private void CreateLayersIfNeeded() From 4236a3f4381996b95e1df403e6612e6bd2877e3e Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Mon, 23 Sep 2019 19:25:04 +0300 Subject: [PATCH 13/20] Added assembly info --- .../Runtime/Scripts/Helpers.meta | 8 +++++ .../Runtime/Scripts/Helpers/AssemblyInfo.cs | 29 +++++++++++++++++++ .../Scripts/Helpers/AssemblyInfo.cs.meta | 11 +++++++ 3 files changed, 48 insertions(+) create mode 100644 Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers.meta create mode 100644 Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs create mode 100644 Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs.meta diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers.meta b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers.meta new file mode 100644 index 0000000..f18352b --- /dev/null +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: de5ff1c474a17ba44a09339f7b56a80b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs new file mode 100644 index 0000000..4e0f171 --- /dev/null +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Alexander Bogarsukov. All rights reserved. +// See the LICENSE.md file in the project root for more information. + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("UnityFx.Outline")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UnityFx.Outline")] +[assembly: AssemblyCopyright("Copyright © Alexander Bogarsukov 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1ace8625-97c5-4d37-a649-03975d187542")] + +// Make internals visible to the editor assembly. +[assembly: InternalsVisibleTo("UnityFx.Outline.Editor")] diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs.meta b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs.meta new file mode 100644 index 0000000..dd9f2bd --- /dev/null +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1613c034178676349be3282789167284 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 196298ffadd8c642f1f48fb813f6996f946f7862 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Mon, 23 Sep 2019 19:25:35 +0300 Subject: [PATCH 14/20] Made the OutlineLayer.Name read-only (but still editable in inspector) --- .../Scripts/OutlineLayerCollectionEditor.cs | 6 ++--- .../Runtime/Scripts/OutlineLayer.cs | 23 +++++++++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs index 1c6f835..7e3615f 100644 --- a/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs +++ b/Assets/Plugins/UnityFx.Outline/Editor/Scripts/OutlineLayerCollectionEditor.cs @@ -64,12 +64,12 @@ public override void OnInspectorGUI() GUI.Box(rect, GUIContent.none); - var name = EditorGUILayout.TextField("Layer Name", _layers[i].Name); + var name = EditorGUILayout.TextField("Layer Name", _layers[i].NameTag); - if (name != _layers[i].Name) + if (name != _layers[i].NameTag) { Undo.RecordObject(_layers, "Set Layer Name"); - _layers[i].Name = name; + _layers[i].NameTag = name; } var priority = EditorGUILayout.IntField("Layer Priority", _layers[i].Priority); diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 6a38fca..64facf1 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -39,18 +39,19 @@ public sealed partial class OutlineLayer : ICollection, IOutlineSett #region interface /// - /// Gets or sets layer name. + /// Gets the layer name. /// public string Name { get { + if (string.IsNullOrEmpty(_name)) + { + return "OutlineLayer #" + Index.ToString(); + } + return _name; } - set - { - _name = value; - } } /// @@ -204,6 +205,18 @@ public bool TryGetRenderers(GameObject go, out ICollection renderers) #region internals + internal string NameTag + { + get + { + return _name; + } + set + { + _name = value; + } + } + internal OutlineLayerCollection ParentCollection { get From 35b68e346acf69888a065d4263a95486cffbd1a7 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 26 Sep 2019 16:35:38 +0300 Subject: [PATCH 15/20] README update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4fe0304..6a6928d 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Npm package is available at [npmjs.com](https://www.npmjs.com/package/com.unityf } ], "dependencies": { - "com.unityfx.outline": "0.5.0" + "com.unityfx.outline": "0.6.0" } } ``` @@ -71,7 +71,7 @@ using UnityFx.Outline; Add `OutlineEffect` script to a camera that should render outlines. Then add and configure as many layers as you need: ```csharp var outlineEffect = Camera.main.GetComponent(); -var layer = new OutlineLayer(); +var layer = new OutlineLayer("MyOutlines"); layer.OutlineColor = Color.red; layer.OutlineWidth = 7; From bedd1907d4b599af37b1a495a0a73149b47a513e Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 26 Sep 2019 16:35:59 +0300 Subject: [PATCH 16/20] Added a few convenience methods --- .../UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs index 64facf1..acbcf47 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.cs @@ -178,6 +178,15 @@ public void Add(GameObject go, int ignoreLayerMask) } } + /// + /// Adds a new object to the layer. + /// + /// Thrown if is . + public void Add(GameObject go, string ignoreLayer) + { + Add(go, 1 << LayerMask.NameToLayer(ignoreLayer)); + } + /// /// Attempts to get renderers assosiated with the specified . /// From 23abd2e022813c506c712056a0fb687c51ca908f Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 26 Sep 2019 18:21:45 +0300 Subject: [PATCH 17/20] Assembly info fixes --- .../Runtime/Scripts/Helpers/AssemblyInfo.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs index 4e0f171..041e387 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/Helpers/AssemblyInfo.cs @@ -5,24 +5,27 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("UnityFx.Outline")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] [assembly: AssemblyProduct("UnityFx.Outline")] +[assembly: AssemblyDescription("Screen-space outlines for Unity3d.")] +#if DEBUG +[assembly: AssemblyConfiguration("Debug")] +#else +[assembly: AssemblyConfiguration("Release")] +#endif +[assembly: AssemblyCompany("")] [assembly: AssemblyCopyright("Copyright © Alexander Bogarsukov 2019")] -[assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] -// The following GUID is for the ID of the typelib if this project is exposed to COM +// The following GUID is for the ID of the typelib if this project is exposed to COM. [assembly: Guid("1ace8625-97c5-4d37-a649-03975d187542")] // Make internals visible to the editor assembly. From 9aa211c425cfd0e8818263d6339cdeffd55a3554 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 26 Sep 2019 18:47:12 +0300 Subject: [PATCH 18/20] Fixed OutlineLayer.Add not filtering added renderers based on the layer mask passed --- .../Runtime/Scripts/OutlineLayer.Renderers.cs | 2 +- .../Tests/Editor/Scripts/OutlineLayerTests.cs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs index d84b264..79dbd9e 100644 --- a/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs +++ b/Assets/Plugins/UnityFx.Outline/Runtime/Scripts/OutlineLayer.Renderers.cs @@ -53,7 +53,7 @@ public void Reset(int ignoreLayerMask) { foreach (var renderer in renderers) { - if ((renderer.gameObject.layer & ignoreLayerMask) == 0) + if (((1 << renderer.gameObject.layer) & ignoreLayerMask) == 0) { _renderers.Add(renderer); } diff --git a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs index 0e9df7e..387b3bb 100644 --- a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs +++ b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs @@ -75,6 +75,25 @@ public void Add_SetsChanged() Assert.IsTrue(_layer.IsChanged); } + [Test] + public void Add_FiltersRenderesByLayer() + { + var go = new GameObject("r1", typeof(MeshRenderer)); + var go2 = new GameObject("r2", typeof(MeshRenderer)); + + go2.layer = LayerMask.NameToLayer("TransparentFX"); + go2.transform.SetParent(go.transform, false); + + ICollection r; + + _layer.Add(go, "TransparentFX"); + _layer.TryGetRenderers(go, out r); + + Assert.AreEqual(1, r.Count); + Assert.IsTrue(r.Contains(go.GetComponent())); + Assert.IsFalse(r.Contains(go2.GetComponent())); + } + [Test] public void Remove_DoesNotThrowOnNullArgument() { From a2d716c281aa8c52294b6eab847b95917efae4aa Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 26 Sep 2019 18:49:40 +0300 Subject: [PATCH 19/20] Added OutlineLayer index/name tests --- .../UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs index 387b3bb..f965443 100644 --- a/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs +++ b/Assets/Plugins/UnityFx.Outline/Tests/Editor/Scripts/OutlineLayerTests.cs @@ -18,7 +18,7 @@ public class OutlineLayerTests : IOutlineSettingsExTests, IDisposable [SetUp] public void Init() { - _layer = new OutlineLayer(); + _layer = new OutlineLayer("TestLayer"); Init(_layer); } @@ -34,6 +34,8 @@ public void DefaultStateIsValid() Assert.IsFalse(_layer.IsReadOnly); Assert.IsEmpty(_layer); Assert.Zero(_layer.Count); + Assert.AreEqual("TestLayer", _layer.Name); + Assert.AreEqual(-1, _layer.Index); } [Test] From cabd5c30d46fb00f420b9f6ffc53c72dad8471e4 Mon Sep 17 00:00:00 2001 From: Alexander Bogarsukov Date: Thu, 26 Sep 2019 18:53:38 +0300 Subject: [PATCH 20/20] CHANGELOG update --- CHANGELOG.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9575ed..ffc89a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/); this project adheres to [Semantic Versioning](http://semver.org/). -## [0.6.0] - unreleased +## [0.6.0] - 2019.09.26 + +Quality of life improvements. ### Added - Added `OutlineLayer.Enabled`. @@ -16,9 +18,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/); this proj ### Changed - `IOutilneSettings` setters now throw if overriden. +### Fixed +- Fixed `OutlineLayer.Add` not filtering renderers by the mask passed. + ## [0.5.0] - 2019.09.09 -Features editor UI and unit tests. +Editor UI improvements and unit tests. ### Added - Added `OutlineSettings`, that can be shared between dfferent `OutlineLayer` and `OutlineBehaviour` instances. @@ -31,7 +36,7 @@ Features editor UI and unit tests. ## [0.4.0] - 2019.08.31 -Features blurred outlines. +Blurred outlines. ### Added - Added Gauss blurring to outlines.