public override void OnInspectorGUI() { //show default variables of manager DrawDefaultInspector(); //get manager reference script = (WaypointManager)target; //get sceneview to auto-detect 2D mode SceneView view = SceneView.currentDrawingSceneView; if (view == null) { view = EditorWindow.GetWindow <SceneView>("Scene", false); } mode2D = view.in2DMode; EditorGUIUtility.LookLikeControls(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); //draw path text label GUILayout.Label("Enter Path Name: ", GUILayout.Height(15)); //display text field for creating a path with that name pathName = EditorGUILayout.TextField(pathName, GUILayout.Height(15)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); //draw path type selection enum GUILayout.Label("Select Path Type: ", GUILayout.Height(15)); pathType = (PathType)EditorGUILayout.EnumPopup(pathType); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); //display label of current mode if (mode2D) { GUILayout.Label("2D Mode Detected.", GUILayout.Height(15)); } else { GUILayout.Label("3D Mode Detected.", GUILayout.Height(15)); } EditorGUILayout.Space(); //draw path creation button if (!placing && GUILayout.Button("Start Path", GUILayout.Height(40))) { if (pathName == "") { Debug.LogWarning("No path name defined. Cancelling."); return; } if (script.transform.Find(pathName) != null) { Debug.LogWarning("Path name already given. Cancelling."); return; } //create a new container transform which will hold all new waypoints path = new GameObject(pathName); //reset position and parent container gameobject to this manager gameobject path.transform.position = script.gameObject.transform.position; path.transform.parent = script.gameObject.transform; StartPath(); //we passed all prior checks, toggle waypoint placement placing = true; //focus sceneview for placement if (view != null) { view.Focus(); } // SceneView.currentDrawingSceneView.Focus(); } if (!placing && GUILayout.Button("Export Path", GUILayout.Height(40))) { string filepath = EditorUtility.SaveFilePanelInProject("Save Path", "PathInfo", "csv", "OKOK"); LogManager.Log(filepath); string fileName = filepath; //文件名字 StringBuilder sb = new StringBuilder(); //offset sb.Append("patrolId").Append(','); sb.Append("patrolPlan").Append(','); sb.Append("patrolX").Append(','); sb.Append("patrolY").Append("\r\n"); int totalCount = 0; PathManager[] pathes = script.GetComponentsInChildren <PathManager>(); for (int i = 0; i < pathes.Length; ++i) { sb.Append('#').Append(pathes[i].name).Append(',').Append(pathes[i].transform.position.y).Append("\r\n"); Vector3[] points = pathes[i].GetPathPoints(); for (int j = 0; j < points.Length; ++j) { totalCount++; sb.Append(totalCount).Append(','); sb.Append(i).Append(','); sb.Append(points[j].x).Append(','); sb.Append(points[j].z).Append("\r\n"); } } //要写的数据源 SaveTextFile(filepath, sb.ToString()); } if (!placing && GUILayout.Button("Import", GUILayout.Height(40))) { string filepath = EditorUtility.OpenFilePanel("Load pathes", Application.dataPath, "csv"); if (filepath != null) { StreamReader reader = new StreamReader(filepath, new UTF8Encoding(false)); if (reader != null) { string content = reader.ReadToEnd(); int readPos = 0; //skip the first line string skipLine = EditorUtils.readLine(content, ref readPos); List <string> kv = null; PathManager manager = null; int pointCount = 0; float currentY = 0f; while (readPos < content.Length) { string lineNew = EditorUtils.readLine(content, ref readPos); //new path if (lineNew[0] == '#') { int noUse = 0; kv = GameAssist.readCsvLine(lineNew, ref noUse); string readpathName = kv[0].Substring(1); float.TryParse(kv[1], out currentY); path = new GameObject(readpathName); //reset position and parent container gameobject to this manager gameobject path.transform.position = script.gameObject.transform.position; path.transform.parent = script.gameObject.transform; StartPath(); wpList.Clear(); } else { int a = 0; kv = GameAssist.readCsvLine(lineNew, ref a); float x = 0f; float.TryParse(kv[2], out x); float z = 0f; float.TryParse(kv[3], out z); PlaceWaypoint(new Vector3(x, currentY, z)); } } } } } if (!placing && GUILayout.Button("CreateColliders", GUILayout.Height(40))) { UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath("Assets/PathEditor/Cube.prefab", typeof(UnityEngine.Object)); GameObject parent = GameObject.Find("WalkColliders"); Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/CameraPath3/Icons/options.png", typeof(Texture2D)); if (parent == null) { parent = new GameObject("WalkColliders"); } PathManager[] pathes = script.GetComponentsInChildren <PathManager>(); for (int i = 0; i < pathes.Length; ++i) { Vector3[] points = pathes[i].GetPathPoints(); int pointC = points.Length; int loopcount = pointC; //不是关闭类型的,不生成最后一个点到初始点的连线 if (pathes[i].closure == false) { loopcount = pointC - 1; } for (int j = 0; j < loopcount; ++j) { Vector3 nextPos = points[(j + 1) % pointC]; Vector3 middlePos = (points[j] + nextPos) * 0.5f; GameObject collider = GameObject.Instantiate(prefab, middlePos, Quaternion.identity) as GameObject; Vector3 lookPos = nextPos; lookPos.y = middlePos.y; collider.transform.LookAt(lookPos); collider.transform.parent = parent.transform; Vector3 setScale = collider.transform.localScale; setScale.z = (nextPos - points[j]).magnitude; collider.transform.localScale = setScale; } } } GUI.backgroundColor = Color.yellow; //finish path button if (placing && GUILayout.Button("Finish Editing", GUILayout.Height(40))) { if (wpList.Count < 2) { Debug.LogWarning("Not enough waypoints placed. Cancelling."); //if we have created a path already, destroy it again if (path) { DestroyImmediate(path); } } //toggle placement off placing = false; //clear list with temporary waypoint references, //we only needed this for getting the waypoint count wpList.Clear(); //reset path name input field pathName = ""; //make the new path the active selection Selection.activeGameObject = path; } GUI.backgroundColor = Color.white; EditorGUILayout.Space(); //draw instructions GUILayout.TextArea("Hint:\nPress 'Start Path' to begin a new path, then press 'p' " + "on your keyboard to place waypoints in the SceneView. In 3D Mode " + "you have to place waypoints onto objects with colliders." + "\n\nPress 'Finish Editing' to end your path."); }
public override void OnInspectorGUI() { editPlane = target as GridPlane; //show default variables of manager DrawDefaultInspector(); //get manager reference EditorGUIUtility.LookLikeControls(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("One Point", GUILayout.Height(40))) { editPlane.SetBrushType(0); SceneView.currentDrawingSceneView.Focus(); } if (GUILayout.Button("three Point", GUILayout.Height(40))) { editPlane.SetBrushType(1); SceneView.currentDrawingSceneView.Focus(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button("Generate", GUILayout.Height(40))) { editPlane.GenerateMesh(); } //draw path creation button GUI.backgroundColor = Color.yellow; if (!placing && GUILayout.Button("Brush", GUILayout.Height(40))) { //we passed all prior checks, toggle waypoint placement placing = true; //focus sceneview for placement SceneView.currentDrawingSceneView.Focus(); } if (placing && GUILayout.Button("Erase", GUILayout.Height(40))) { //we passed all prior checks, toggle waypoint placement placing = false; //focus sceneview for placement SceneView.currentDrawingSceneView.Focus(); } GUI.backgroundColor = Color.white; if (GUILayout.Button("ExportCollision", GUILayout.Height(40))) { string filepath = EditorUtility.SaveFilePanelInProject("Save Map", "CollisionInfo", "bytes", "OKOK"); LogManager.Log(filepath); FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fs); // string fileName = filepath;//文件名字 Vector3 offset = editPlane.transform.position; //write offset x FP offsetX = (FP)(offset.x); bw.Write(offsetX.RawValue); //write offset z FP offsetZ = (FP)offset.z; bw.Write(offsetZ.RawValue); //write width bw.Write(editPlane.width); //write height bw.Write(editPlane.height); //write size bw.Write(editPlane.gridsize); int [] gridInfo = editPlane.GetGridInfo(); int len = gridInfo.Length; BitArray bitarray = new BitArray(len); int byteCount = (len + 7) / 8; byte[] data = new byte[byteCount]; for (int i = 0; i < editPlane.height; ++i) { for (int j = 0; j < editPlane.width; ++j) { int index = i * editPlane.width + j; if (gridInfo[i * editPlane.width + j] == 0) { bitarray.Set(index, false); } else { bitarray.Set(index, true); } } } //要写的数据源 bitarray.CopyTo(data, 0); for (int i = 0; i < data.Length; ++i) { bw.Write(data[i]); } bw.Flush(); bw.Close(); fs.Close(); } if (GUILayout.Button("Export", GUILayout.Height(40))) { string filepath = EditorUtility.SaveFilePanelInProject("Save Map", "GridInfo", "txt", "OKOK"); LogManager.Log(filepath); string fileName = filepath; //文件名字 StringBuilder sb = new StringBuilder(); //offset sb.Append("type octile").Append("\r\n"); Vector3 offset = editPlane.transform.position; FP x = (FP)offset.x; sb.Append("X ").Append(x.RawValue).Append("\r\n"); FP z = (FP)offset.z; sb.Append("Z ").Append(z.RawValue).Append("\r\n"); sb.Append("width ").Append(editPlane.width).Append("\r\n"); sb.Append("height ").Append(editPlane.height).Append("\r\n"); FP size = (FP)editPlane.gridsize; sb.Append("size ").Append(size.RawValue).Append("\r\n"); sb.Append("map").Append("\r\n"); int [] gridInfo = editPlane.GetGridInfo(); // int len = gridInfo.Length; for (int i = 0; i < editPlane.height; ++i) { for (int j = 0; j < editPlane.width; ++j) { if (gridInfo[i * editPlane.width + j] == 0) { sb.Append('@'); } else { sb.Append('.'); } } sb.Append("\r\n"); } //要写的数据源 EditorUtils.SaveTextFile(filepath, sb.ToString()); } if (GUILayout.Button("Import", GUILayout.Height(40))) { string filepath = EditorUtility.OpenFilePanel("Load map", Application.dataPath, "txt"); if (filepath != null) { StreamReader reader = new StreamReader(filepath, new UTF8Encoding(false)); if (reader != null) { MapGridT myGrid = new MapGridT(); string content = reader.ReadToEnd(); int readPos = 0; List <string> kv = null; while (readPos < content.Length) { string line = EditorUtils.readLine(content, ref readPos); kv = EditorUtils.splitLine(line); if (kv.Count == 0) { continue; } if (kv[0] == "map") { break; } if (kv[0] == "X") { if (kv.Count > 1) { myGrid.X = float.Parse(kv[1]); } } if (kv[0] == "Z") { if (kv.Count > 1) { myGrid.Z = float.Parse(kv[1]); } } if (kv[0] == "width") { if (kv.Count > 1) { myGrid.Width = int.Parse(kv[1]); } } if (kv[0] == "height") { if (kv.Count > 1) { myGrid.Height = int.Parse(kv[1]); } } if (kv[0] == "size") { if (kv.Count > 1) { myGrid.GridSize = float.Parse(kv[1]); } } } if (myGrid.Width == 0 || myGrid.Height == 0) { StringBuilder log = new StringBuilder(); log.Append("invlid width").Append(myGrid.Width).Append("or height").Append(myGrid.Height); LogManager.Log(log.ToString()); return; } editPlane.transform.position = new Vector3((float)myGrid.X, 0f, (float)myGrid.Z); editPlane.width = myGrid.Width; editPlane.height = myGrid.Height; editPlane.gridsize = (float)myGrid.GridSize; editPlane.GenerateMesh(); int[] gridData = editPlane.GetGridInfo(); for (int i = 0; i < myGrid.Height; i++) { string line = EditorUtils.readLine(content, ref readPos); if (line.Length < myGrid.Width + 1) { StringBuilder log = new StringBuilder(); log.Append("line").Append(i).Append("length is less than").Append(myGrid.Width); LogManager.Log(log.ToString()); return; } for (int w = 0; w < myGrid.Width; w++) { if (line[w] == '.') { gridData[i * myGrid.Width + w] = 1; } else { gridData[i * myGrid.Width + w] = 0; } } } } } } if (GUILayout.Button("ImportCollision", GUILayout.Height(40))) { string filepath = EditorUtility.OpenFilePanel("Load collision", Application.dataPath, "bytes"); if (filepath != null) { FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read); if (fs != null) { BinaryReader br = new BinaryReader(fs); MapGridT myGrid = new MapGridT(); //read offset x myGrid.X = br.ReadSingle(); //read offset z myGrid.Z = br.ReadSingle(); //read width myGrid.Width = br.ReadInt32(); //read height myGrid.Height = br.ReadInt32(); //read size myGrid.GridSize = br.ReadSingle(); if (myGrid.Width == 0 || myGrid.Height == 0) { StringBuilder log = new StringBuilder(); log.Append("invlid width").Append(myGrid.Width).Append("or height").Append(myGrid.Height); LogManager.Log(log.ToString()); return; } editPlane.transform.position = new Vector3((float)myGrid.X, 0f, (float)myGrid.Z); editPlane.width = myGrid.Width; editPlane.height = myGrid.Height; editPlane.gridsize = (float)myGrid.GridSize; editPlane.GenerateMesh(); int [] gridInfo = editPlane.GetGridInfo(); int len = gridInfo.Length; int byteCount = (len + 7) / 8; byte[] data = br.ReadBytes(byteCount); BitArray bitarray = new BitArray(data); for (int i = 0; i < myGrid.Height; i++) { for (int w = 0; w < myGrid.Width; w++) { gridInfo[i * myGrid.Width + w] = bitarray.Get(i * myGrid.Width + w) == true ? 1:0; } } } } } if (GUILayout.Button("CreateFromPath", GUILayout.Height(40))) { int walkNum = 0, nonWalkNum = 0; Polygon[] walkables = new Polygon[16]; for (int a = 0; a < walkables.Length; ++a) { walkables[a] = new Polygon(); } Polygon[] nonWalkables = new Polygon[32]; for (int b = 0; b < nonWalkables.Length; ++b) { nonWalkables[b] = new Polygon(); } //get all pathes WaypointManager manager = GameObject.FindObjectOfType <WaypointManager>(); if (manager) { Vector3 offset = editPlane.transform.position; PathManager[] pathes = manager.GetComponentsInChildren <PathManager>(); foreach (PathManager path in pathes) { if (path.walkable) { for (int i = 0; i < path.waypoints.Length; ++i) { Vector3 pos = path.waypoints[i].position; walkables[walkNum].m_Points.Add(new Vector2(pos.x - offset.x, pos.z - offset.z)); } Vector3 firstPos = path.waypoints[0].position; walkables[walkNum].m_Points.Add(new Vector2(firstPos.x - offset.x, firstPos.z - offset.z)); walkNum++; } else { for (int i = 0; i < path.waypoints.Length; ++i) { Vector3 pos = path.waypoints[i].position; nonWalkables[nonWalkNum].m_Points.Add(new Vector2(pos.x - offset.x, pos.z - offset.z)); } Vector3 firstPos = path.waypoints[0].position; nonWalkables[nonWalkNum].m_Points.Add(new Vector2(firstPos.x - offset.x, firstPos.z - offset.z)); nonWalkNum++; } } } int[] gridData = editPlane.GetGridInfo(); for (int i = 0; i < editPlane.height; i++) { for (int w = 0; w < editPlane.width; w++) { bool processed = false; Vector2 pos = new Vector2(w * editPlane.gridsize + editPlane.gridsize * 0.5f, i * editPlane.gridsize + editPlane.gridsize * 0.5f); for (int nonWalkIndex = 0; nonWalkIndex < nonWalkNum; ++nonWalkIndex) { if (PtInPolygon(pos, nonWalkables[nonWalkIndex].m_Points)) { processed = true; gridData[i * editPlane.width + w] = 0; } } if (!processed) { for (int walkIndex = 0; walkIndex < walkNum; ++walkIndex) { if (PtInPolygon(pos, walkables[walkIndex].m_Points)) { processed = true; gridData[i * editPlane.width + w] = 1; } } } } } } EditorGUILayout.Space(); //draw instructions GUILayout.TextArea("Hint:\nPress 'Brush' to begin a new path, then press 'p' " + "on your keyboard to place green points in the SceneView " + "\n\nPress 'Erase' to do the opposite operation."); }