using AX.InputSystem; using AX.MessageSystem; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawRectSelectRange : MonoBehaviour { private Vector3 mousePosition = Vector3.zero;//记录刚进入框选状态时鼠标的位置 private bool drawRectStart;//框选画框是否开始 private Vector3 endPosition = Vector3.zero; private Material rectMat = null; public Color rectColor = Color.green; public Shader LinesColorShader; private Camera mainCamera = null; private float farPlane = 100; // Use this for initialization void Start() { rectMat = new Material(LinesColorShader);//生成画线材质 rectMat.hideFlags = HideFlags.HideAndDontSave; //rectMat.shader.hideFlags = HideFlags.HideAndDontSave; mainCamera = GetComponent(); farPlane = mainCamera.farClipPlane; } // Update is called once per frame void Update() { } void OnEnable() { MessageDispatcher.AddListener("RECTDRAW_ENTER_COMMAND", DrawRectSelectRangeEnter); MessageDispatcher.AddListener("RECTDRAWING_COMMAND", DrawRectSelectRanging); MessageDispatcher.AddListener("RECTDRAW_EXIT_COMMAND", DrawRectSelectRangeExit); } void OnDisable() { MessageDispatcher.RemoveListener("RECTDRAW_ENTER_COMMAND", DrawRectSelectRangeEnter); MessageDispatcher.RemoveListener("RECTDRAWING_COMMAND", DrawRectSelectRanging); MessageDispatcher.RemoveListener("RECTDRAW_EXIT_COMMAND", DrawRectSelectRangeExit); } void OnDestroy() { MessageDispatcher.RemoveListener("RECTDRAW_ENTER_COMMAND", DrawRectSelectRangeEnter); MessageDispatcher.RemoveListener("RECTDRAWING_COMMAND", DrawRectSelectRanging); MessageDispatcher.RemoveListener("RECTDRAW_EXIT_COMMAND", DrawRectSelectRangeExit); } private void DrawRectSelectRangeEnter(IMessage obj) { var data = (DrawRectSelectRangeCmdArgs)obj.Data; mousePosition = data.mousePosition; drawRectStart = data.drawRectStart; } private void DrawRectSelectRanging(IMessage obj) { var data = (DrawRectSelectRangeCmdArgs)obj.Data; endPosition = data.mousePosition; drawRectStart = data.drawRectStart; } private void DrawRectSelectRangeExit(IMessage obj) { var data = (DrawRectSelectRangeCmdArgs)obj.Data; mousePosition = data.mousePosition; drawRectStart = data.drawRectStart; } void OnPostRender() { if (drawRectStart) { DrawSelectionRectangle(mousePosition, endPosition); //没有选中克隆按钮时,画框同时判断是否框选选中并做选中处理;选中克隆按钮时只画框,不做框选选中处理 if (InputManager.cloneObjType == CloneObjType.None) { checkSelection(mousePosition, endPosition); } } } private void DrawSelectionRectangle(Vector3 start, Vector3 end) { GL.PushMatrix();//保存摄像机变换矩阵 if (!rectMat) return; rectMat.SetPass(0); GL.LoadPixelMatrix();//设置用屏幕坐标绘图 GL.Begin(GL.QUADS); GL.Color(new Color(rectColor.r, rectColor.g, rectColor.b, 0.1f)); GL.Vertex3(start.x, start.y, 0); GL.Vertex3(end.x, start.y, 0); GL.Vertex3(end.x, end.y, 0); GL.Vertex3(start.x, end.y, 0); GL.End(); GL.Begin(GL.LINES); GL.Color(rectColor);//设置方框的边框颜色 边框不透明 GL.Vertex3(start.x, start.y, 0); GL.Vertex3(end.x, start.y, 0); GL.Vertex3(end.x, start.y, 0); GL.Vertex3(end.x, end.y, 0); GL.Vertex3(end.x, end.y, 0); GL.Vertex3(start.x, end.y, 0); GL.Vertex3(start.x, end.y, 0); GL.Vertex3(start.x, start.y, 0); GL.End(); GL.PopMatrix();//恢复摄像机矩阵 } private void checkSelection(Vector3 start, Vector3 end) { Vector3 p1 = Vector3.zero; Vector3 p2 = Vector3.zero; //这些判断是用来确保p1的xy坐标小于p2的xy坐标,因为画的框不见得就是左下到右上或者左上到右下这个方向 if (start.x > end.x) { p1.x = end.x; p2.x = start.x; } else { p1.x = start.x; p2.x = end.x; } if (start.y > end.y) { p1.y = end.y; p2.y = start.y; } else { p1.y = start.y; p2.y = end.y; } if (SelectedObjs.characters.Count>0) { for (int i = 0; i < SelectedObjs.characters.Count; i++) { if (SelectedObjs.characters[i] == null) { SelectedObjs.characters.Remove(SelectedObjs.characters[i]); } } } foreach (GameObject obj in SelectedObjs.characters) { if (obj==null) { return; } Vector3 location = mainCamera.WorldToScreenPoint(obj.transform.position); if (location.x < p1.x || location.x > p2.x || location.y < p1.y || location.y > p2.y || location.z < 0 || location.z > farPlane) {//框选范围之外及摄像头视线范围外,不需要选择 MessageDispatcher.SendMessage(obj, "CANCEL_OBJ_SELECTED"); // AddRecordEventSelect(RecordEventType.CancelObjSelected, obj); } else {//否则就进行选中操作 MessageDispatcher.SendMessage(obj, "OBJ_RECT_SELECTED"); // AddRecordEventSelect(RecordEventType.ObjRectSelected, obj); } } } private void AddRecordEventSelect(RecordEventType type, GameObject obj) { if (ReplaySetting.PlayStatus == PlayStatus.isEditor && RecordManager.Instance.recordStatus == RecordStatus.normal) { var eventData = new EventData(); eventData.time = RecordManager.Instance.RecordTimer; eventData.cloneObjType = CloneObjType.None; eventData.eventType = type; eventData.json = obj.name; RecordManager.Instance.jsonData.eventDataList.Add(eventData); } } }