_xiaofang/xiaofang/Assets/Obi/Editor/RopeAndRod/ObiRopeSectionEditor.cs
杨号敬 bcc74f0465 add
2024-12-18 02:18:45 +08:00

214 lines
5.7 KiB
C#

using UnityEditor;
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Obi{
/**
* Custom inspector for ObiParticleRenderer component.
*/
[CustomEditor(typeof(ObiRopeSection))]
public class ObiRopeSectionEditor : Editor
{
ObiRopeSection section;
bool[] selected = new bool[0];
Color previewBck = new Color(0.2f,0.2f,0.2f,1);
Color previewLines = new Color(0.15f,0.15f,0.15f,1);
public void OnEnable(){
section = (ObiRopeSection)target;
}
public override bool HasPreviewGUI(){
return true;
}
private void ResetSelection(){
selected = new bool[section.Segments];
}
public override void OnInspectorGUI() {
serializedObject.UpdateIfRequiredOrScript();
Editor.DrawPropertiesExcluding(serializedObject,"m_Script");
GUI.enabled = !EditorApplication.isPlaying;
GUILayout.Label("Presets");
GUILayout.BeginHorizontal();
if (GUILayout.Button("4-segment circle")){
Undo.RecordObject(section, "Set rope section preset");
section.CirclePreset(4);
ResetSelection();
}
if (GUILayout.Button("8-segment circle")){
Undo.RecordObject(section, "Set rope section preset");
section.CirclePreset(8);
ResetSelection();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button("12-segment circle")){
Undo.RecordObject(section, "Set rope section preset");
section.CirclePreset(12);
ResetSelection();
}
if (GUILayout.Button("16-segment circle")){
Undo.RecordObject(section, "Set rope section preset");
section.CirclePreset(16);
ResetSelection();
}
GUILayout.EndHorizontal();
GUILayout.Label("Tools");
if (GUILayout.Button("Add vertex")){
Undo.RecordObject(section, "Add rope vertex");
section.vertices.Add(Vector2.zero);
}
if (GUILayout.Button("Remove selected vertices")){
Undo.RecordObject(section, "Remove rope vertices");
for (int i = selected.Length-1; i > 0; --i){
if (selected[i] && section.vertices.Count > 3)
section.vertices.RemoveAt(i);
}
// special cases: first vertex:
if (selected[0] && section.vertices.Count > 3){
section.vertices.RemoveAt(0);
section.vertices[section.vertices.Count-1] = section.vertices[0];
}
ResetSelection();
}
GUI.enabled = true;
// Apply changes to the serializedProperty
if (GUI.changed){
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(target);
}
}
private void DrawSectionOutline(Rect region, Color color){
// Draw segment lines:
Handles.BeginGUI( );
Color oldColor = Handles.color;
Handles.color = color;
Vector3[] points = new Vector3[section.vertices.Count];
for (int i = 0; i < section.vertices.Count; i++){
points[i] = new Vector3(region.center.x + section.vertices[i].x * region.width * 0.5f,
region.center.y + section.vertices[i].y * region.height * 0.5f,0);
}
Handles.DrawAAPolyLine(points);
Handles.EndGUI();
Handles.color = oldColor;
}
private void DrawDrawingArea(Rect region){
// Draw drawing area grid:
Handles.BeginGUI();
Handles.DrawSolidRectangleWithOutline(region,previewBck,previewLines);
Color oldColor = Handles.color;
Handles.color = previewLines;
if (section.snapX > 5){
float x = region.center.x;
while (x < region.xMax){
Handles.DrawLine(new Vector3(x,region.yMin,0),new Vector3(x,region.yMax,0));
x += section.snapX;
}
x = region.center.x - section.snapX;
while (x > region.xMin){
Handles.DrawLine(new Vector3(x,region.yMin,0),new Vector3(x,region.yMax,0));
x -= section.snapX;
}
}
if (section.snapY > 5){
float y = region.center.y;
while (y < region.yMax){
Handles.DrawLine(new Vector3(region.xMin,y,0),new Vector3(region.xMax,y,0));
y += section.snapY;
}
y = region.center.y - section.snapY;
while (y > region.yMin){
Handles.DrawLine(new Vector3(region.xMin,y,0),new Vector3(region.xMax,y,0));
y -= section.snapY;
}
}
Handles.color = oldColor;
Handles.EndGUI();
}
public override void OnPreviewGUI(Rect region, GUIStyle background)
{
DrawSectionOutline(region, Color.red);
}
public override void OnInteractivePreviewGUI(Rect region, GUIStyle background)
{
Array.Resize(ref selected,section.Segments);
// Calculate drawing area rect:
Vector2 oldCenter = region.center;
if (region.width > region.height)
region.width = region.height;
if (region.height > region.width)
region.height = region.width;
region.width -= 10;
region.height -= 15;
region.center = oldCenter;
// Draw background and lines:
DrawDrawingArea(region);
// Draw the section outline:
DrawSectionOutline(region, Color.white);
// Draw all draggable vertices:
for (int i = 0; i < section.Segments; i++){
float x = region.center.x + section.vertices[i].x * region.width * 0.5f;
float y = region.center.y + section.vertices[i].y * region.height * 0.5f;
Vector2 pos = new Vector2(x,y);
bool oldSelection = selected[i];
Vector2 olsPos = pos;
selected[i] = ObiDraggableIcon.Draw(selected[i],i,ref pos,Color.red);
if (selected[i] != oldSelection)
this.Repaint();
if (pos != olsPos){
pos.x = Mathf.Clamp(ObiRopeSection.SnapTo(pos.x - region.center.x,section.snapX,5) / (region.width * 0.5f),-1,1);
pos.y = Mathf.Clamp(ObiRopeSection.SnapTo(pos.y - region.center.y,section.snapY,5) / (region.height * 0.5f),-1,1);
section.vertices[i] = pos;
if (i == 0)
section.vertices[section.Segments] = pos;
EditorUtility.SetDirty(target);
}
}
}
}
}