Traditional Culture Encyclopedia - Photography major - How to use Unity camera to determine the line of sight of AI agent, please help.

How to use Unity camera to determine the line of sight of AI agent, please help.

My idea is to bind a camera for each intelligent agent viewsensor. The camera has a certain field of view and far plane. Unity has two convenient camera testing methods. The first function returns the camera frustum defined by six parts, and the second function tells us whether the boundary object is inside or outside the camera frustum.

Now we can know whether a gameobjet is in our field of vision, but we don't know whether we can see it, because it may be blocked by another object closer to the camera. So I use line projection to tell us whether we can see this object. But which position should I change? The center position of the object is a good choice, but it is not necessarily accurate enough. I use the object grid boundary, traverse all the boundary positions, stop when linecast doesn't pass anything, and then I know if I can see the object.

The most perfect method is to draw a line between each vertex of the grid, but it will take too much time.

Get all game objects

Now we have a function that can tell us whether a specific object is in the line of sight of artificial intelligence. I just test each object, taking a camera position as the origin and the distance from the far plane of the camera as the radius, and check the overlapping range. I call the previous SeeGameObject function for each object and save the objects I see in an array.

Public bool SeeGameObject(GameObject go)

{

//If the object has a renderer, is visible to any camera, and is in this camera frustum.

if(go.renderer! = null & amp& ampgo . renderer . is visible & amp; & Geometric utility. TestPlanesAABB(GeometryUtility。 calculatefirtumplanes(_ camera),go.renderer.bounds))

{

RaycastHit hitInfo

//By default, we use rough renderer boundaries.

vector 3 center = go . renderer . bounds . center;

vector 3 extents = go . renderer . bounds . extents;

float coefreduc = 0.8f

vector 3[]gobounds; //Point to check the line broadcast from the camera

MeshFilter mesh filter = go. GetComponent & lt grid filter & gt ();

if(meshfilter! = null) // Almost every interesting game object has a grid.

{

center = go . transform . position;

extents = mesh filter . mesh . bounds . extents;

Range. scale(go . transform . lossyscale);

Gobounds = new Vector3[33]{ // We can add more or delete some, which can improve the accuracy without increasing too much time or memory overhead.

Vector 3. Zero,

go . transform . transform direction(new vector 3(extents . x,extents.y,extents.z)*0.9f),

go . transform . transform direction(new vector 3(extents . x,extents.y,-extents.z)*0.9f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,extents.z)*0.9f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,-extents.z)*0.9f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,extents.z)*0.9f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,-extents.z)*0.9f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,extents.z)*0.9f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,-extents.z)*0.9f),

go . transform . transform direction(new vector 3(extents . x,extents.y,extents.z)*0.5f),

go . transform . transform direction(new vector 3(extents . x,extents.y,-extents.z)*0.5f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,extents.z)*0.5f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,-extents.z)*0.5f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,extents.z)*0.5f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,-extents.z)*0.5f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,extents.z)*0.5f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,-extents.z)*0.5f),

go . transform . transform direction(new vector 3(extents . x,extents.y,extents.z)*0.75f),

go . transform . transform direction(new vector 3(extents . x,extents.y,-extents.z)*0.75f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,extents.z)*0.75f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,-extents.z)*0.75f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,extents.z)*0.75f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,-extents.z)*0.75f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,extents.z)*0.75f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,-extents.z)*0.75f),

go . transform . transform direction(new vector 3(extents . x,extents.y,extents.z)*0.25f),

go . transform . transform direction(new vector 3(extents . x,extents.y,-extents.z)*0.25f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,extents.z)*0.25f),

go . transform . transform direction(new vector 3(extents . x,-extents.y,-extents.z)*0.25f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,extents.z)*0.25f),

go . transform . transform direction(new vector 3(-extents . x,extents.y,-extents.z)*0.25f),

go . transform . transform direction(new vector 3(-extents . x,-extents.y,extents.z)*0.25f),

Go.transform.transform direction (new vector 3(-extents.x, -extents.y, -extents.z)*0.25f).

};

}

Else // Only when the game object has no grid (= almost none) (very approximate to use the renderer boundary instead of the grid boundary checkpoint)

{

gobounds = new Vector3[9]{

Vector 3. Zero,

The new vector 3(extents.x, extents.y, Extents.z) * coeffredc,

The new vector 3(extents.x, extents.y,-Extents.z) * coeffredc,

The new vector 3(extents.x, -extents.y, extents.z) * coeffredc,

The new vector 3(extents.x, -extents.y,-extents.z) * coeffredc,

The new vector 3(-extents.x, extents.y, extents.z) * coeffredc,

The new vector 3(-extents.x, extents.y,-extents.z) * coeffredc,

The new vector 3(-extents.x, -extents.y, extents.z) * coeffredc,

New Vector 3(-extents.x, -extents.y,-Extents.z) * coeffredc

};

}

Foreach (vector 3 v, in gigabytes)

{

//Test whether it can see the game object.

if(GeometryUtility。 TestPlanesAABB(GeometryUtility。 Compute files (_ camera), new Bounds(v+center, Vector3.zero)) // if point is in the viewing frustum.

& amp& amp(! Physics. Linecast(transform.position, v+center, out hit info) || hit info. collier.game object = = go))//If there is nothing between the viewing position and the point,

{

if(graphicalDebug)

{

Debugging. DrawLine(transform.position,v+center,Color.red,0.0 1f,false);

}

Return true

}

}

}

Returns false

}

If you don't understand anything, you can search Baidu: Memoirs of Programming. They are now recording tutorials in this field, all from scratch, from shallow to deep.