init
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
// Copyright (C) 2019-2021 Alexander Bogarsukov. All rights reserved.
|
||||
// See the LICENSE.md file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomEditor(typeof(OutlineBehaviour))]
|
||||
public class OutlineBehaviourEditor : Editor
|
||||
{
|
||||
private OutlineBehaviour _effect;
|
||||
private SerializedProperty _settingsProp;
|
||||
private bool _debugOpened;
|
||||
private bool _renderersOpened;
|
||||
private bool _camerasOpened;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_effect = (OutlineBehaviour)target;
|
||||
_settingsProp = serializedObject.FindProperty("_outlineSettings");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
// 1) Outline settings.
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var mask = EditorGUILayout.MaskField("Ignore layers", _effect.IgnoreLayerMask, InternalEditorUtility.layers);
|
||||
|
||||
if (_effect.IgnoreLayerMask != mask)
|
||||
{
|
||||
Undo.RecordObject(_effect, "Set Ignore Layers");
|
||||
_effect.IgnoreLayerMask = mask;
|
||||
}
|
||||
|
||||
var e = (CameraEvent)EditorGUILayout.EnumPopup("Render Event", _effect.RenderEvent);
|
||||
|
||||
if (e != _effect.RenderEvent)
|
||||
{
|
||||
Undo.RecordObject(_effect, "Set Render Event");
|
||||
_effect.RenderEvent = e;
|
||||
}
|
||||
|
||||
var c = (Camera)EditorGUILayout.ObjectField("Target Camera", _effect.Camera, typeof(Camera), true);
|
||||
|
||||
if (c != _effect.Camera)
|
||||
{
|
||||
Undo.RecordObject(_effect, "Set Target Camera");
|
||||
_effect.Camera = c;
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(_settingsProp);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorUtility.SetDirty(_effect.gameObject);
|
||||
|
||||
if (!EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
EditorSceneManager.MarkSceneDirty(_effect.gameObject.scene);
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Renderers (read-only).
|
||||
_renderersOpened = EditorGUILayout.Foldout(_renderersOpened, "Renderers", true);
|
||||
|
||||
if (_renderersOpened)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.indentLevel += 1;
|
||||
|
||||
var rendererNumber = 1;
|
||||
|
||||
foreach (var renderer in _effect.OutlineRenderers)
|
||||
{
|
||||
EditorGUILayout.ObjectField("#" + rendererNumber.ToString(), renderer, typeof(Renderer), true);
|
||||
rendererNumber++;
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
// 3) Cameras (read-only).
|
||||
_camerasOpened = EditorGUILayout.Foldout(_camerasOpened, "Cameras", true);
|
||||
|
||||
if (_camerasOpened)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.indentLevel += 1;
|
||||
|
||||
var cameraNumber = 1;
|
||||
|
||||
foreach (var camera in _effect.Cameras)
|
||||
{
|
||||
EditorGUILayout.ObjectField("#" + cameraNumber.ToString(), camera, typeof(Camera), true);
|
||||
cameraNumber++;
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6e77a9d499a86e4fbdc52a2977e774f
|
||||
timeCreated: 1566572433
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomEditor(typeof(OutlineBuilder))]
|
||||
public class OutlineBuilderEditor : Editor
|
||||
{
|
||||
private OutlineBuilder _builder;
|
||||
private ReorderableList _content;
|
||||
private List<ReorderableList> _lists;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_builder = (OutlineBuilder)target;
|
||||
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
if (_builder.OutlineLayers)
|
||||
{
|
||||
_lists = new List<ReorderableList>(_builder.OutlineLayers.Count);
|
||||
|
||||
foreach (var layer in _builder.OutlineLayers)
|
||||
{
|
||||
var list0 = new ArrayList(layer.Count);
|
||||
|
||||
foreach (var go in layer)
|
||||
{
|
||||
list0.Add(go);
|
||||
}
|
||||
|
||||
var editorList = new ReorderableList(list0, typeof(GameObject), false, true, true, true);
|
||||
|
||||
editorList.onAddCallback += (list) =>
|
||||
{
|
||||
list.list.Add(null);
|
||||
};
|
||||
|
||||
editorList.onRemoveCallback += (list) =>
|
||||
{
|
||||
var go = list.list[list.index];
|
||||
list.list.RemoveAt(list.index);
|
||||
layer.Remove(go as GameObject);
|
||||
};
|
||||
|
||||
editorList.drawElementCallback += (rect, index, isActive, isFocused) =>
|
||||
{
|
||||
var prevGo = list0[index] as GameObject;
|
||||
var go = (GameObject)EditorGUI.ObjectField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), $"#{index}", prevGo, typeof(GameObject), true);
|
||||
|
||||
if (prevGo != go)
|
||||
{
|
||||
list0[index] = go;
|
||||
layer.Remove(prevGo);
|
||||
layer.Add(go);
|
||||
}
|
||||
};
|
||||
|
||||
editorList.drawHeaderCallback += (rect) =>
|
||||
{
|
||||
EditorGUI.LabelField(rect, layer.Name);
|
||||
};
|
||||
|
||||
editorList.elementHeightCallback += (index) =>
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
};
|
||||
|
||||
_lists.Add(editorList);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_content = new ReorderableList(_builder.Content, typeof(OutlineBuilder.ContentItem), true, true, true, true);
|
||||
|
||||
_content.drawElementCallback += (rect, index, isActive, isFocused) =>
|
||||
{
|
||||
if (_builder && _builder.Content != null && index < _builder.Content.Count)
|
||||
{
|
||||
var item = _builder.Content[index];
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.Go = (GameObject)EditorGUI.ObjectField(new Rect(rect.x + rect.width * 0.3f + 1, rect.y, rect.width * 0.7f, EditorGUIUtility.singleLineHeight), item.Go, typeof(GameObject), true);
|
||||
item.LayerIndex = EditorGUI.IntField(new Rect(rect.x, rect.y, rect.width * 0.3f - 1, EditorGUIUtility.singleLineHeight), item.LayerIndex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_content.drawHeaderCallback += (rect) =>
|
||||
{
|
||||
EditorGUI.LabelField(rect, "Content");
|
||||
};
|
||||
|
||||
_content.elementHeightCallback += (index) =>
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
if (_content != null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Game objectes listed below will be added to corresponding outline layers when application is started. Only scene references are allowed.", MessageType.Info);
|
||||
_content.DoLayoutList();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
_builder.Content.Clear();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
else if (_lists != null && _lists.Count > 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Settings below are not serialized, they only exist in runtime.", MessageType.Info);
|
||||
|
||||
for (var i = 0; i < _lists.Count; ++i)
|
||||
{
|
||||
_lists[i].DoLayoutList();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
foreach (var list in _lists)
|
||||
{
|
||||
list.list.Clear();
|
||||
}
|
||||
|
||||
_builder.Clear();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(_builder, "Builder");
|
||||
|
||||
if (!EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
EditorUtility.SetDirty(_builder.gameObject);
|
||||
EditorSceneManager.MarkSceneDirty(_builder.gameObject.scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2ba41e0b025a6e46abc7b69d31d1907
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
public static class OutlineEditorUtility
|
||||
{
|
||||
public static readonly GUIContent FilterSettingsContent = new GUIContent("Outline Filter Settings", "");
|
||||
public static readonly GUIContent LayerMaskContent = new GUIContent("Layer Mask", OutlineResources.OutlineLayerMaskTooltip);
|
||||
public static readonly GUIContent RenderingLayerMaskContent = new GUIContent("Rendering Layer Mask", OutlineResources.OutlineRenderingLayerMaskTooltip);
|
||||
public static readonly GUIContent ColorContent = new GUIContent("Color", "Outline color.");
|
||||
public static readonly GUIContent WidthContent = new GUIContent("Width", "Outline width in pixels.");
|
||||
public static readonly GUIContent RenderFlagsContent = new GUIContent("Render Flags", "Outline render flags. Multiple values can be selected at the same time.");
|
||||
public static readonly GUIContent BlurIntensityContent = new GUIContent("Blur Intensity", "Outline intensity value. It is only usable for blurred outlines.");
|
||||
public static readonly GUIContent AlphaCutoffContent = new GUIContent("Alpha Cutoff", "Outline alpha cutoff value. It is only usable when alpha testing is enabled and the material doesn't have _Cutoff property.");
|
||||
|
||||
public static void RenderPreview(OutlineLayer layer, int layerIndex, bool showObjects)
|
||||
{
|
||||
if (layer != null)
|
||||
{
|
||||
var goIndex = 1;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUILayout.PrefixLabel("Layer #" + layerIndex.ToString());
|
||||
EditorGUI.indentLevel -= 1;
|
||||
|
||||
if (layer.Enabled)
|
||||
{
|
||||
EditorGUILayout.LabelField(layer.OutlineRenderMode == OutlineRenderFlags.None ? layer.OutlineRenderMode.ToString() : string.Format("Blurred ({0})", layer.OutlineIntensity), GUILayout.MaxWidth(70));
|
||||
EditorGUILayout.IntField(layer.OutlineWidth, GUILayout.MaxWidth(100));
|
||||
EditorGUILayout.ColorField(layer.OutlineColor, GUILayout.MinWidth(100));
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("Disabled.");
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (showObjects)
|
||||
{
|
||||
if (layer.Count > 0)
|
||||
{
|
||||
foreach (var go in layer)
|
||||
{
|
||||
EditorGUI.indentLevel += 2;
|
||||
EditorGUILayout.ObjectField("#" + goIndex.ToString(), go, typeof(GameObject), true);
|
||||
EditorGUI.indentLevel -= 2;
|
||||
|
||||
goIndex++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.indentLevel += 2;
|
||||
EditorGUILayout.LabelField("No objects.");
|
||||
EditorGUI.indentLevel -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUILayout.PrefixLabel("Layer #" + layerIndex.ToString());
|
||||
EditorGUI.indentLevel -= 1;
|
||||
EditorGUILayout.LabelField("Null");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RenderPreview(IList<OutlineLayer> layers, bool showObjects)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
|
||||
if (layers.Count > 0)
|
||||
{
|
||||
for (var i = 0; i < layers.Count; ++i)
|
||||
{
|
||||
RenderPreview(layers[i], i, showObjects);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUILayout.LabelField("No layers.");
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba087138029b59d4bbdf0783db0e2606
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomEditor(typeof(OutlineEffect))]
|
||||
public class OutlineEffectEditor : Editor
|
||||
{
|
||||
private OutlineEffect _effect;
|
||||
private bool _debugOpened;
|
||||
private bool _previewOpened;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_effect = (OutlineEffect)target;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (_effect.OutlineLayers.Count > 0)
|
||||
{
|
||||
_previewOpened = EditorGUILayout.Foldout(_previewOpened, "Preview", true);
|
||||
|
||||
if (_previewOpened)
|
||||
{
|
||||
OutlineEditorUtility.RenderPreview(_effect.OutlineLayers, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03c2e35bb52d2ba44882b92d7cde45bf
|
||||
timeCreated: 1566558360
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,214 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomEditor(typeof(OutlineLayerCollection))]
|
||||
public class OutlineLayerCollectionEditor : Editor
|
||||
{
|
||||
private OutlineLayerCollection _layers;
|
||||
|
||||
private SerializedProperty _layersProp;
|
||||
private ReorderableList _layersList;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_layers = (OutlineLayerCollection)target;
|
||||
|
||||
_layersProp = serializedObject.FindProperty("_layers");
|
||||
_layersList = new ReorderableList(serializedObject, _layersProp, true, true, true, true);
|
||||
_layersList.drawElementCallback += OnDrawLayer;
|
||||
_layersList.drawHeaderCallback += OnDrawHeader;
|
||||
_layersList.elementHeightCallback += OnGetElementHeight;
|
||||
_layersList.onAddCallback += OnAddLayer;
|
||||
_layersList.onRemoveCallback += OnRemoveLayer;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var mask = EditorGUILayout.MaskField("Ignore layers", _layers.IgnoreLayerMask, InternalEditorUtility.layers);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(_layers, "Change ignore mask");
|
||||
_layers.IgnoreLayerMask = mask;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
_layersList.DoLayoutList();
|
||||
|
||||
if (_layers.NumberOfObjects > 0)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.HelpBox("Read-only lists below represent game objects assigned to specific outline layers. Only non-empty layers are displayed.", MessageType.Info);
|
||||
|
||||
foreach (var layer in _layers)
|
||||
{
|
||||
if (layer.Count > 0)
|
||||
{
|
||||
EditorGUILayout.LabelField(layer.Name, EditorStyles.boldLabel);
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUI.indentLevel += 1;
|
||||
|
||||
var index = 0;
|
||||
|
||||
foreach (var go in layer)
|
||||
{
|
||||
EditorGUILayout.ObjectField($"#{index++}", go, typeof(GameObject), true);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void OnDrawLayer(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
var lineHeight = EditorGUIUtility.singleLineHeight;
|
||||
var lineSpacing = EditorGUIUtility.standardVerticalSpacing;
|
||||
var lineOffset = lineHeight + lineSpacing;
|
||||
var y = rect.y + lineSpacing;
|
||||
var layer = _layers[index];
|
||||
|
||||
var obj = layer.OutlineSettings;
|
||||
var merge = layer.MergeLayerObjects;
|
||||
var enabled = layer.Enabled;
|
||||
var name = layer.NameTag;
|
||||
var color = layer.OutlineColor;
|
||||
var width = layer.OutlineWidth;
|
||||
var renderMode = layer.OutlineRenderMode;
|
||||
var blurIntensity = layer.OutlineIntensity;
|
||||
var alphaCutoff = layer.OutlineAlphaCutoff;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
// Header
|
||||
{
|
||||
var rc = new Rect(rect.x, y, rect.width, lineHeight);
|
||||
var bgRect = new Rect(rect.x - 2, y - 2, rect.width + 3, lineHeight + 3);
|
||||
|
||||
// Header background
|
||||
EditorGUI.DrawRect(rc, Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(bgRect.x, bgRect.y, bgRect.width, 1), Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(bgRect.x, bgRect.yMax, bgRect.width, 1), Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(bgRect.x, bgRect.y, 1, bgRect.height), Color.gray);
|
||||
EditorGUI.DrawRect(new Rect(bgRect.xMax, bgRect.y, 1, bgRect.height), Color.gray);
|
||||
|
||||
obj = (OutlineSettings)EditorGUI.ObjectField(rc, " ", obj, typeof(OutlineSettings), true);
|
||||
enabled = EditorGUI.ToggleLeft(rc, "Layer #" + index.ToString(), enabled, EditorStyles.boldLabel);
|
||||
y += lineOffset;
|
||||
}
|
||||
|
||||
// Layer properties
|
||||
{
|
||||
name = EditorGUI.TextField(new Rect(rect.x, y, rect.width, lineHeight), "Name", name);
|
||||
y += lineOffset;
|
||||
|
||||
merge = EditorGUI.Toggle(new Rect(rect.x, y, rect.width, lineHeight), "Merge Layer Objects", merge);
|
||||
y += lineOffset;
|
||||
}
|
||||
|
||||
// Outline settings
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(obj != null);
|
||||
|
||||
color = EditorGUI.ColorField(new Rect(rect.x, y, rect.width, lineHeight), OutlineEditorUtility.ColorContent, color, true, true, true);
|
||||
y += lineOffset;
|
||||
|
||||
width = EditorGUI.IntSlider(new Rect(rect.x, y, rect.width, lineHeight), OutlineEditorUtility.WidthContent, width, OutlineResources.MinWidth, OutlineResources.MaxWidth);
|
||||
y += lineOffset;
|
||||
|
||||
renderMode = (OutlineRenderFlags)EditorGUI.EnumFlagsField(new Rect(rect.x, y, rect.width, lineHeight), OutlineEditorUtility.RenderFlagsContent, renderMode);
|
||||
y += lineOffset;
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.Blurred) != 0)
|
||||
{
|
||||
blurIntensity = EditorGUI.Slider(new Rect(rect.x, y, rect.width, lineHeight), OutlineEditorUtility.BlurIntensityContent, blurIntensity, OutlineResources.MinIntensity, OutlineResources.MaxIntensity);
|
||||
y += lineOffset;
|
||||
}
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0)
|
||||
{
|
||||
alphaCutoff = EditorGUI.Slider(new Rect(rect.x, y, rect.width, lineHeight), OutlineEditorUtility.AlphaCutoffContent, alphaCutoff, OutlineResources.MinAlphaCutoff, OutlineResources.MaxAlphaCutoff);
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(_layers, "Layers changed");
|
||||
EditorUtility.SetDirty(_layers);
|
||||
|
||||
layer.OutlineSettings = obj;
|
||||
layer.Enabled = enabled;
|
||||
layer.NameTag = name;
|
||||
layer.MergeLayerObjects = merge;
|
||||
layer.OutlineWidth = width;
|
||||
layer.OutlineColor = color;
|
||||
layer.OutlineRenderMode = renderMode;
|
||||
layer.OutlineIntensity = blurIntensity;
|
||||
layer.OutlineAlphaCutoff = alphaCutoff;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawHeader(Rect rect)
|
||||
{
|
||||
EditorGUI.LabelField(rect, "Layer settings");
|
||||
}
|
||||
|
||||
private float OnGetElementHeight(int index)
|
||||
{
|
||||
var numberOfLines = 6;
|
||||
|
||||
if ((_layers[index].OutlineRenderMode & OutlineRenderFlags.Blurred) != 0)
|
||||
{
|
||||
++numberOfLines;
|
||||
}
|
||||
|
||||
if ((_layers[index].OutlineRenderMode & OutlineRenderFlags.EnableAlphaTesting) != 0)
|
||||
{
|
||||
++numberOfLines;
|
||||
}
|
||||
|
||||
return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * numberOfLines + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
|
||||
private void OnAddLayer(ReorderableList list)
|
||||
{
|
||||
var layer = new OutlineLayer();
|
||||
|
||||
Undo.RecordObject(_layers, "Add Layer");
|
||||
EditorUtility.SetDirty(_layers);
|
||||
|
||||
_layers.Add(layer);
|
||||
}
|
||||
|
||||
private void OnRemoveLayer(ReorderableList list)
|
||||
{
|
||||
var index = list.index;
|
||||
var layer = _layers[index];
|
||||
|
||||
Undo.RecordObject(_layers, "Remove Layer");
|
||||
EditorUtility.SetDirty(_layers);
|
||||
|
||||
_layers.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f4ec5de59e58794b8e34f2ca3c00199
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,240 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomEditor(typeof(OutlineSettings))]
|
||||
public class OutlineSettingsEditor : Editor
|
||||
{
|
||||
private const string _filterModePropName = "_filterMode";
|
||||
private const string _layerMaskPropName = "_layerMask";
|
||||
private const string _renderingLayerMaskPropName = "_renderingLayerMask";
|
||||
private const string _settingsPropName = "_outlineSettings";
|
||||
private const string _colorPropName = "_outlineColor";
|
||||
private const string _widthPropName = "_outlineWidth";
|
||||
private const string _intensityPropName = "_outlineIntensity";
|
||||
private const string _cutoffPropName = "_outlineAlphaCutoff";
|
||||
private const string _renderModePropName = "_outlineMode";
|
||||
|
||||
private static readonly string[] _renderingLayerMaskNames = new string[]
|
||||
{
|
||||
"Layer1",
|
||||
"Layer2",
|
||||
"Layer3",
|
||||
"Layer4",
|
||||
"Layer5",
|
||||
"Layer6",
|
||||
"Layer7",
|
||||
"Layer8",
|
||||
"Layer9",
|
||||
"Layer10",
|
||||
"Layer11",
|
||||
"Layer12",
|
||||
"Layer13",
|
||||
"Layer14",
|
||||
"Layer15",
|
||||
"Layer16",
|
||||
"Layer17",
|
||||
"Layer18",
|
||||
"Layer19",
|
||||
"Layer20",
|
||||
"Layer21",
|
||||
"Layer22",
|
||||
"Layer23",
|
||||
"Layer24",
|
||||
"Layer25",
|
||||
"Layer26",
|
||||
"Layer27",
|
||||
"Layer28",
|
||||
"Layer29",
|
||||
"Layer30",
|
||||
"Layer31",
|
||||
"Layer32",
|
||||
};
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
var colorProp = serializedObject.FindProperty(_colorPropName);
|
||||
var widthProp = serializedObject.FindProperty(_widthPropName);
|
||||
var intensityProp = serializedObject.FindProperty(_intensityPropName);
|
||||
var cutoffProp = serializedObject.FindProperty(_cutoffPropName);
|
||||
var renderModeProp = serializedObject.FindProperty(_renderModePropName);
|
||||
var renderMode = (OutlineRenderFlags)renderModeProp.intValue;
|
||||
|
||||
//EditorGUILayout.PropertyField(colorProp, _colorContent);
|
||||
colorProp.colorValue = EditorGUILayout.ColorField(OutlineEditorUtility.ColorContent, colorProp.colorValue, true, true, true);
|
||||
|
||||
EditorGUILayout.PropertyField(widthProp, OutlineEditorUtility.WidthContent);
|
||||
|
||||
//EditorGUILayout.PropertyField(renderModeProp, _renderModeContent);
|
||||
renderModeProp.intValue = (int)(OutlineRenderFlags)EditorGUILayout.EnumFlagsField(OutlineEditorUtility.RenderFlagsContent, renderMode);
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.Blurred) != 0)
|
||||
{
|
||||
EditorGUILayout.PropertyField(intensityProp, OutlineEditorUtility.BlurIntensityContent);
|
||||
}
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0)
|
||||
{
|
||||
EditorGUILayout.PropertyField(cutoffProp, OutlineEditorUtility.AlphaCutoffContent);
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
internal static float GetSettingsInstanceHeight(SerializedProperty property)
|
||||
{
|
||||
var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
var renderModeProp = property.FindPropertyRelative(_renderModePropName);
|
||||
var renderMode = (OutlineRenderFlags)renderModeProp.intValue;
|
||||
var result = lineCy * 4;
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.Blurred) != 0)
|
||||
{
|
||||
result += lineCy;
|
||||
}
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0)
|
||||
{
|
||||
result += lineCy;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static float GetSettingsWithMaskHeight(SerializedProperty property)
|
||||
{
|
||||
var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
var filterModeProp = property.FindPropertyRelative(_filterModePropName);
|
||||
var renderOutlineSettings = false;
|
||||
|
||||
if (filterModeProp.intValue == (int)OutlineFilterMode.UseLayerMask)
|
||||
{
|
||||
var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName);
|
||||
renderOutlineSettings = true;
|
||||
}
|
||||
else if (filterModeProp.intValue == (int)OutlineFilterMode.UseRenderingLayerMask)
|
||||
{
|
||||
var renderingLayerMaskProp = property.FindPropertyRelative(_renderingLayerMaskPropName);
|
||||
renderOutlineSettings = true;
|
||||
}
|
||||
|
||||
if (renderOutlineSettings)
|
||||
{
|
||||
var renderModeProp = property.FindPropertyRelative(_renderModePropName);
|
||||
var renderMode = (OutlineRenderFlags)renderModeProp.intValue;
|
||||
var result = lineCy * 6;
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.Blurred) != 0)
|
||||
{
|
||||
result += lineCy;
|
||||
}
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0)
|
||||
{
|
||||
result += lineCy;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return lineCy;
|
||||
}
|
||||
|
||||
internal static void DrawSettingsInstance(Rect rc, SerializedProperty property)
|
||||
{
|
||||
var settingsProp = property.FindPropertyRelative(_settingsPropName);
|
||||
|
||||
EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), settingsProp);
|
||||
EditorGUI.indentLevel += 1;
|
||||
|
||||
if (settingsProp.objectReferenceValue)
|
||||
{
|
||||
var obj = new SerializedObject(settingsProp.objectReferenceValue);
|
||||
var colorProp = obj.FindProperty(_colorPropName);
|
||||
var widthProp = obj.FindProperty(_widthPropName);
|
||||
var intensityProp = obj.FindProperty(_intensityPropName);
|
||||
var cutoffProp = obj.FindProperty(_cutoffPropName);
|
||||
var renderModeProp = obj.FindProperty(_renderModePropName);
|
||||
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, cutoffProp, renderModeProp);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
var colorProp = property.FindPropertyRelative(_colorPropName);
|
||||
var widthProp = property.FindPropertyRelative(_widthPropName);
|
||||
var intensityProp = property.FindPropertyRelative(_intensityPropName);
|
||||
var cutoffProp = property.FindPropertyRelative(_cutoffPropName);
|
||||
var renderModeProp = property.FindPropertyRelative(_renderModePropName);
|
||||
|
||||
DrawSettingsInternal(rc, colorProp, widthProp, intensityProp, cutoffProp, renderModeProp);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
internal static void DrawSettingsWithMask(Rect rc, SerializedProperty property)
|
||||
{
|
||||
var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
var filterModeProp = property.FindPropertyRelative(_filterModePropName);
|
||||
|
||||
EditorGUI.PropertyField(new Rect(rc.x, rc.y, rc.width, EditorGUIUtility.singleLineHeight), filterModeProp, OutlineEditorUtility.FilterSettingsContent);
|
||||
|
||||
if (filterModeProp.intValue == (int)OutlineFilterMode.UseLayerMask)
|
||||
{
|
||||
var layerMaskProp = property.FindPropertyRelative(_layerMaskPropName);
|
||||
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUI.PropertyField(new Rect(rc.x, rc.y + lineCy, rc.width, EditorGUIUtility.singleLineHeight), layerMaskProp, OutlineEditorUtility.LayerMaskContent);
|
||||
EditorGUI.indentLevel -= 1;
|
||||
|
||||
DrawSettingsInstance(new Rect(rc.x, rc.y + lineCy * 2, rc.width, rc.height - lineCy), property);
|
||||
}
|
||||
else if (filterModeProp.intValue == (int)OutlineFilterMode.UseRenderingLayerMask)
|
||||
{
|
||||
var renderingLayerMaskProp = property.FindPropertyRelative(_renderingLayerMaskPropName);
|
||||
|
||||
EditorGUI.indentLevel += 1;
|
||||
renderingLayerMaskProp.intValue = EditorGUI.MaskField(new Rect(rc.x, rc.y + lineCy, rc.width, EditorGUIUtility.singleLineHeight), OutlineEditorUtility.RenderingLayerMaskContent, renderingLayerMaskProp.intValue, _renderingLayerMaskNames);
|
||||
EditorGUI.indentLevel -= 1;
|
||||
|
||||
DrawSettingsInstance(new Rect(rc.x, rc.y + lineCy * 2, rc.width, rc.height - lineCy), property);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawSettingsInternal(Rect rc, SerializedProperty colorProp, SerializedProperty widthProp, SerializedProperty intensityProp, SerializedProperty cutoffProp, SerializedProperty renderModeProp)
|
||||
{
|
||||
var renderMode = (OutlineRenderFlags)renderModeProp.intValue;
|
||||
var lineCy = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
var n = 4;
|
||||
|
||||
//EditorGUI.PropertyField(new Rect(rc.x, rc.y + 1 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), colorProp, _colorContent);
|
||||
colorProp.colorValue = EditorGUI.ColorField(new Rect(rc.x, rc.y + 1 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), OutlineEditorUtility.ColorContent, colorProp.colorValue, true, true, true);
|
||||
|
||||
EditorGUI.PropertyField(new Rect(rc.x, rc.y + 2 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), widthProp, OutlineEditorUtility.WidthContent);
|
||||
|
||||
// NOTE: EditorGUI.PropertyField doesn't allow multi-selection, have to use EnumFlagsField explixitly.
|
||||
renderModeProp.intValue = (int)(OutlineRenderFlags)EditorGUI.EnumFlagsField(new Rect(rc.x, rc.y + 3 * lineCy, rc.width, EditorGUIUtility.singleLineHeight), OutlineEditorUtility.RenderFlagsContent, renderMode);
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.Blurred) != 0)
|
||||
{
|
||||
EditorGUI.PropertyField(new Rect(rc.x, rc.y + n++ * lineCy, rc.width, EditorGUIUtility.singleLineHeight), intensityProp, OutlineEditorUtility.BlurIntensityContent);
|
||||
}
|
||||
|
||||
if ((renderMode & OutlineRenderFlags.EnableAlphaTesting) != 0)
|
||||
{
|
||||
EditorGUI.PropertyField(new Rect(rc.x, rc.y + n * lineCy, rc.width, EditorGUIUtility.singleLineHeight), cutoffProp, OutlineEditorUtility.AlphaCutoffContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28f2a32d8600f8045a4b9a9916ff8801
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(OutlineSettingsInstance))]
|
||||
public class OutlineSettingsInstanceDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(rc, label, property);
|
||||
OutlineSettingsEditor.DrawSettingsInstance(rc, property);
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return OutlineSettingsEditor.GetSettingsInstanceHeight(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a7d070135166b04783f98841111c742
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2019-2021 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 UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityFx.Outline
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(OutlineSettingsWithLayerMask))]
|
||||
public class OutlineSettingsWithLayerMaskDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect rc, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(rc, label, property);
|
||||
OutlineSettingsEditor.DrawSettingsWithMask(rc, property);
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
return OutlineSettingsEditor.GetSettingsWithMaskHeight(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5558cd049bcb613438115d59a4376272
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user