using System.Collections; using System.Collections.Generic; using NPOI.SS.Formula.Functions; using PhxhSDK; using TGS; using UnityEditor; using UnityEditor.Graphs; using UnityEditor.SceneManagement; using UnityEngine; public partial class SceneBrush { protected readonly Color BRUSH_COLOR = new Color(0.1453659f, 0.7463484f, 0.9433962f, 0.3f); protected readonly Color ERASER_COLOR = new Color(1, 0, 0, 0.3f); private const float ERASER_MAX_RADIUS = 20; private const float ERASER_MIN_RADIUS = 1; private RaycastHit[] _hits = new RaycastHit[1]; protected bool _isHitGround; protected Vector3 _mouseHitPosition; protected Event _currEvent; protected GameObject _ground; private bool _isDragging; private int _undoGroupID; public virtual void OnInspectorGUI() { GUI.enabled = false; EditorGUILayout.EnumPopup("笔刷类型", brushType); GUI.enabled = true; if (Valid) GUI.enabled = false; EditorGUI.BeginChangeCheck(); var tempPrefab = EditorGUILayout.ObjectField("笔刷预制:", prefab, typeof(GameObject), false) as GameObject; if (EditorGUI.EndChangeCheck()) { OnPrefabChanged(tempPrefab); EditorUtility.SetDirty(this); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); return; } GUI.enabled = true; if (Valid) { Undo.RecordObject(this, BRUSH_UNDO_NAME); Undo.RecordObject(prefab, BRUSH_UNDO_NAME); renderInfo.RecordUndo(BRUSH_UNDO_NAME); remarkName = EditorGUILayout.TextField("备注", remarkName); isEraser = EditorGUILayout.Toggle("擦子", isEraser); if (isEraser) { radius = EditorGUILayout.Slider("笔刷半径", radius, ERASER_MIN_RADIUS, ERASER_MAX_RADIUS); eraseSameType = EditorGUILayout.Toggle("擦除同类", eraseSameType); } else { radius = 1; if (_tgs != null) useTGS = EditorGUILayout.Toggle("对其网格", useTGS); scale = EditorGUILayout.FloatField("对象缩放", scale); yAngle = EditorGUILayout.FloatField("y轴旋转", yAngle); //objCount = EditorGUILayout.IntField("对象数目", objCount); //layout = (ESceneObjectLayout)EditorGUILayout.EnumPopup("分布类型", layout); canOverlap = EditorGUILayout.Toggle("允许重叠", canOverlap); } EditorUtility.SetDirty(this); EditorUtility.SetDirty(renderInfo); } } public virtual void OnSceneGUI(Event e) { ResetSceneGUIState(e); DrawMouse(); HandleInput(); } protected void ResetSceneGUIState(Event e) { _isHitGround = false; _mouseHitPosition = Vector3.zero; _currEvent = e; _ground = null; } protected void DrawMouse() { var mousePosSS = _currEvent.mousePosition; var ray = HandleUtility.GUIPointToWorldRay(mousePosSS); var count = Physics.RaycastNonAlloc(ray, _hits, 1000, 1 << LayerMask.NameToLayer("Ground")); if (count > 0) { var hit = _hits[0]; _mouseHitPosition = hit.point; Handles.color = isEraser ? ERASER_COLOR : BRUSH_COLOR; Handles.DrawSolidDisc(_mouseHitPosition, Vector3.up, radius); _isHitGround = true; _ground = hit.collider.gameObject; } } protected void HandleInput() { if (!_isHitGround) return; var controlID = GUIUtility.GetControlID(FocusType.Passive); var eventType = _currEvent.GetTypeForControl(controlID); switch (eventType) { case EventType.MouseDown: if (_currEvent.button == 0) { Undo.IncrementCurrentGroup(); _undoGroupID = Undo.GetCurrentGroup(); OnMouseDownInScene(_mouseHitPosition); GUIUtility.hotControl = controlID; _isDragging = true; } break; case EventType.MouseDrag: if (GUIUtility.hotControl == controlID && _isDragging) { OnMouseDragInScene(_mouseHitPosition, Vector3.Distance(_mouseHitPosition, _lastDrawPosition)); } break; case EventType.MouseUp: if (GUIUtility.hotControl == controlID && _currEvent.button == 0) { OnMouseUpInScene(_mouseHitPosition); _isDragging = false; GUIUtility.hotControl = 0; _currEvent.Use(); Undo.CollapseUndoOperations(_undoGroupID); } break; case EventType.ScrollWheel: if (_currEvent.control) { Undo.RecordObject(this, BRUSH_UNDO_NAME); radius += _currEvent.delta.y; radius = Mathf.Clamp(radius, ERASER_MIN_RADIUS, ERASER_MAX_RADIUS); _currEvent.Use(); } break; } } }