This commit is contained in:
2025-07-20 21:01:09 +08:00
commit d2b8ce01f8
110 changed files with 6418 additions and 0 deletions
+113
View File
@@ -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:
+169
View File
@@ -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:
+100
View File
@@ -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:
+62
View File
@@ -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:
+240
View File
@@ -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: