Unity 2018 Artificial Intelligence Cookbook(Second Edition)
上QQ阅读APP看书,第一时间看更新

How to do it...

We'll be creating the graph representation class as well as a custom Vertex class:

  1. Create the VertexVisibility class deriving from Vertex:
using UnityEngine; 
using System.Collections.Generic; 
 
public class VertexVisibility : Vertex 
{ 
    void Awake() 
    { 
        neighbours = new List<Edge>(); 
    } 
} 
  1. Define the FindNeighbours function for automating the process of connecting vertices among them:
public void FindNeighbours(List<Vertex> vertices) 
{ 
    Collider c = gameObject.GetComponent<Collider>(); 
    c.enabled = false; 
    Vector3 direction = Vector3.zero; 
    Vector3 origin = transform.position; 
    Vector3 target = Vector3.zero; 
    RaycastHit[] hits; 
    Ray ray; 
    float distance = 0f; 
    // next step 
} 
  1. Go over each object and cast a ray to validate whether it's completely visible and add it to the list of neighbors:
for (int i = 0; i < vertices.Count; i++) 
{ 
    if (vertices[i] == this) 
        continue; 
    target = vertices[i].transform.position; 
    direction = target - origin; 
    distance = direction.magnitude; 
    ray = new Ray(origin, direction); 
    hits = Physics.RaycastAll(ray, distance); 
    if (hits.Length == 1) 
    { 
        if (hits[0].collider.gameObject.tag.Equals("Vertex")) 
        { 
            Edge e = new Edge(); 
            e.cost = distance; 
            GameObject go = hits[0].collider.gameObject; 
            Vertex v = go.GetComponent<Vertex>(); 
            if (v != vertices[i]) 
                continue; 
            e.vertex = v; 
            neighbours.Add(e); 
        } 
    } 
} 
c.enabled = true; 
  1. Create the GraphVisibility class:
using UnityEngine; 
using System.Collections.Generic; 
 
public class GraphVisibility : Graph 
{ 
    // next steps 
} 
  1. Build the Load function for making the connections between vertices:
public override void Load() 
{ 
    Vertex[] verts = GameObject.FindObjectsOfType<Vertex>(); 
    vertices = new List<Vertex>(verts); 
    for (int i = 0; i < vertices.Count; i++) 
    { 
        VertexVisibility vv = vertices[i] as VertexVisibility; 
        vv.id = i; 
        vv.FindNeighbours(vertices); 
    } 
} 
  1. Define the GetNearesteVertex function:
public override Vertex GetNearestVertex(Vector3 position) 
{ 
    Vertex vertex = null; 
    float dist = Mathf.Infinity; 
    float distNear = dist; 
    Vector3 posVertex = Vector3.zero; 
    for (int i = 0; i < vertices.Count; i++) 
    { 
        posVertex = vertices[i].transform.position; 
        dist = Vector3.Distance(position, posVertex); 
        if (dist < distNear) 
        { 
            distNear = dist; 
            vertex = vertices[i]; 
        } 
    } 
    return vertex; 
} 
  1. Define the GetNeighbours function:
public override Vertex[] GetNeighbours(Vertex v) 
{ 
    List<Edge> edges = v.neighbours; 
    Vertex[] ns = new Vertex[edges.Count]; 
    int i; 
    for (i = 0; i < edges.Count; i++) 
    { 
        ns[i] = edges[i].vertex; 
    } 
    return ns; 
} 
  1. Finally, override the GetEdges function:
public override Edge[] GetEdges(Vertex v) 
{ 
    return vertices[v.id].neighbours.ToArray(); 
}