- Unity 2018 Artificial Intelligence Cookbook(Second Edition)
- Jorge Palacios
- 322字
- 2021-07-16 18:11:36
How to do it...
We will create an editor window for easily handling the automation process without weighing down the graph's Start function, thereby delaying the scene loading:
- Create the CustomNavMeshWindow class and place it in a directory called Editor:
using UnityEngine; using UnityEditor; using System.Collections; using System.Collections.Generic; public class CustomNavMeshWindow : EditorWindow { // next steps here }
- Add the attributes to the editor window:
static bool isEnabled = false; static GameObject graphObj; static CustomNavMesh graph; static CustomNavMeshWindow window; static GameObject graphVertex;
- Implement the function for initializing and showing the window:
[MenuItem("UAIPC/Ch02/CustomNavMeshWindow")] static void Init() { window = EditorWindow.GetWindow<CustomNavMeshWindow>(); window.title = "CustomNavMeshWindow"; SceneView.onSceneGUIDelegate += OnScene; graphObj = GameObject.Find("CustomNavMesh"); if (graphObj == null) { graphObj = new GameObject("CustomNavMesh"); graphObj.AddComponent<CustomNavMesh>(); graph = graphObj.GetComponent<CustomNavMesh>(); } else { graph = graphObj.GetComponent<CustomNavMesh>(); if (graph == null) graphObj.AddComponent<CustomNavMesh>(); graph = graphObj.GetComponent<CustomNavMesh>(); } }
- Define the OnDestroy function:
void OnDestroy() { SceneView.onSceneGUIDelegate -= OnScene; }
- Implement the OnGUI function for drawing the window's interior:
void OnGUI() { isEnabled = EditorGUILayout.Toggle("Enable Mesh Picking", isEnabled); if (GUILayout.Button("Build Edges")) { if (graph != null) graph.LoadGraph(); } }
- Implement the first half of the OnScene function for handling the left-click on the scene window:
private static void OnScene(SceneView sceneView) { if (!isEnabled) return; if (Event.current.type == EventType.MouseDown) { graphVertex = graph.vertexPrefab; if (graphVertex == null) { Debug.LogError("No Vertex Prefab assigned"); return; } Event e = Event.current; Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition); RaycastHit hit; GameObject newV; // next step } }
- Implement the second half for implementing the behavior when clicking on the mesh:
if (Physics.Raycast(ray, out hit)) { GameObject obj = hit.collider.gameObject; Mesh mesh = obj.GetComponent<MeshFilter>().sharedMesh; Vector3 pos; int i; for (i = 0; i < mesh.triangles.Length; i += 3) { int i0 = mesh.triangles[i]; int i1 = mesh.triangles[i + 1]; int i2 = mesh.triangles[i + 2]; pos = mesh.vertices[i0]; pos += mesh.vertices[i1]; pos += mesh.vertices[i2]; pos /= 3; newV = (GameObject)Instantiate(graphVertex, pos, Quaternion.identity); newV.transform.Translate(obj.transform.position); newV.transform.parent = graphObj.transform; graphObj.transform.parent = obj.transform; } }