NLDClient-yudde/ProjectNLD/Assets/Editor/Scene/NLDSceneManagerInspector.cs

344 lines
11 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Sirenix.OdinInspector.Editor;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(NLDSceneManager))]
public class NLDSceneManagerInspector : Editor
{
private const string SCENE_BRUSH_PATH = "Assets/Art/Scene/SceneBrush/Brush/Editor";
private const string SCENE_RENDER_INFO_PATH = "Assets/Art/Scene/SceneBrush/SceneRenderInfo";
private List<SceneBrush> _showBrushes = new();
private bool _isSelectingBrush;
private bool _isCreatingBrush;
private SceneBrush _currBrush;
private string _brushName;
private EBrushType _brushType;
private string _searchStr;
private bool _isDirty;
private Vector2 _scrollPosition;
private NLDSceneManager _sceneManager;
private PreviewRenderUtility _previewRenderUtility;
private GameObject Prefab => _currBrush != null ? _currBrush.prefab : null;
private void ValidateData()
{
if (_previewRenderUtility == null)
{
_previewRenderUtility = new PreviewRenderUtility();
//We set the previews camera to 6 units back, look towards the middle of the 'scene'
_previewRenderUtility.camera.transform.rotation = Quaternion.identity;
}
}
public override bool HasPreviewGUI()
{
ValidateData();
return true;
}
private void OnEnable()
{
RefreshData();
}
protected void OnDisable()
{
if (_previewRenderUtility != null)
{
_previewRenderUtility.Cleanup();
}
}
private void RefreshData()
{
RefreshAllBrush();
RefreshBrushToShow();
}
private void RefreshAllBrush()
{
SceneBrushHelper.RefreshAllBrush();
}
private void RefreshBrushToShow()
{
_showBrushes.Clear();
foreach (var brush in SceneBrushHelper.AllBrushes)
{
if (string.IsNullOrEmpty(_searchStr) || brush.name.ToLower().Contains(_searchStr.ToLower()))
{
_showBrushes.Add(brush);
}
}
}
private bool CheckCreateBrush()
{
if (string.IsNullOrEmpty(_brushName))
{
Debug.LogError("笔刷名为空!");
return false;
}
if (_brushType == EBrushType.None)
{
Debug.LogError("笔刷类型为空!");
return false;
}
foreach (var brush in SceneBrushHelper.AllBrushes)
{
var path = AssetDatabase.GetAssetPath(brush);
if (Path.GetFileNameWithoutExtension(path) == _brushName)
{
Debug.LogError("当前笔刷名字已存在,请重新命名!");
return false;
}
}
return true;
}
private bool CheckPreview()
{
return Prefab != null;
}
public override void OnPreviewGUI(Rect r, GUIStyle background)
{
if (Event.current.type == EventType.Repaint && CheckPreview())
{
_previewRenderUtility.BeginPreview(r, background);
_previewRenderUtility.camera.farClipPlane = 100;
var meshRenderer = Prefab.GetComponent<MeshRenderer>();
var meshFilter = Prefab.GetComponent<MeshFilter>();
if (meshRenderer == null || meshFilter == null || meshRenderer.sharedMaterials.Length == 0 ||
meshFilter.sharedMesh == null)
return;
var mesh = meshFilter.sharedMesh;
var bounds = meshRenderer.bounds;
var y = bounds.center.y;
var height = bounds.size.y + 1;
var fov = _previewRenderUtility.camera.fieldOfView;
var z = -(height / 2) / Mathf.Tan(Mathf.Deg2Rad * (fov / 2));
var cameraPos = new Vector3(0, y, z);
_previewRenderUtility.camera.transform.position = cameraPos;
var materials = meshRenderer.sharedMaterials;
for (int i = 0; i < mesh.subMeshCount; i++)
{
if (i < materials.Length)
_previewRenderUtility.DrawMesh(mesh, Matrix4x4.identity, materials[i], i);
}
_previewRenderUtility.camera.Render();
var result_render = _previewRenderUtility.EndPreview();
GUI.DrawTexture(r, result_render, ScaleMode.StretchToFill, false);
}
}
public override void OnInspectorGUI()
{
//base.OnInspectorGUI();
_isDirty = false;
DrawBrushSelecting();
DrawCreateBrush();
DrawBrush();
if (_isDirty)
AssetDatabase.SaveAssets();
}
private void DrawBrushSelecting()
{
if (_isSelectingBrush)
{
RefreshBrushToShow();
EditorGUI.BeginChangeCheck();
_searchStr = EditorGUILayout.TextField("搜索笔刷", _searchStr);
if (EditorGUI.EndChangeCheck())
{
//RefreshBrushToShow();
}
var scrollViewHeight = Mathf.Min(200, 30 * (_showBrushes.Count + 1) + 10);
_scrollPosition =
GUILayout.BeginScrollView(_scrollPosition, GUI.skin.box, GUILayout.Height(scrollViewHeight));
EditorGUILayout.BeginHorizontal(GUI.skin.label, GUILayout.Height(20));
EditorGUILayout.LabelField("笔刷名", GUILayout.Width(150));
EditorGUILayout.LabelField("笔刷类型", GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
foreach (var brush in _showBrushes)
{
if (brush == _currBrush)
GUI.color = Color.cyan;
EditorGUILayout.BeginHorizontal(GUI.skin.box, GUILayout.Height(20));
EditorGUILayout.LabelField(brush.name, GUILayout.Width(150));
EditorGUILayout.LabelField(brush.brushType.ToString(), GUILayout.Width(150));
if (GUILayout.Button("选择"))
{
_currBrush = brush;
}
GUI.color = Color.white;
EditorGUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
}
if (SceneBrushHelper.AllBrushes.Count > 0)
{
if (!_isSelectingBrush && GUILayout.Button("选择笔刷"))
{
_isSelectingBrush = true;
}
if (_isSelectingBrush && GUILayout.Button("选择完毕"))
{
_scrollPosition = Vector2.zero;
_isSelectingBrush = false;
}
}
else
{
_isSelectingBrush = false;
}
}
private void DrawCreateBrush()
{
if (!_isCreatingBrush)
{
if (GUILayout.Button("创建笔刷"))
{
_isCreatingBrush = true;
Repaint();
}
}
else
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical();
_brushName = EditorGUILayout.TextField("新建笔刷名", _brushName);
_brushType = (EBrushType)EditorGUILayout.EnumPopup("新建笔刷类型", _brushType);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
if (GUILayout.Button("创建"))
{
if (!CheckCreateBrush())
{
return;
}
var renderInfoName = $"{_brushName}_renderInfo";
var renderInfoPath = $"{SCENE_RENDER_INFO_PATH}/{renderInfoName}.asset";
EditorUtil.CreateAnUniqueAsset(CreateInstance<SceneObjectRenderInfo>(), renderInfoPath);
AssetDatabase.Refresh();
var renderInfo = AssetDatabase.LoadAssetAtPath<SceneObjectRenderInfo>(renderInfoPath);
renderInfo.name = renderInfoName;
var brushName = _brushName;
var brushPath = $"{SCENE_BRUSH_PATH}/{brushName}.asset";
switch (_brushType)
{
case EBrushType.Tree:
EditorUtil.CreateAnUniqueAsset(CreateInstance<SceneBrushTree>(), brushPath);
break;
case EBrushType.Building:
EditorUtil.CreateAnUniqueAsset(CreateInstance<SceneBrushBuilding>(), brushPath);
break;
default: break;
}
AssetDatabase.Refresh();
var brush = AssetDatabase.LoadAssetAtPath<SceneBrush>(brushPath);
brush.renderInfo = renderInfo;
brush.name = brushName;
EditorUtility.SetDirty(renderInfo);
EditorUtility.SetDirty(brush);
_isDirty = true;
_currBrush = brush;
_isCreatingBrush = false;
RefreshData();
}
if (GUILayout.Button("取消创建"))
{
_isCreatingBrush = false;
}
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
}
private void DrawBrush()
{
if (_currBrush != null)
{
GUI.enabled = false;
EditorGUILayout.ObjectField("当前笔刷:", _currBrush, typeof(SceneBrush), false);
EditorGUILayout.ObjectField("当前渲染信息:", _currBrush.renderInfo, typeof(SceneObjectRenderInfo), false);
GUI.enabled = true;
if (_currBrush.prefab != null)
GUI.enabled = false;
EditorGUI.BeginChangeCheck();
var prefab =
EditorGUILayout.ObjectField("笔刷预制:", _currBrush.prefab, typeof(GameObject), false) as GameObject;
if (EditorGUI.EndChangeCheck())
{
_currBrush.OnPrefabChanged(prefab);
}
GUI.enabled = true;
DrawBrushSettings();
if (GUILayout.Button("删除笔刷"))
{
_currBrush.OnDelete();
var path = AssetDatabase.GetAssetPath(_currBrush);
//DestroyImmediate(_currBrush,true);
AssetDatabase.DeleteAsset(path);
_currBrush = null;
RefreshData();
}
}
}
private void DrawBrushSettings()
{
if (_currBrush.Valid)
{
GUI.enabled = false;
EditorGUILayout.EnumPopup("笔刷类型", _currBrush.brushType);
GUI.enabled = true;
_currBrush.useTGS = EditorGUILayout.Toggle("对其网格", _currBrush.useTGS);
_currBrush.radius = EditorGUILayout.FloatField("笔刷半径", _currBrush.radius);
_currBrush.isEraser = EditorGUILayout.Toggle("擦子", _currBrush.isEraser);
_currBrush.OnInspectorGUI();
}
}
}