using UI; using UnityEditor; using UnityEngine; namespace Editor { // 告诉 Unity 这个编辑器是为 UIBezierCurveGenerator 组件服务的 [CustomEditor(typeof(UIBezierCurveGenerator))] public class UIBezierCurveGeneratorEditor : UnityEditor.Editor { // 这个方法用于定义组件在 Inspector 窗口中的显示 public override void OnInspectorGUI() { // 调用基类的 OnInspectorGUI 方法,绘制所有 public 或 [SerializeField] 字段 // 这意味着我们会看到 P0, P1, P2, P3 和 segmentCount 的默认 Inspector 控件 base.OnInspectorGUI(); // 获取目标组件的引用 UIBezierCurveGenerator generator = (UIBezierCurveGenerator)target; // 可以在这里添加自定义的 Inspector 按钮或信息 if (GUILayout.Button("Generate Curve Now")) { generator.GenerateCurvePoints(); } } // 这个方法用于在 Scene 视图中绘制 Gizmos 或处理交互 protected virtual void OnSceneGUI() { // 获取当前被选中的 UIBezierCurveGenerator 实例 UIBezierCurveGenerator generator = (UIBezierCurveGenerator)target; RectTransform rectTransform = generator.GetComponent(); // 如果没有 RectTransform 或 UILineRenderer,则无法操作,直接返回 if (rectTransform == null || generator.lineRenderer == null) // lineRenderer 现已为 public { return; } // 确保在 Scene 视图中显示时重新生成曲线 // 这有助于在编辑器中实时预览,即使 Inspector 没有变动。 // 但要注意,频繁调用 GenerateCurvePoints() 可能对性能有轻微影响, // 但对于贝塞尔曲线这种操作,通常是可以接受的。 generator.GenerateCurvePoints(); // 设置 Unity Editor Handles 的颜色,方便区分不同的点 Handles.color = Color.white; // 修正:使用 HandleUtility.GetHandleSize 方法,并根据 P0 的世界位置计算句柄大小 float handleSphereSize = HandleUtility.GetHandleSize(rectTransform.TransformPoint(generator.P0)) * 0.05f; // 调整一个合适的大小比例 // ========================================================= // P0 (起点) 的操作 // ========================================================= Handles.color = Color.green; // 绿色表示起点 Vector3 worldP0 = rectTransform.TransformPoint(generator.P0); // 将 P0 从局部坐标转换为世界坐标 EditorGUI.BeginChangeCheck(); // 开始检查是否有改变发生 // 绘制一个可拖动的 PositionHandle,返回用户拖动后的新世界坐标 worldP0 = Handles.PositionHandle(worldP0, Quaternion.identity); if (EditorGUI.EndChangeCheck()) // 如果 PositionHandle 被拖动,检测到改变 { Undo.RecordObject(generator, "Move Bezier Point P0"); // 记录操作,支持撤销 generator.P0 = rectTransform.InverseTransformPoint(worldP0); // 将新的世界坐标转换回局部坐标 generator.GenerateCurvePoints(); // 立即更新曲线 (调用组件的方法) EditorUtility.SetDirty(generator); // 标记组件已修改,确保保存到场景 } Handles.DrawSolidDisc(worldP0, Vector3.forward, handleSphereSize * 0.8f); // 绘制一个小圆盘作为点标记 // ========================================================= // P1 (第一个控制点) 的操作 // ========================================================= Handles.color = Color.blue; // 蓝色表示第一个控制点 Vector3 worldP1 = rectTransform.TransformPoint(generator.P1); EditorGUI.BeginChangeCheck(); worldP1 = Handles.PositionHandle(worldP1, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(generator, "Move Bezier Point P1"); generator.P1 = rectTransform.InverseTransformPoint(worldP1); generator.GenerateCurvePoints(); EditorUtility.SetDirty(generator); } Handles.DrawSolidDisc(worldP1, Vector3.forward, handleSphereSize * 0.6f); // ========================================================= // P2 (第二个控制点) 的操作 // ========================================================= Handles.color = Color.magenta; // 洋红色表示第二个控制点 Vector3 worldP2 = rectTransform.TransformPoint(generator.P2); EditorGUI.BeginChangeCheck(); worldP2 = Handles.PositionHandle(worldP2, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(generator, "Move Bezier Point P2"); generator.P2 = rectTransform.InverseTransformPoint(worldP2); generator.GenerateCurvePoints(); EditorUtility.SetDirty(generator); } Handles.DrawSolidDisc(worldP2, Vector3.forward, handleSphereSize * 0.6f); // ========================================================= // P3 (终点) 的操作 // ========================================================= Handles.color = Color.red; // 红色表示终点 Vector3 worldP3 = rectTransform.TransformPoint(generator.P3); EditorGUI.BeginChangeCheck(); worldP3 = Handles.PositionHandle(worldP3, Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(generator, "Move Bezier Point P3"); generator.P3 = rectTransform.InverseTransformPoint(worldP3); generator.GenerateCurvePoints(); EditorUtility.SetDirty(generator); } Handles.DrawSolidDisc(worldP3, Vector3.forward, handleSphereSize * 0.8f); // ========================================================= // 绘制辅助线 (控制杆),连接起点到第一个控制点,终点到第二个控制点 // ========================================================= Handles.color = Color.gray; // 灰色辅助线 Handles.DrawLine(worldP0, worldP1); // P0 -> P1 Handles.DrawLine(worldP2, worldP3); // P2 -> P3 // 刷新 Scene 视图,确保所有 Gizmos 和曲线更新立即显示 SceneView.RepaintAll(); } } }