Files
AR-Menu/Library/PackageCache/com.needle.engine-exporter@8c046140a1d9/Shaders/Editor/CustomShaderInspectorDrawer.cs
2025-11-30 08:35:03 +02:00

168 lines
5.6 KiB
C#

using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Needle.Engine.Shaders
{
internal static class CustomShaderInspectorDrawer
{
[InitializeOnLoadMethod]
private static void Init()
{
InspectorHook.Inject += OnInject;
}
private static void OnInject(Editor editor, VisualElement ui)
{
if(editor.targets.Length > 1) return;
var target = editor.target;
var targetMat = target as Material;
if (targetMat) target = targetMat.shader;
if (target is Shader shader)
{
if (shader.name.StartsWith("UnityGLTF/")) return;
// We can not edit immutable shaders
var shaderPath = AssetDatabase.GetAssetPath(shader);
// if (shaderPath.Contains("PackageCache")) return;
// Only shadergraph shaders are supported
// TODO do we want to show the upgrade button for all Skybox/Cubemap?
// Or only with ExportInfo? Or only when set as scene skybox?
if (shader.name == "Skybox/Cubemap" && ExportInfo.Get())
{
var skyboxUI = new VisualElement();
var hint = new HelpBox("This skybox can be upgraded to a Needle Skybox. It supports a nice background blur and more options.\n\n", HelpBoxMessageType.None);
hint.style.marginTop = 5;
skyboxUI.Add(hint);
var group = new VisualElement() { style =
{
flexDirection = FlexDirection.Row,
position = Position.Absolute,
alignContent = Align.FlexEnd,
right = 0,
bottom = 2,
} };
var upgradeButton = new Button(() =>
{
var mat = RenderSettings.skybox;
if (!mat) return;
Undo.RegisterCompleteObjectUndo(mat, "Changed Skybox Shader to Better Cubemap (Needle)");
if (editor is MaterialEditor materialEditor)
// This will call AssignNewShaderToMaterial correctly in contrast to mat.shader = ...
materialEditor.SetShader(Shader.Find("Skybox/Better Cubemap (Needle)"));
EditorUtility.SetDirty(mat);
skyboxUI.parent.Remove(skyboxUI);
})
{
text = "Upgrade now",
};
group.Add(upgradeButton);
hint.Add(group);
skyboxUI.style.marginBottom = 10;
if (ui.childCount > 1)
ui.Insert(1, skyboxUI);
else
ui.Add(skyboxUI);
return;
}
if (!shaderPath.EndsWith(".shadergraph")) return;
var isMarkedForExport = ShaderExporterRegistry.HasExportLabel(shader);
var customShaderSettings = new VisualElement();
var canBeEdited = !AssetDatabase.IsSubAsset(shader) && !shaderPath.Contains("PackageCache");
customShaderSettings.SetEnabled(canBeEdited);
if (!canBeEdited)
{
customShaderSettings.tooltip = "This shader can not be edited because it is a sub-asset or inside an immutable package. Please extract the shader/material first";
}
customShaderSettings.style.paddingLeft = 10;
customShaderSettings.style.paddingRight = 10;
customShaderSettings.style.marginTop = 10;
customShaderSettings.style.marginBottom = 10;
// insert the custom shader options at the top after the header
if (ui.childCount > 1)
ui.Insert(1, customShaderSettings);
else
ui.Add(customShaderSettings);
customShaderSettings.Add(new Label("Needle Engine — Custom Shader Settings")
{
style =
{
unityFontStyleAndWeight = FontStyle.Bold,
marginBottom = 5
}
});
var helpBox = new HelpBox();
var link = new Label("Open Documentation " + Constants.ExternalLinkChar)
{
style = { color = new Color(.3f, .6f, 1f), marginTop = 3}
};
link.AddManipulator(new Clickable(() =>
{
Application.OpenURL(Constants.DocumentationUrlCustomShader);
}));
var toggle = new Toggle("Export as Custom Shader");
toggle.value = isMarkedForExport;
toggle.RegisterValueChangedCallback(evt =>
{
ShaderExporterRegistry.SetExportLabel(shader, evt.newValue);
OnExportSettingHasChanged();
});
customShaderSettings.Add(toggle);
customShaderSettings.Add(helpBox);
if (!canBeEdited)
{
var helpbox2 = new HelpBox();
helpbox2.text += "This shader can not be edited because it is a sub-asset or inside an immutable package. Please extract the shader/material first (click this message to ping the shader)";
helpbox2.messageType = (HelpBoxMessageType) MessageType.Warning;
helpbox2.AddManipulator(new Clickable(() =>
{
EditorGUIUtility.PingObject(shader);
}));
customShaderSettings.Add(helpbox2);
}
customShaderSettings.Add(link);
void OnExportSettingHasChanged()
{
isMarkedForExport = ShaderExporterRegistry.HasExportLabel(shader);
helpBox.text = isMarkedForExport
? "This shader will be export as a custom shader to Needle Engine (Note that we only support exporting custom Unlit shaders at the moment)"
: "This shader is not marked as a custom shader for export to Needle Engine. It will instead be exported as a standard glTF material.";
helpBox.messageType = (HelpBoxMessageType)(isMarkedForExport ? MessageType.Info : MessageType.Warning);
toggle.value = isMarkedForExport;
}
OnExportSettingHasChanged();
// var imgui = new IMGUIContainer(() =>
// {
// GUILayout.Space(10);
// GUILayout.Label("Needle Engine — Custom Shader Settings", EditorStyles.boldLabel);
// GUILayout.Space(5);
// if (isMarkedForExport)
// EditorGUILayout.HelpBox("This shader is marked for export", MessageType.Info);
// else
// EditorGUILayout.HelpBox("This shader is not marked for export", MessageType.Warning);
//
// if (GUILayout.Button("Open Shader Editor"))
// {
//
// }
// });
// ui.Add(imgui);
}
}
}
}