256 lines
9.2 KiB
C#
Raw Normal View History

2025-09-25 19:05:14 +08:00
using System.Linq;
2025-09-11 20:42:09 +08:00
using Unity.Mathematics;
using UnityEditor;
2025-09-28 19:40:35 +08:00
using UnityEditor.EditorTools;
2025-09-25 19:05:14 +08:00
using UnityEditor.IMGUI.Controls;
2025-09-11 20:42:09 +08:00
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UIElements;
namespace X.Rendering.Scene
{
[CustomEditor(typeof(SceneEffect))]
public class SceneEffectEditorBase : Editor
{
ReorderableList lightList;
Transform transform;
int selectIndex = -1;
2025-09-25 19:05:14 +08:00
Vector4 mainLightDir = Vector4.zero;
SerializedProperty boundsProperty;
private BoxBoundsHandle boundsHandle = new();
2025-09-28 19:40:35 +08:00
LightData[] lightDatas = null;
2025-09-11 20:42:09 +08:00
public override VisualElement CreateInspectorGUI()
{
transform = (target as MonoBehaviour).transform;
2025-09-25 19:05:14 +08:00
var mainLight = GameObject.FindGameObjectWithTag("MainLight")?.GetComponent<Light>();
2025-09-28 19:40:35 +08:00
if (mainLight == null)
2025-09-25 19:05:14 +08:00
{
mainLight = GameObject.FindObjectsOfType<Light>().Where(l => l.type == LightType.Directional).First();
}
2025-09-28 19:40:35 +08:00
if (mainLight != null)
2025-09-25 19:05:14 +08:00
{
mainLightDir = (mainLight.transform.rotation * Vector3.forward).normalized;
mainLightDir.w = 1;
}
2025-09-11 20:42:09 +08:00
lightList = new ReorderableList(serializedObject, serializedObject.FindProperty("capsuleLights"), true, true, true, true);
lightList.onSelectCallback += (_) =>
{
Debug.Log($"{lightList.index}");
selectIndex = lightList.index;
};
2025-09-28 19:40:35 +08:00
var t = serializedObject.targetObject.GetType().GetField("capsuleLights", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
lightDatas = t.GetValue(serializedObject.targetObject) as LightData[];
2025-09-25 19:05:14 +08:00
lightList.onAddCallback += (_) =>
{
if (lightList.index == -1 && lightList.count == 0)
{
lightList.index = 0;
}
lightList.serializedProperty.InsertArrayElementAtIndex(lightList.index);
2025-09-28 19:40:35 +08:00
serializedObject.ApplyModifiedProperties();
var light = new LightData()
{
isPointLight = true,
lightIntensity = 1,
lightPosition = transform.position + Vector3.up
};
if (lightDatas != null)
{
lightDatas[lightList.index] = light;
lightList.Select(lightList.index);
}
2025-09-25 19:05:14 +08:00
};
2025-09-11 20:42:09 +08:00
lightList.drawHeaderCallback = DrawHeader;
lightList.drawElementCallback = DrawListItems;
2025-09-25 19:05:14 +08:00
boundsProperty = serializedObject.FindProperty("Bounds");
2025-09-11 20:42:09 +08:00
return base.CreateInspectorGUI();
}
private void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
2025-09-28 19:40:35 +08:00
if(index < 0 )
{
return;
}
EditorGUI.BeginChangeCheck();
var light = lightDatas[index];
float x = rect.x;
//EditorGUI.LabelField(new Rect(x, rect.y, 50, EditorGUIUtility.singleLineHeight), "点光");
//x += 50;
EditorGUI.LabelField(new Rect(x, rect.y, 150, EditorGUIUtility.singleLineHeight), $"{light.lightPosition}");
x += 140;
light.lightIntensity = EditorGUI.Slider(new Rect(x, rect.y, 200, EditorGUIUtility.singleLineHeight), light.lightIntensity, 0.2f, 2);
x += 210;
light.isPointLight = EditorGUI.ToggleLeft(new Rect(x, rect.y, 50, EditorGUIUtility.singleLineHeight), "点光", light.isPointLight);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "DrawListItems");
CallValidate();
}
2025-09-11 20:42:09 +08:00
}
private void DrawHeader(Rect rect)
{
string name = "光照方向";
EditorGUI.LabelField(rect, name);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
2025-09-28 19:40:35 +08:00
base.OnInspectorGUI();
2025-09-11 20:42:09 +08:00
lightList.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
2025-09-28 19:40:35 +08:00
private void OnDestroy()
{
Tools.hidden = false;
}
2025-09-11 20:42:09 +08:00
public void OnSceneGUI()
{
2025-09-25 19:05:14 +08:00
DrawBoundHandle();
if (selectIndex == -1 || lightList == null || selectIndex >= lightList?.serializedProperty.arraySize)
2025-09-11 20:42:09 +08:00
{
return;
}
2025-09-28 19:40:35 +08:00
var light = lightDatas[selectIndex];
Tools.hidden = true;
2025-09-11 20:42:09 +08:00
2025-09-28 19:40:35 +08:00
if (!light.isPointLight)
{
var rot = (float3)light.lightPosition;
rot += DrawRotationHandle(light.lightPosition);
light.lightPosition = rot;
}
else
{
var pos = (float3)light.lightPosition;
pos += DrawPositionHandle(light.lightPosition);
light.lightPosition = pos;
}
serializedObject.ApplyModifiedProperties();
}
2025-09-25 19:05:14 +08:00
2025-09-28 19:40:35 +08:00
protected void CallValidate()
{
target.GetType().GetMethod("OnValidate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Invoke(target, null);
}
2025-09-11 20:42:09 +08:00
2025-09-28 19:40:35 +08:00
protected float3 DrawPositionHandle(Vector3 vec)
{
EditorGUI.BeginChangeCheck();
var newPos = Handles.PositionHandle(vec, Quaternion.identity);
float3 delta = float3.zero;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "DrawPositionHandle");
delta = newPos - vec;
CallValidate();
}
return delta;
2025-09-11 20:42:09 +08:00
}
2025-09-25 19:05:14 +08:00
protected float3 DrawRotationHandle(Vector3 vec)
2025-09-11 20:42:09 +08:00
{
EditorGUI.BeginChangeCheck();
2025-09-25 19:05:14 +08:00
var rotation = Quaternion.LookRotation(vec);
Vector3 newEuler = Vector3.zero;
Vector3 oldEuler = rotation.eulerAngles;
2025-09-28 19:40:35 +08:00
2025-09-25 19:05:14 +08:00
var col = Handles.color;
var pos = transform.position;
if (boundsProperty != null)
{
pos = boundsProperty.boundsValue.center;
}
2025-09-28 19:40:35 +08:00
2025-09-25 19:05:14 +08:00
Handles.color = Handles.xAxisColor;
newEuler.x = Handles.Disc(Quaternion.Euler(oldEuler.x, 0, 0), pos, Vector3.left, HandleUtility.GetHandleSize(pos) * 1.5f, false, 0.1f).eulerAngles.x;
Handles.color = Handles.yAxisColor;
newEuler.y = Handles.Disc(Quaternion.Euler(0, oldEuler.y, 0), pos, Vector3.up, HandleUtility.GetHandleSize(pos) * 1.5f, false, 0.1f).eulerAngles.y;
//var newRot = Handles.RotationHandle(rotation, pos);
2025-09-11 20:42:09 +08:00
EditorGUI.EndChangeCheck();
2025-09-25 19:05:14 +08:00
Handles.ConeHandleCap(0, pos, Quaternion.Euler(newEuler), HandleUtility.GetHandleSize(pos), EventType.Repaint);
2025-09-28 19:40:35 +08:00
2025-09-25 19:05:14 +08:00
Handles.color = col;
2025-09-11 20:42:09 +08:00
2025-09-28 19:40:35 +08:00
float3 delta = float3.zero;
2025-09-25 19:05:14 +08:00
var newVec = (Quaternion.Euler(newEuler) * Vector3.forward).normalized;
if (newVec != vec)
2025-09-11 20:42:09 +08:00
{
2025-09-25 19:05:14 +08:00
Undo.RecordObject(target, "DrawRotationHandle");
delta = newVec - vec;
2025-09-28 19:40:35 +08:00
CallValidate();
2025-09-11 20:42:09 +08:00
}
return delta;
}
2025-09-25 19:05:14 +08:00
protected void DrawBoundHandle()
2025-09-11 20:42:09 +08:00
{
2025-09-25 19:05:14 +08:00
if (boundsProperty == null)
2025-09-11 20:42:09 +08:00
{
2025-09-28 19:40:35 +08:00
return;
2025-09-11 20:42:09 +08:00
}
2025-09-25 19:05:14 +08:00
EditorGUI.BeginChangeCheck();
var bounds = boundsProperty.boundsValue;
var col = Handles.color;
Handles.color = Color.green;
var newPos = Handles.PositionHandle(bounds.center, transform.rotation);
boundsHandle.center = bounds.center;
boundsHandle.size = bounds.size;
2025-09-28 19:40:35 +08:00
boundsHandle.DrawHandle();
2025-09-25 19:05:14 +08:00
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "DrawBoundHandle");
bounds.center = newPos;
bounds.size = boundsHandle.size;
boundsProperty.boundsValue = bounds;
}
boundsProperty.serializedObject.ApplyModifiedProperties();
Handles.color = col;
2025-09-11 20:42:09 +08:00
}
}
[CustomEditor(typeof(CapsuleShadowAreaEffect))]
public class MyClaCapsuleShadowAreaEffectsEditor : SceneEffectEditorBase
{
}
2025-09-25 19:05:14 +08:00
//[CustomPropertyDrawer(typeof(CapsuleShadowAreaSetting))]
//public class CapsuleShadowAreaSettingDrawer : PropertyDrawer
//{
// public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
// {
// EditorGUI.BeginProperty(position, label, property);
// EditorGUI.PropertyField(new Rect(position.x, position.y, 30, position.height), property.FindPropertyRelative("AmbientIntensity"), GUIContent.none);
// EditorGUI.PropertyField(new Rect(position.x + 35, position.y, 50, position.height), property.FindPropertyRelative("ShadowIntensity"), GUIContent.none);
// EditorGUI.PropertyField(new Rect(position.x + 90, position.y, position.width - 90, position.height), property.FindPropertyRelative("ShadowSharpness"), GUIContent.none);
// EditorGUI.EndProperty();
// }
//}
2025-09-11 20:42:09 +08:00
}