Net.Like.Xue.Tokyo/Assets/BITKit/Unity/Scripts/Scenes/Editor/MaterialPaletteWindow.cs

96 lines
2.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace BITKit
{
public class MaterialPaletteWindow : EditorWindow
{
[MenuItem("Tools/Scenes/Material Palette")]
public static void Open()
{
GetWindow<MaterialPaletteWindow>().Show();
}
private Button buildButton;
private Label _titleLabel;
private VisualElement _container;
private MeshRenderer[] _renderers=Array.Empty<MeshRenderer>();
private void OnEnable()
{
UnityEditor.Selection.selectionChanged += OnSelectionChanged;
rootVisualElement.Clear();
_titleLabel = rootVisualElement.Create<Label>();
_container = rootVisualElement.Create<VisualElement>();
_titleLabel.text = "选择一个物体";
}
private void OnDisable()
{
UnityEditor.Selection.selectionChanged -= OnSelectionChanged;
}
private void OnSelectionChanged()
{
var actives = UnityEditor.Selection.gameObjects;
_container.Clear();
_renderers = actives.SelectMany(x => x.GetComponentsInChildren<MeshRenderer>()).ToArray();
var materials = _renderers.SelectMany(x => x.sharedMaterials).Distinct().ToArray();
_titleLabel.text = actives is not {Length:0} ?$"选择了{actives.Length }个物体,{materials.Length}个材质" : "未选择物体";
foreach (var material in materials)
{
var filed = _container.Create<ObjectField>();
filed.label = material.name;
filed.objectType = typeof(Material);
filed.allowSceneObjects = false;
filed.value = material;
filed.RegisterValueChangedCallback(OnChanged);
}
}
private void OnChanged(ChangeEvent<Object> evt)
{
if(evt.newValue is not Material value) return;
var list = new List<Object>();
foreach (var renderer in _renderers)
{
var sharedMaterials = renderer.sharedMaterials;
var isDirty = false;
for (var i = 0; i < sharedMaterials.Length; i++)
{
var current = sharedMaterials[i];
if(current != evt.previousValue) continue;
sharedMaterials[i] = value;
isDirty = true;
}
if (!isDirty) continue;
renderer.sharedMaterials = sharedMaterials;
list.Add(renderer);
EditorUtility.SetDirty(renderer);
}
if (list.Count > 0)
{
OnSelectionChanged();
}
}
}
}