Files
ichni_Official/Packages/NB_FX/NBShaders2/Editor/FeatureLevel/NBShaderSVCBuilderWindow.cs
SoulliesOfficial 40fa80cd70 NB_FX
2026-07-17 17:46:16 -04:00

291 lines
11 KiB
C#

using System.Collections.Generic;
using NBShader;
using UnityEditor;
using UnityEngine;
namespace NBShaders2.Editor.FeatureLevel
{
internal sealed class NBShaderSVCBuilderWindow : EditorWindow
{
[SerializeField] private List<string> m_SearchFolders = new List<string>();
[SerializeField] private string m_OutputFolder = NBShaderVariantCollectionBuilder.DefaultOutputFolder;
[SerializeField] private int m_TierMask = AllTierMask;
private Vector2 m_Scroll;
private NBShaderVariantCollectionTierResult[] m_Previews = new NBShaderVariantCollectionTierResult[0];
private string m_Status = string.Empty;
private const int AllTierMask =
(1 << (int)NBShaderFeatureTier.Low) |
(1 << (int)NBShaderFeatureTier.Medium) |
(1 << (int)NBShaderFeatureTier.High) |
(1 << (int)NBShaderFeatureTier.Ultra);
private static readonly NBShaderFeatureTier[] Tiers =
{
NBShaderFeatureTier.Low,
NBShaderFeatureTier.Medium,
NBShaderFeatureTier.High,
NBShaderFeatureTier.Ultra
};
internal static void Open()
{
var window = GetWindow<NBShaderSVCBuilderWindow>("NBShader Variant Collection Builder");
window.minSize = new Vector2(620f, 420f);
window.Show();
}
private void OnEnable()
{
if (m_SearchFolders == null)
m_SearchFolders = new List<string>();
if (m_SearchFolders.Count == 0)
m_SearchFolders.Add("Assets");
if (string.IsNullOrEmpty(m_OutputFolder))
m_OutputFolder = NBShaderVariantCollectionBuilder.DefaultOutputFolder;
if (m_TierMask == 0)
m_TierMask = AllTierMask;
}
private void OnGUI()
{
m_Scroll = EditorGUILayout.BeginScrollView(m_Scroll);
DrawSearchFolders();
EditorGUILayout.Space(8f);
DrawOutputFolder();
EditorGUILayout.Space(8f);
DrawTierSelection();
EditorGUILayout.Space(8f);
DrawActions();
EditorGUILayout.Space(8f);
DrawPreview();
EditorGUILayout.EndScrollView();
}
private void DrawSearchFolders()
{
EditorGUILayout.LabelField("Material Search Folders", EditorStyles.boldLabel);
for (var i = 0; i < m_SearchFolders.Count; i++)
{
EditorGUILayout.BeginHorizontal();
m_SearchFolders[i] = EditorGUILayout.TextField(m_SearchFolders[i]);
if (GUILayout.Button("...", GUILayout.Width(28f)))
{
var folder = PickProjectFolder(m_SearchFolders[i]);
if (!string.IsNullOrEmpty(folder))
m_SearchFolders[i] = folder;
}
if (GUILayout.Button("-", GUILayout.Width(28f)))
{
m_SearchFolders.RemoveAt(i);
GUIUtility.ExitGUI();
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add Folder"))
{
var folder = PickProjectFolder("Assets");
if (!string.IsNullOrEmpty(folder))
AddSearchFolder(folder);
}
if (GUILayout.Button("Add Selected"))
{
AddSelectedFolders();
}
EditorGUILayout.EndHorizontal();
}
private void DrawOutputFolder()
{
EditorGUILayout.LabelField("Output Folder", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
m_OutputFolder = EditorGUILayout.TextField(m_OutputFolder);
if (GUILayout.Button("...", GUILayout.Width(28f)))
{
var folder = PickProjectFolder(m_OutputFolder);
if (!string.IsNullOrEmpty(folder))
m_OutputFolder = folder;
}
EditorGUILayout.EndHorizontal();
}
private void DrawTierSelection()
{
EditorGUILayout.LabelField("Build Tiers", EditorStyles.boldLabel);
using (new EditorGUILayout.HorizontalScope())
{
for (var i = 0; i < Tiers.Length; i++)
DrawTierToggle(Tiers[i]);
GUILayout.FlexibleSpace();
if (GUILayout.Button("All", GUILayout.Width(56f)))
SetTierMask(AllTierMask);
}
if (!HasSelectedTier())
EditorGUILayout.HelpBox("Select at least one tier before previewing or generating SVC assets.", MessageType.Warning);
}
private void DrawTierToggle(NBShaderFeatureTier tier)
{
var selected = IsTierSelected(tier);
var newSelected = EditorGUILayout.ToggleLeft(tier.ToString(), selected, GUILayout.Width(92f));
if (newSelected == selected)
return;
var mask = 1 << (int)tier;
if (newSelected)
SetTierMask(m_TierMask | mask);
else
SetTierMask(m_TierMask & ~mask);
}
private void DrawActions()
{
EditorGUILayout.BeginHorizontal();
using (new EditorGUI.DisabledScope(!HasSelectedTier()))
{
if (GUILayout.Button("Preview", GUILayout.Height(28f)))
Preview();
}
using (new EditorGUI.DisabledScope(!HasSelectedTier() || m_Previews == null || m_Previews.Length == 0))
{
if (GUILayout.Button("Generate SVC", GUILayout.Height(28f)))
Generate();
}
EditorGUILayout.EndHorizontal();
if (!string.IsNullOrEmpty(m_Status))
EditorGUILayout.HelpBox(m_Status, MessageType.Info);
}
private void DrawPreview()
{
if (m_Previews == null || m_Previews.Length == 0)
return;
EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel);
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
{
DrawPreviewHeader();
for (var i = 0; i < m_Previews.Length; i++)
{
var preview = m_Previews[i];
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(preview.tier.ToString(), GUILayout.Width(90f));
EditorGUILayout.LabelField(preview.materialCount.ToString(), GUILayout.Width(90f));
EditorGUILayout.LabelField(preview.passCount.ToString(), GUILayout.Width(70f));
EditorGUILayout.LabelField(preview.variantCount.ToString(), GUILayout.Width(90f));
EditorGUILayout.LabelField(preview.outputAssetPath ?? string.Empty);
EditorGUILayout.EndHorizontal();
}
}
}
private static void DrawPreviewHeader()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUILayout.LabelField("Tier", EditorStyles.boldLabel, GUILayout.Width(90f));
EditorGUILayout.LabelField("Materials", EditorStyles.boldLabel, GUILayout.Width(90f));
EditorGUILayout.LabelField("Passes", EditorStyles.boldLabel, GUILayout.Width(70f));
EditorGUILayout.LabelField("Variants", EditorStyles.boldLabel, GUILayout.Width(90f));
EditorGUILayout.LabelField("Output", EditorStyles.boldLabel);
EditorGUILayout.EndHorizontal();
}
private void Preview()
{
var selectedTiers = GetSelectedTiers();
var result = NBShaderVariantCollectionBuilder.Preview(m_SearchFolders, m_OutputFolder, selectedTiers);
m_Previews = result.tiers;
m_Status = string.Format(
"Found {0} NBShader materials in {1} valid folder(s). Previewed {2} tier(s) and did not write assets.",
result.materialCount,
result.validSearchFolderCount,
selectedTiers.Length);
}
private void Generate()
{
var result = NBShaderVariantCollectionBuilder.Generate(m_SearchFolders, m_OutputFolder, GetSelectedTiers());
if (result.hasError)
{
EditorUtility.DisplayDialog("Generate NBShader SVC", result.firstErrorMessage, "OK");
m_Previews = result.tiers;
return;
}
m_Previews = result.tiers;
m_Status = string.Format("Generated {0} NBShader shader variant collection asset(s).", result.generatedCount);
}
private void AddSelectedFolders()
{
var guids = Selection.assetGUIDs;
for (var i = 0; i < guids.Length; i++)
{
var path = AssetDatabase.GUIDToAssetPath(guids[i]);
if (AssetDatabase.IsValidFolder(path))
AddSearchFolder(path);
}
}
private void AddSearchFolder(string folder)
{
folder = NBShaderVariantCollectionBuilder.NormalizeAssetPath(folder);
if (string.IsNullOrEmpty(folder))
return;
if (!m_SearchFolders.Contains(folder))
m_SearchFolders.Add(folder);
}
private static string PickProjectFolder(string current)
{
var start = AssetDatabase.IsValidFolder(current) ? current : "Assets";
var absoluteStart = NBShaderVariantCollectionBuilder.ToAbsolutePath(start);
var picked = EditorUtility.OpenFolderPanel("Select Project Folder", absoluteStart, string.Empty);
return NBShaderVariantCollectionBuilder.NormalizeAssetPath(picked);
}
private bool HasSelectedTier()
{
return (m_TierMask & AllTierMask) != 0;
}
private bool IsTierSelected(NBShaderFeatureTier tier)
{
return (m_TierMask & (1 << (int)tier)) != 0;
}
private NBShaderFeatureTier[] GetSelectedTiers()
{
var result = new List<NBShaderFeatureTier>();
for (var i = 0; i < Tiers.Length; i++)
{
var tier = Tiers[i];
if (IsTierSelected(tier))
result.Add(tier);
}
return result.ToArray();
}
private void SetTierMask(int tierMask)
{
tierMask &= AllTierMask;
if (m_TierMask == tierMask)
return;
m_TierMask = tierMask;
m_Previews = new NBShaderVariantCollectionTierResult[0];
m_Status = string.Empty;
}
}
}