215 lines
6.5 KiB
C#
215 lines
6.5 KiB
C#
// 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);
|
|
}
|
|
}
|
|
}
|