初始化

This commit is contained in:
2026-06-05 22:12:05 +08:00
commit d7146f87ac
1999 changed files with 221608 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
{
"name": "EPOEditor",
"rootNamespace": "",
"references": [
"Unity.RenderPipelines.HighDefinition.Runtime",
"Unity.RenderPipelines.HighDefinition.Config.Runtime",
"Unity.RenderPipelines.Universal.Runtime",
"EPO",
"EPOUtilities",
"EPOURP",
"EPOHDRP"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.render-pipelines.high-definition",
"expression": "0.0.0",
"define": "HDRP_OUTLINE"
},
{
"name": "com.unity.render-pipelines.universal",
"expression": "0.0.0",
"define": "URP_OUTLINE"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: c6e98c0a3f7edf847b52f3103eb0cf1d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/EPO Editor.asmdef
uploadId: 710656

View File

@@ -0,0 +1,498 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEditor;
#if UNITY_6000_0_OR_NEWER
using UnityEditor.Build;
#endif
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;
using UnityEngine.Rendering;
#if HDRP_OUTLINE
using UnityEngine.Rendering.HighDefinition;
#endif
namespace EPOOutline
{
public class EPOSetuper : EditorWindow
{
private static readonly string SRPShownID = "EasyPerformantOutlineWasShownAndCanceled";
private static bool UPRWasFound = false;
private static bool HDRPWasFound = false;
private static ListRequest request;
private static AddRequest addRequest;
private Texture2D logoImage;
public enum SetupType
{
BuiltIn,
URP,
HDRP
}
[SerializeField]
private Vector2 scroll;
public static bool ShouldShow
{
get
{
return PlayerPrefs.GetInt(SRPShownID, 0) == 0;
}
set
{
PlayerPrefs.SetInt(SRPShownID, value ? 0 : 1);
}
}
private static
#if UNITY_6000_0_OR_NEWER
List<NamedBuildTarget>
#else
List<BuildTargetGroup>
#endif
GetApplicableGroups()
{
var groups = new List<BuildTargetGroup>();
var type = typeof(BuildTargetGroup);
var values = type.GetFields(BindingFlags.Public | BindingFlags.Static);
foreach (var value in values)
{
if (value.GetCustomAttribute<ObsoleteAttribute>() != null)
continue;
var targetValue = (BuildTargetGroup) value.GetValue(null);
if (targetValue == BuildTargetGroup.Unknown)
continue;
groups.Add(targetValue);
}
#if UNITY_6000_0_OR_NEWER
return groups.ConvertAll(NamedBuildTarget.FromBuildTargetGroup);
#else
return groups;
#endif
}
private static bool CheckHasDefinition(string definition)
{
var targets = GetApplicableGroups();
foreach (var buildTargetGroup in targets)
{
#if UNITY_6000_0_OR_NEWER
var definitions = PlayerSettings.GetScriptingDefineSymbols(buildTargetGroup);
#else
var definitions = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
#endif
var splited = definitions.Split(';');
if (Array.Find(splited, x => x == definition) == null)
return false;
}
return true;
}
#if URP_OUTLINE
private static bool CheckShouldFixFeature()
{
var activeAssets = PipelineAssetUtility.ActiveAssets;
foreach (var asset in activeAssets)
{
if (!PipelineAssetUtility.IsURP(asset))
continue;
if (!PipelineAssetUtility.DoesAssetContainsSRPOutlineFeature(asset))
return true;
}
return false;
}
#endif
#if URP_OUTLINE || HDRP_OUTLINE
public enum ExpectedAssetType
{
URP,
HDRP
}
private static bool CheckHasActiveRenderAssets(ExpectedAssetType type)
{
foreach (var asset in PipelineAssetUtility.ActiveAssets)
{
switch (type)
{
case ExpectedAssetType.URP:
if (PipelineAssetUtility.IsURP(asset))
return true;
break;
case ExpectedAssetType.HDRP:
if (PipelineAssetUtility.IsHDRP(asset))
return true;
break;
}
}
return false;
}
#endif
private void OnEnable()
{
EditorApplication.update += Check;
}
private void OnDisable()
{
EditorApplication.update -= Check;
}
private static void RemoveDefinition(string definition, Func<bool> check)
{
if (!check())
return;
var group = EditorUserBuildSettings.selectedBuildTargetGroup;
#if UNITY_6000_0_OR_NEWER
var definitions = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(group));
#else
var definitions = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
#endif
var splited = definitions.Split(';');
var builder = new StringBuilder();
var addedCount = 0;
foreach (var item in splited)
{
if (item == definition)
continue;
builder.Append(item);
builder.Append(';');
addedCount++;
}
if (addedCount != 0)
builder.Remove(builder.Length - 1, 1);
#if UNITY_6000_0_OR_NEWER
PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(group), builder.ToString());
#else
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, builder.ToString());
#endif
}
private static void Check()
{
if (EditorApplication.isPlaying)
return;
if (request == null || request.Error != null)
{
request = Client.List();
return;
}
if (!request.IsCompleted)
return;
UPRWasFound = HasURP(request.Result);
HDRPWasFound = HasHDRP(request.Result);
request = Client.List();
}
private static bool HasHDRP(PackageCollection result)
{
return HasPackage(result, "com.unity.render-pipelines.high-definition");
}
private static bool HasURP(PackageCollection result)
{
return HasPackage(result, "com.unity.render-pipelines.universal");
}
private static bool HasPackage(PackageCollection result, string packageName)
{
if (result == null)
return false;
var found = false;
var name = packageName;
foreach (var item in result)
{
if (item.name == name)
{
found = true;
break;
}
}
return found;
}
[MenuItem("Tools/Easy performant outline/Setup")]
private static void ForceShowWindow()
{
ShouldShow = true;
ShowWindow();
}
[MenuItem("Tools/Easy performant outline/Online docs")]
private static void ShowDocs()
{
Application.OpenURL("https://docs.google.com/document/d/17GvzvXNEjpEQ8DShRrVHKQ4I6s2tTVtwX6NzCZZ28AQ");
}
private static void ShowWindow()
{
if (!ShouldShow)
return;
var window = GetWindow<EPOSetuper>(true, "EPO Setuper", false);
window.maxSize = new Vector2(500, 500);
window.minSize = new Vector2(500, 500);
}
public void OnGUI()
{
if (logoImage == null)
logoImage = Resources.Load<Texture2D>("Easy performant outline/EP Outline logo");
var height = 180;
GUILayout.Space(height);
var imagePosition = new Rect(Vector2.zero, new Vector2(position.width, height));
GUI.DrawTexture(imagePosition, logoImage, ScaleMode.ScaleAndCrop, true);
GUILayout.Space(10);
if (GUILayout.Button("Open documentation"))
ShowDocs();
scroll = GUILayout.BeginScrollView(scroll);
if (EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Please stop running the app to start setup process", MessageType.Info);
if (GUILayout.Button("Stop"))
EditorApplication.isPlaying = false;
GUILayout.EndScrollView();
return;
}
if (EditorApplication.isCompiling)
{
EditorGUILayout.HelpBox(new GUIContent("Compiling... please wait."));
GUILayout.EndScrollView();
return;
}
EditorGUILayout.HelpBox("In order to make DOTween work, please enable it on the DOTween setup panel", MessageType.Warning);
EditorGUI.indentLevel = 0;
EditorPrefs.SetInt("SetupType", (int)(SetupType)EditorGUILayout.EnumPopup("Setup type", (SetupType)EditorPrefs.GetInt("SetupType")));
switch ((SetupType)EditorPrefs.GetInt("SetupType"))
{
case SetupType.BuiltIn:
DrawBuiltInSetup();
break;
case SetupType.URP:
DrawURPSetup();
break;
case SetupType.HDRP:
DrawHDRPSetup();
break;
}
GUILayout.EndScrollView();
}
private void DrawBuiltInSetup()
{
EditorGUILayout.HelpBox(new GUIContent("There is no need in making any changes to work with Built-In renderer. Just add Outliner to camera and Outlinable to the object you wish to highlight"));
}
private void DrawHDRPSetup()
{
if (addRequest != null && !addRequest.IsCompleted)
{
EditorGUILayout.HelpBox(new GUIContent("Adding package..."));
return;
}
var packageName = "com.unity.render-pipelines.high-definition";
if (!HDRPWasFound)
{
EditorGUILayout.HelpBox(new GUIContent("There is no package added. Chick 'Add' to add the pipeline package."));
if (GUILayout.Button("Add"))
addRequest = Client.Add(packageName);
return;
}
else
EditorGUILayout.HelpBox(new GUIContent("Pipeline asset has been found in packages"));
#if HDRP_OUTLINE
if (!CheckHasActiveRenderAssets(ExpectedAssetType.HDRP))
{
EditorGUILayout.HelpBox(new GUIContent("There is no renderer asset set up. Create one?"));
if (GUILayout.Button("Create"))
{
var path = EditorUtility.SaveFilePanelInProject("Asset location", "Rendering asset", "asset", "Select the folder to save rendering asset");
if (string.IsNullOrEmpty(path))
{
GUILayout.EndScrollView();
return;
}
var pathNoExt = Path.ChangeExtension(path, string.Empty);
pathNoExt = pathNoExt.Substring(0, pathNoExt.Length - 1);
var asset = PipelineAssetUtility.CreateHDRPAsset();
#if UNITY_6000_0_OR_NEWER
GraphicsSettings.defaultRenderPipeline = asset;
#else
GraphicsSettings.renderPipelineAsset = asset;
#endif
AssetDatabase.CreateAsset(asset, path);
}
}
else
EditorGUILayout.HelpBox(new GUIContent("At least one renderer asset is set up"));
#if UNITY_6000_0_OR_NEWER
var volume = FindAnyObjectByType<CustomPassVolume>();
#else
var volume = FindObjectOfType<CustomPassVolume>();
#endif
if (volume == null)
{
EditorGUILayout.HelpBox(new GUIContent("There is no custom pass volume in the scene. Click Add to fix it."));
if (GUILayout.Button("Add"))
{
var go = new GameObject("Custom volume");
go.AddComponent<CustomPassVolume>();
EditorUtility.SetDirty(go);
}
}
else
{
EditorGUILayout.HelpBox(new GUIContent("The scene has custom pass volume."));
if (volume.customPasses.Find(x => x is EPOOutline.OutlineCustomPass) == null)
{
EditorGUILayout.HelpBox(new GUIContent("The volume doesn't have custom pass. Click Add to fix it."));
if (GUILayout.Button("Add"))
{
volume.AddPassOfType(typeof(EPOOutline.OutlineCustomPass));
EditorUtility.SetDirty(volume);
}
}
else
EditorGUILayout.HelpBox(new GUIContent("The custom volume is set up"));
}
#endif
}
private void DrawURPSetup()
{
if (addRequest != null && !addRequest.IsCompleted)
{
EditorGUILayout.HelpBox(new GUIContent("Adding package..."));
return;
}
var packageName = "com.unity.render-pipelines.universal";
if (!UPRWasFound)
{
EditorGUILayout.HelpBox(new GUIContent("There is no package added. Chick 'Add' to add the pipeline package."));
if (GUILayout.Button("Add"))
addRequest = Client.Add(packageName);
return;
}
else
EditorGUILayout.HelpBox(new GUIContent("Pipeline asset has been found in packages"));
#if URP_OUTLINE
if (!CheckHasActiveRenderAssets(ExpectedAssetType.URP))
{
EditorGUILayout.HelpBox(new GUIContent("There is no renderer asset set up. Create one?"));
if (GUILayout.Button("Create"))
{
var path = EditorUtility.SaveFilePanelInProject("Asset location", "Rendering asset", "asset", "Select the folder to save rendering asset");
if (string.IsNullOrEmpty(path))
{
GUILayout.EndScrollView();
return;
}
var pathNoExt = Path.ChangeExtension(path, string.Empty);
pathNoExt = pathNoExt.Substring(0, pathNoExt.Length - 1);
var asset = PipelineAssetUtility.CreateAsset(pathNoExt);
#if UNITY_6000_0_OR_NEWER
GraphicsSettings.defaultRenderPipeline = asset;
#else
GraphicsSettings.renderPipelineAsset = asset;
#endif
}
}
else
EditorGUILayout.HelpBox(new GUIContent("At least one renderer asset is set up"));
if (CheckShouldFixFeature())
{
if (!GUILayout.Button("Add render features to all assets"))
return;
var assets = PipelineAssetUtility.ActiveAssets;
foreach (var asset in assets)
PipelineAssetUtility.AddRenderFeature(asset);
AssetDatabase.SaveAssets();
}
else
EditorGUILayout.HelpBox(new GUIContent("Feature is added for all renderers in use"));
#endif
}
public void OnDestroy()
{
ShouldShow = false;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b58e2aece6703fe4eafcb90a0d6072ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/EPOSetuper.cs
uploadId: 710656

View File

@@ -0,0 +1,225 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace EPOOutline
{
[CustomEditor(typeof(Outlinable))]
public class OutlinableEditor : Editor
{
private UnityEditorInternal.ReorderableList targetsList;
private void CheckList(SerializedProperty targets)
{
if (targetsList != null)
return;
targetsList = new UnityEditorInternal.ReorderableList(serializedObject, targets);
targetsList.drawHeaderCallback = position => EditorGUI.LabelField(position, "Renderers. All renderers that has to be outlined must be included here.");
targetsList.drawElementCallback = (position, item, isActive, isFocused) =>
{
var renderPosition = position;
var element = targets.GetArrayElementAtIndex(item);
var rendererItem = element.FindPropertyRelative("renderer");
var reference = rendererItem.objectReferenceValue;
EditorGUI.PropertyField(renderPosition, element, new GUIContent(reference == null ? "Null" : reference.name), true);
};
targetsList.elementHeightCallback = (index) => EditorGUI.GetPropertyHeight(targets.GetArrayElementAtIndex(index));
targetsList.onRemoveCallback = (list) =>
{
var index = list.index;
targets.DeleteArrayElementAtIndex(index);
targets.serializedObject.ApplyModifiedProperties();
};
targetsList.onAddDropdownCallback = (buttonRect, targetList) =>
{
var outlinable = target as Outlinable;
var items = outlinable.gameObject.GetComponentsInChildren<Renderer>(true);
var menu = new GenericMenu();
if (!Application.isPlaying)
{
menu.AddItem(new GUIContent("Add all renderers"), false, () =>
{
(target as Outlinable).AddAllChildRenderersToRenderingList(RenderersAddingMode.All);
EditorUtility.SetDirty(target);
});
menu.AddItem(new GUIContent("Add all basic renderers"), false, () =>
{
(target as Outlinable).AddAllChildRenderersToRenderingList(RenderersAddingMode.MeshRenderer | RenderersAddingMode.SkinnedMeshRenderer);
EditorUtility.SetDirty(target);
});
menu.AddItem(new GUIContent("Add all skinned mesh renderers"), false, () =>
{
(target as Outlinable).AddAllChildRenderersToRenderingList(RenderersAddingMode.SkinnedMeshRenderer);
EditorUtility.SetDirty(target);
});
menu.AddItem(new GUIContent("Add all mesh renderers"), false, () =>
{
(target as Outlinable).AddAllChildRenderersToRenderingList(RenderersAddingMode.MeshRenderer);
EditorUtility.SetDirty(target);
});
menu.AddItem(new GUIContent("Add all sprite renderers"), false, () =>
{
(target as Outlinable).AddAllChildRenderersToRenderingList(RenderersAddingMode.SpriteRenderer);
EditorUtility.SetDirty(target);
});
}
var entryIndex = -1;
foreach (var item in items)
{
entryIndex++;
var submeshCount = RendererUtility.GetSubmeshCount(item);
var path = string.Empty;
if (item.transform != outlinable.transform)
{
var parent = item.transform;
do
{
path = $"{parent}/{path}";
parent = parent.transform.parent;
} while (parent != outlinable.transform);
path = $"{parent}/{path}";
path = path.Substring(0, path.Length - 1);
}
else
path = item.ToString();
var foundSubmeshes = new HashSet<int>();
for (var submeshIndex = 0; submeshIndex < submeshCount; submeshIndex++)
{
var found = false;
for (var index = 0; index < targets.arraySize; index++)
{
var element = targets.GetArrayElementAtIndex(index);
var elementRenderer = element.FindPropertyRelative("renderer");
if (elementRenderer.objectReferenceValue != item)
continue;
var submesh = element.FindPropertyRelative("SubmeshIndex");
if (submesh.intValue != submeshIndex)
continue;
found = true;
foundSubmeshes.Add(submeshIndex);
break;
}
var submeshChunk = submeshCount > 1 ? $"{path}/sub mesh {submeshIndex}" : path;
var finalPath = $"{entryIndex}: {submeshChunk}";
var capturedSubmeshIndex = submeshIndex;
GenericMenu.MenuFunction function = () =>
{
var index = targets.arraySize;
targets.InsertArrayElementAtIndex(index);
var arrayItem = targets.GetArrayElementAtIndex(index);
var renderer = arrayItem.FindPropertyRelative("renderer");
arrayItem.FindPropertyRelative("CutoutThreshold").floatValue = 0.5f;
arrayItem.FindPropertyRelative("SubmeshIndex").intValue = capturedSubmeshIndex;
renderer.objectReferenceValue = item;
serializedObject.ApplyModifiedProperties();
};
if (found)
function = null;
menu.AddItem(new GUIContent(finalPath), found, function);
}
if (submeshCount <= 1)
continue;
GenericMenu.MenuFunction allFunction = () =>
{
for (var submeshIndex = 0; submeshIndex < submeshCount; submeshIndex++)
{
if (foundSubmeshes.Contains(submeshIndex))
continue;
var index = targets.arraySize;
targets.InsertArrayElementAtIndex(index);
var arrayItem = targets.GetArrayElementAtIndex(index);
var renderer = arrayItem.FindPropertyRelative("renderer");
arrayItem.FindPropertyRelative("CutoutThreshold").floatValue = 0.5f;
arrayItem.FindPropertyRelative("SubmeshIndex").intValue = submeshIndex;
renderer.objectReferenceValue = item;
serializedObject.ApplyModifiedProperties();
}
};
if (foundSubmeshes.Count == submeshCount)
allFunction = null;
menu.AddItem(new GUIContent($"{entryIndex}: {path}/All sub meshes"), foundSubmeshes.Count == submeshCount, allFunction);
}
menu.ShowAsContext();
};
}
public override void OnInspectorGUI()
{
if ((serializedObject.FindProperty("drawingMode").intValue & (int)OutlinableDrawingMode.Normal) != 0)
{
if (serializedObject.FindProperty("renderStyle").intValue == 1)
{
DrawPropertiesExcluding(serializedObject,
"frontParameters",
"backParameters",
"outlineTargets",
"outlineTargets",
"m_Script");
}
else
{
DrawPropertiesExcluding(serializedObject,
"outlineParameters",
"outlineTargets",
"outlineTargets",
"m_Script");
}
}
else
{
DrawPropertiesExcluding(serializedObject,
"outlineParameters",
"frontParameters",
"backParameters",
"outlineTargets",
"m_Script");
}
serializedObject.ApplyModifiedProperties();
var renderers = serializedObject.FindProperty("outlineTargets");
CheckList(renderers);
if (serializedObject.targetObjects.Count() == 1)
targetsList.DoLayoutList();
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 64671a2d6446a3340bcb913f96ca0af3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/OutlinableEditor.cs
uploadId: 710656

View File

@@ -0,0 +1,82 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace EPOOutline
{
[CustomPropertyDrawer(typeof(Outlinable.OutlineProperties))]
public class OutlinePropertiesPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var labelPosition = position;
labelPosition.height = EditorGUIUtility.singleLineHeight;
var enabledProperty = property.FindPropertyRelative("enabled");
enabledProperty.boolValue = EditorGUI.ToggleLeft(labelPosition, label, enabledProperty.boolValue);
var drawingPosition = position;
drawingPosition.width -= EditorGUIUtility.singleLineHeight * 1.5f;
drawingPosition.x += EditorGUIUtility.singleLineHeight;
drawingPosition.height = EditorGUIUtility.singleLineHeight;
NewLine(ref drawingPosition);
var infoPosition = drawingPosition;
infoPosition.height = EditorGUIUtility.singleLineHeight * 3.0f + EditorGUIUtility.standardVerticalSpacing * 2.0f;
EditorGUI.HelpBox(infoPosition, "Changing dilate and blur settings will enable info buffer which will increase draw calls and will have some performance impact. Use Outliner settings if you don't need per object settings.", MessageType.Warning);
NewLine(ref drawingPosition);
NewLine(ref drawingPosition);
NewLine(ref drawingPosition);
var colorPosition = drawingPosition;
colorPosition.width = 46;
var colorProperty = property.FindPropertyRelative("color");
colorProperty.colorValue = EditorGUI.ColorField(colorPosition, GUIContent.none, colorProperty.colorValue, true, true, true);
float width = 45;
var shiftPropertiesPositions = drawingPosition;
shiftPropertiesPositions.x += colorPosition.width + EditorGUIUtility.standardVerticalSpacing;
shiftPropertiesPositions.width -= colorPosition.width + EditorGUIUtility.standardVerticalSpacing;
shiftPropertiesPositions.width /= 2;
shiftPropertiesPositions.width -= EditorGUIUtility.standardVerticalSpacing + width;
shiftPropertiesPositions.x += width;
var labelRect = shiftPropertiesPositions;
labelRect.x -= width - EditorGUIUtility.singleLineHeight * 0.25f;
labelRect.width = width - EditorGUIUtility.singleLineHeight * 0.5f;
EditorGUI.LabelField(labelRect, new GUIContent("Dilate"));
EditorGUI.PropertyField(shiftPropertiesPositions, property.FindPropertyRelative("dilateShift"), GUIContent.none);
shiftPropertiesPositions.x += shiftPropertiesPositions.width + EditorGUIUtility.standardVerticalSpacing + width;
labelRect.x += shiftPropertiesPositions.width + width;
EditorGUI.LabelField(labelRect, new GUIContent("Blur"));
EditorGUI.PropertyField(shiftPropertiesPositions, property.FindPropertyRelative("blurShift"), GUIContent.none);
NewLine(ref drawingPosition);
EditorGUI.PropertyField(drawingPosition, property.FindPropertyRelative("fillPass"), new GUIContent("Fill parameters"));
property.serializedObject.ApplyModifiedProperties();
}
private void NewLine(ref Rect rect)
{
rect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * 3.0f + EditorGUI.GetPropertyHeight(property.FindPropertyRelative("fillPass")) +
EditorGUIUtility.singleLineHeight * 2.0f + EditorGUIUtility.standardVerticalSpacing * 1.0f;// + EditorGUI.GetPropertyHeight(property.FindPropertyRelative("outlineRenderingPass"));
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: db921f9fa4de2e642981132a45747b41
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/OutlinePropertiesPropertyDrawer.cs
uploadId: 710656

View File

@@ -0,0 +1,181 @@
using UnityEditor;
using UnityEngine;
namespace EPOOutline
{
[CustomPropertyDrawer(typeof(OutlineTarget))]
public class OutlineTargetPropertyDrawer : PropertyDrawer
{
private void Shift(ref Rect rect, bool right)
{
if (right)
rect.x += EditorGUIUtility.singleLineHeight;
rect.width -= EditorGUIUtility.singleLineHeight * (right ? 1.0f : 0.5f);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var initialPosition = position;
var labelWidth = EditorGUIUtility.labelWidth;
position.y += EditorGUIUtility.singleLineHeight * 0.2f;
position.height = EditorGUIUtility.singleLineHeight;
var rendererPosition = position;
rendererPosition.width = position.width / 2;
Shift(ref rendererPosition, false);
var renderer = property.FindPropertyRelative("renderer");
EditorGUI.PropertyField(rendererPosition, renderer, GUIContent.none);
var menu = new GenericMenu();
var textureNameProperty = property.FindPropertyRelative("cutoutTextureName");
var cutoutIsInUse = !string.IsNullOrEmpty(textureNameProperty.stringValue);
menu.AddItem(new GUIContent("none"), string.IsNullOrEmpty(textureNameProperty.stringValue), () =>
{
textureNameProperty.stringValue = string.Empty;
textureNameProperty.serializedObject.ApplyModifiedProperties();
});
var rendererReference = renderer.objectReferenceValue as Renderer;
var referenceName = "none";
var usingCutout = cutoutIsInUse && rendererReference != null;
if (rendererReference != null)
{
var materialSubMeshIndex = property.FindPropertyRelative("SubmeshIndex").intValue;
var materials = rendererReference.sharedMaterials;
if (materials.Length > 0)
{
var material = materials[materialSubMeshIndex % materials.Length];
if (material != null)
{
var propertiesCount = ShaderUtil.GetPropertyCount(material.shader);
for (var index = 0; index < propertiesCount; index++)
{
var propertyType = ShaderUtil.GetPropertyType(material.shader, index);
if (propertyType != ShaderUtil.ShaderPropertyType.TexEnv)
continue;
var propertyName = ShaderUtil.GetPropertyName(material.shader, index);
var equals = propertyName == textureNameProperty.stringValue;
if (equals)
referenceName = ShaderUtil.GetPropertyDescription(material.shader, index) + " '" +
propertyName + "'";
menu.AddItem(
new GUIContent(ShaderUtil.GetPropertyDescription(material.shader, index) + " '" +
propertyName + "'"), equals && usingCutout, () =>
{
textureNameProperty.stringValue = propertyName;
textureNameProperty.serializedObject.ApplyModifiedProperties();
});
}
}
}
}
var cutoutPosition = position;
cutoutPosition.x = rendererPosition.x + rendererPosition.width;
cutoutPosition.width -= rendererPosition.width;
Shift(ref cutoutPosition, true);
var sourceLable = usingCutout ? referenceName : "none";
var cutoutSourceLabel = "Cutout source: " + sourceLable;
if (EditorGUI.DropdownButton(cutoutPosition, new GUIContent(cutoutSourceLabel), FocusType.Passive))
menu.ShowAsContext();
var drawingPosition = position;
EditorGUIUtility.labelWidth = 80;
drawingPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
var boundsModePosition = initialPosition;
boundsModePosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing * 3.0f;
boundsModePosition.width = cutoutPosition.width / 2.0f;
boundsModePosition.height = EditorGUIUtility.singleLineHeight;
EditorGUI.LabelField(boundsModePosition, new GUIContent("Bounds mode"));
boundsModePosition.x += boundsModePosition.width;
EditorGUI.PropertyField(boundsModePosition, property.FindPropertyRelative("BoundsMode"), GUIContent.none);
boundsModePosition.x += boundsModePosition.width;
EditorGUIUtility.labelWidth = 90;
boundsModePosition.width = drawingPosition.width / 2.0f;
Shift(ref boundsModePosition, true);
if (usingCutout)
EditorGUI.PropertyField(boundsModePosition, property.FindPropertyRelative("cutoutTextureIndex"), new GUIContent("Texture index"));
if (property.FindPropertyRelative("BoundsMode").intValue == (int)BoundsMode.Manual)
{
drawingPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawingPosition, property.FindPropertyRelative("Bounds"), GUIContent.none);
drawingPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
EditorGUIUtility.labelWidth = labelWidth;
if (usingCutout || rendererReference is SpriteRenderer)
{
drawingPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawingPosition, property.FindPropertyRelative("CutoutThreshold"));
drawingPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawingPosition, property.FindPropertyRelative("CutoutMask"));
}
drawingPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
var linePosition = drawingPosition;
linePosition.width /= 2;
Shift(ref linePosition, false);
var cullPosition = linePosition;
cullPosition.width /= 2;
EditorGUI.LabelField(cullPosition, new GUIContent("Cull mode"));
cullPosition.x += cullPosition.width;
EditorGUI.PropertyField(cullPosition, property.FindPropertyRelative("CullMode"), GUIContent.none);
linePosition.x += linePosition.width;
Shift(ref linePosition, true);
var submeshIndex = property.FindPropertyRelative("SubmeshIndex");
EditorGUIUtility.labelWidth = 90;
EditorGUI.PropertyField(linePosition, submeshIndex);
if (submeshIndex.intValue < 0)
submeshIndex.intValue = 0;
EditorGUIUtility.labelWidth = labelWidth;
property.serializedObject.ApplyModifiedProperties();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var renderer = property.FindPropertyRelative("renderer");
var rendererReference = renderer.objectReferenceValue as Renderer;
var textureNameProperty = property.FindPropertyRelative("cutoutTextureName");
var usingCutout = !string.IsNullOrEmpty(textureNameProperty.stringValue);
var linesCount = 3.0f;
if (usingCutout || rendererReference is SpriteRenderer)
linesCount += 2.0f;
if (property.FindPropertyRelative("BoundsMode").intValue == (int)BoundsMode.Manual)
linesCount += 2.0f;
return (EditorGUIUtility.standardVerticalSpacing + EditorGUIUtility.singleLineHeight) * (linesCount + 0.5f);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e73fd235d4c252b44bc8b184f615c88c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/OutlineTargetPropertyDrawer.cs
uploadId: 710656

View File

@@ -0,0 +1,114 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace EPOOutline
{
[CustomEditor(typeof(Outliner))]
public class OutlinerEditor : Editor
{
public override void OnInspectorGUI()
{
var maskProperty = serializedObject.FindProperty("outlineLayerMask");
var currentMask = maskProperty.longValue;
var maskValue = "Mask: none";
if (currentMask == -1 || currentMask == long.MaxValue)
maskValue = "Mask: all";
else if (currentMask != 0)
maskValue = "Mask: mixed";
if (GUILayout.Button(maskValue, EditorStyles.layerMaskField))
{
var maskMenu = new GenericMenu();
maskMenu.AddItem(new GUIContent("none"), currentMask == 0, () =>
{
maskProperty.longValue = 0;
serializedObject.ApplyModifiedProperties();
});
maskMenu.AddItem(new GUIContent("all"), currentMask == -1 || currentMask == long.MaxValue, () =>
{
maskProperty.longValue = -1;
serializedObject.ApplyModifiedProperties();
});
for (var index = 0; index < sizeof(long) * 8; index++)
{
var capturedIndex = index;
if (index >= 20)
{
var decima = index / 10;
var lowerDecima = decima * 10;
var higherDecima = (decima + 1) * 10;
if (higherDecima > 63)
higherDecima = 63;
maskMenu.AddItem(new GUIContent(lowerDecima + "-" + higherDecima + "/" + index), (currentMask & 1 << index) != 0, () =>
{
maskProperty.longValue = currentMask ^ (1 << capturedIndex);
serializedObject.ApplyModifiedProperties();
});
}
else
{
maskMenu.AddItem(new GUIContent(index.ToString()), (currentMask & 1 << index) != 0, () =>
{
maskProperty.longValue = currentMask ^ (1 << capturedIndex);
serializedObject.ApplyModifiedProperties();
});
}
}
maskMenu.ShowAsContext();
}
#if (URP_OUTLINE || HDRP_OUTLINE)
var isHDRP = PipelineAssetUtility.IsHDRP(PipelineAssetUtility.CurrentAsset);
#else
var isHDRP = false;
#endif
if (isHDRP)
{
DrawPropertiesExcluding(serializedObject,
"m_Script",
"outlineLayerMask",
"primaryRendererScale",
"primaryBufferSizeMode",
"primarySizeReference",
"renderingMode");
}
else
{
var itemsToExclude = new List<string>
{
"m_Script",
"outlineLayerMask"
};
var mode = (BufferSizeMode)serializedObject.FindProperty("primaryBufferSizeMode").intValue;
switch (mode)
{
case BufferSizeMode.Native:
itemsToExclude.Add("primaryRendererScale");
itemsToExclude.Add("primarySizeReference");
break;
case BufferSizeMode.Scaled:
itemsToExclude.Add("primarySizeReference");
break;
case BufferSizeMode.HeightControlsWidth:
case BufferSizeMode.WidthControlsHeight:
itemsToExclude.Add("primaryRendererScale");
break;
}
DrawPropertiesExcluding(serializedObject, propertyToExclude: itemsToExclude.ToArray());
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 52a30cffbedc74949b39fa234f443134
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/OutlinerEditor.cs
uploadId: 710656

View File

@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
#if URP_OUTLINE
using UnityEngine.Rendering.Universal;
#endif
#if HDRP_OUTLINE
using UnityEngine.Rendering.HighDefinition;
#endif
namespace EPOOutline
{
#if (URP_OUTLINE || HDRP_OUTLINE) && UNITY_EDITOR
public static class PipelineAssetUtility
{
public static RenderPipelineAsset CurrentAsset
{
get
{
return PipelineFetcher.CurrentAsset;
}
}
public static HashSet<RenderPipelineAsset> ActiveAssets
{
get
{
var set = new HashSet<RenderPipelineAsset>();
#if UNITY_6000_0_OR_NEWER
if (GraphicsSettings.defaultRenderPipeline != null)
set.Add(GraphicsSettings.defaultRenderPipeline);
#else
if (GraphicsSettings.renderPipelineAsset != null)
set.Add(GraphicsSettings.renderPipelineAsset);
#endif
var qualitySettingNames = QualitySettings.names;
for (var index = 0; index < qualitySettingNames.Length; index++)
{
var assset = QualitySettings.GetRenderPipelineAssetAt(index);
if (assset == null)
continue;
set.Add(assset);
}
return set;
}
}
#if URP_OUTLINE
public static object GetDefault(Type type)
{
if(type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
public static RenderPipelineAsset CreateAsset(string path)
{
var method = typeof(UniversalRenderPipelineAsset)
.GetMethod("CreateRendererAsset", BindingFlags.NonPublic | BindingFlags.Static);
var methodParams = method.GetParameters();
object[] parameters = new object[methodParams.Length];
for (var index = 0; index < methodParams.Length; index++)
parameters[index] = GetDefault(methodParams[index].ParameterType);
var possibleParameters = new object[] {path + " renderer.asset", (RendererType)1, false, "Renderer"};
for (var index = 0; index < Mathf.Min(possibleParameters.Length, parameters.Length); index++)
parameters[index] = possibleParameters[index];
var data = method.Invoke(null, parameters) as ScriptableRendererData;
var pipeline = UniversalRenderPipelineAsset.Create(data);
AssetDatabase.CreateAsset(pipeline, path + ".asset");
return pipeline;
}
#endif
#if HDRP_OUTLINE
public static RenderPipelineAsset CreateHDRPAsset()
{
return ScriptableObject.CreateInstance<HDRenderPipelineAsset>();
}
#endif
public static bool IsURP(RenderPipelineAsset asset)
{
return asset != null &&
asset.GetType().Name.Equals("UniversalRenderPipelineAsset");
}
public static bool IsHDRP(RenderPipelineAsset asset)
{
return asset != null &&
asset.GetType().Name.Equals("HDRenderPipelineAsset");
}
#if URP_OUTLINE
public static ScriptableRendererData GetRenderer(RenderPipelineAsset asset)
{
using (var so = new SerializedObject(asset))
{
so.Update();
#if URP_OUTLINE
var rendererDataList = so.FindProperty("m_RendererDataList");
var assetIndex = so.FindProperty("m_DefaultRendererIndex");
var item = rendererDataList.GetArrayElementAtIndex(assetIndex.intValue);
return item.objectReferenceValue as ScriptableRendererData;
#else
return null;
#endif
}
}
public static bool DoesAssetContainsSRPOutlineFeature(RenderPipelineAsset asset)
{
var data = GetRenderer(asset);
return data.rendererFeatures.Find(x => x is URPOutlineFeature) != null;
}
public static void AddRenderFeature(RenderPipelineAsset asset)
{
if (DoesAssetContainsSRPOutlineFeature(asset))
return;
var data = GetRenderer(asset);
var instance = ScriptableObject.CreateInstance<URPOutlineFeature>();
instance.name = "EPO Feature";
data.rendererFeatures.Add(instance);
AssetDatabase.AddObjectToAsset(instance, data);
EditorUtility.SetDirty(data);
}
#endif
}
#endif
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: fc4dea52e032c8d48a1e40b2c76dc752
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/PipelineAssetUtility.cs
uploadId: 710656

View File

@@ -0,0 +1,181 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace EPOOutline
{
[CustomPropertyDrawer(typeof(SerializedPass))]
public class SerializedPassPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var drawingPosition = position;
drawingPosition.height = EditorGUIUtility.singleLineHeight;
var shaderProperty = property.FindPropertyRelative("shader");
var currentShaderReference = shaderProperty.objectReferenceValue as Shader;
var prefix = "Hidden/EPO/Fill/";
var fillLabel = currentShaderReference == null ? "none" : currentShaderReference.name.Substring(prefix.Length);
if (shaderProperty.hasMultipleDifferentValues)
fillLabel = "-";
if (EditorGUI.DropdownButton(position, new GUIContent(label.text + " : " + fillLabel), FocusType.Passive))
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent("none"), currentShaderReference == null && !shaderProperty.hasMultipleDifferentValues, () =>
{
shaderProperty.objectReferenceValue = null;
shaderProperty.serializedObject.ApplyModifiedProperties();
});
var shaders = AssetDatabase.FindAssets("t:Shader");
foreach (var shader in shaders)
{
var loadedShader = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(shader), typeof(Shader)) as Shader;
if (!loadedShader.name.StartsWith(prefix))
continue;
var shaderName = loadedShader.name.Substring(prefix.Length);
if (shaderName.StartsWith("Utils"))
continue;
menu.AddItem(new GUIContent(shaderName), loadedShader == shaderProperty.objectReferenceValue && !shaderProperty.hasMultipleDifferentValues, () =>
{
shaderProperty.objectReferenceValue = loadedShader;
shaderProperty.serializedObject.ApplyModifiedProperties();
});
}
menu.ShowAsContext();
}
if (shaderProperty.hasMultipleDifferentValues)
return;
if (currentShaderReference != null)
{
position.x += EditorGUIUtility.singleLineHeight;
position.width -= EditorGUIUtility.singleLineHeight;
var properties = new Dictionary<string, SerializedProperty>();
var serializedProperties = property.FindPropertyRelative("serializedProperties");
for (var index = 0; index < serializedProperties.arraySize; index++)
{
var subProperty = serializedProperties.GetArrayElementAtIndex(index);
var propertyName = subProperty.FindPropertyRelative("PropertyName");
var propertyValue = subProperty.FindPropertyRelative("Property");
if (propertyName == null || propertyValue == null)
break;
properties.Add(propertyName.stringValue, propertyValue);
}
var fillParametersPosition = position;
fillParametersPosition.height = EditorGUIUtility.singleLineHeight;
for (var index = 0; index < ShaderUtil.GetPropertyCount(currentShaderReference); index++)
{
var propertyName = ShaderUtil.GetPropertyName(currentShaderReference, index);
if (!propertyName.StartsWith("_Public"))
continue;
fillParametersPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
SerializedProperty currentProperty;
if (!properties.TryGetValue(propertyName, out currentProperty))
{
serializedProperties.InsertArrayElementAtIndex(serializedProperties.arraySize);
currentProperty = serializedProperties.GetArrayElementAtIndex(serializedProperties.arraySize - 1);
currentProperty.FindPropertyRelative("PropertyName").stringValue = propertyName;
currentProperty = currentProperty.FindPropertyRelative("Property");
var tempMaterial = new Material(currentShaderReference);
switch (ShaderUtil.GetPropertyType(currentShaderReference, index))
{
case ShaderUtil.ShaderPropertyType.Color:
currentProperty.FindPropertyRelative("ColorValue").colorValue = tempMaterial.GetColor(propertyName);
break;
case ShaderUtil.ShaderPropertyType.Vector:
currentProperty.FindPropertyRelative("VectorValue").vector4Value = tempMaterial.GetVector(propertyName);
break;
case ShaderUtil.ShaderPropertyType.Float:
currentProperty.FindPropertyRelative("FloatValue").floatValue = tempMaterial.GetFloat(propertyName);
break;
case ShaderUtil.ShaderPropertyType.Range:
currentProperty.FindPropertyRelative("FloatValue").floatValue = tempMaterial.GetFloat(propertyName);
break;
case ShaderUtil.ShaderPropertyType.TexEnv:
currentProperty.FindPropertyRelative("TextureValue").objectReferenceValue = tempMaterial.GetTexture(propertyName);
break;
}
GameObject.DestroyImmediate(tempMaterial);
properties.Add(propertyName, currentProperty);
}
if (currentProperty == null)
continue;
var content = new GUIContent(ShaderUtil.GetPropertyDescription(currentShaderReference, index));
switch (ShaderUtil.GetPropertyType(currentShaderReference, index))
{
case ShaderUtil.ShaderPropertyType.Color:
var colorProperty = currentProperty.FindPropertyRelative("ColorValue");
colorProperty.colorValue = EditorGUI.ColorField(fillParametersPosition, content, colorProperty.colorValue, true, true, true);
break;
case ShaderUtil.ShaderPropertyType.Vector:
var vectorProperty = currentProperty.FindPropertyRelative("VectorValue");
vectorProperty.vector4Value = EditorGUI.Vector4Field(fillParametersPosition, content, vectorProperty.vector4Value);
break;
case ShaderUtil.ShaderPropertyType.Float:
EditorGUI.PropertyField(fillParametersPosition, currentProperty.FindPropertyRelative("FloatValue"), content);
break;
case ShaderUtil.ShaderPropertyType.Range:
var floatProperty = currentProperty.FindPropertyRelative("FloatValue");
floatProperty.floatValue = EditorGUI.Slider(fillParametersPosition, content, floatProperty.floatValue,
ShaderUtil.GetRangeLimits(currentShaderReference, index, 1),
ShaderUtil.GetRangeLimits(currentShaderReference, index, 2));
break;
case ShaderUtil.ShaderPropertyType.TexEnv:
EditorGUI.PropertyField(fillParametersPosition, currentProperty.FindPropertyRelative("TextureValue"), content);
break;
}
currentProperty.FindPropertyRelative("PropertyType").intValue = (int)ShaderUtil.GetPropertyType(currentShaderReference, index);
}
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (property.FindPropertyRelative("shader").hasMultipleDifferentValues)
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
var shaderProperty = property.FindPropertyRelative("shader");
var currentShaderReference = shaderProperty.objectReferenceValue as Shader;
var additionalCount = 0;
if (currentShaderReference != null)
{
for (var index = 0; index < ShaderUtil.GetPropertyCount(currentShaderReference); index++)
{
var propertyName = ShaderUtil.GetPropertyName(currentShaderReference, index);
if (!propertyName.StartsWith("_Public"))
continue;
additionalCount++;
}
}
return (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing) * (additionalCount + 1);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: ee58bf6e03314ac44a3aefa3e59475f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 157187
packageName: Easy Performant Outline 2D | 3D (URP / HDRP and Built-in Renderer)
packageVersion: 3.5.7
assetPath: Assets/Plugins/Easy performant outline/Scripts/Editor/SerializedPassPropertyDrawer.cs
uploadId: 710656