344 lines
11 KiB
C#
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();
|
|
}
|
|
}
|
|
} |