Red de conocimientos turísticos - Preguntas y respuestas turísticas - Cómo utilizar la cámara de Unity para determinar la línea de visión del agente de IA, por favor ayuda.

Cómo utilizar la cámara de Unity para determinar la línea de visión del agente de IA, por favor ayuda.

Mi idea es vincular una cámara a cada sensor de vista de agente inteligente. Una cámara tiene un cierto campo de visión y un plano lejano. Unity tiene dos métodos convenientes para probar cámaras. La primera función devuelve el tronco de cámara definido por sus seis partes, y la segunda función nos dice si el objeto delimitador está dentro o fuera del tronco de cámara.

Ahora sabemos si un objeto de juego está en nuestro campo de visión, pero no si podemos verlo porque puede estar bloqueado por otro objeto más cercano a la posición de la cámara. Entonces uso conversiones de líneas para decirnos si podemos ver el objeto. ¿Pero a qué posición debería cambiar? El centro del objeto es una buena elección, pero puede que no sea lo suficientemente preciso. Utilizo un borde de cuadrícula de objetos, reviso todas las posiciones del borde y me detengo cuando la transmisión de línea no pasa nada, entonces sé si puedo ver el objeto.

El método más perfecto es trazar una línea entre cada vértice de la malla, pero esto llevará demasiado tiempo.

Obtener todos los objetos del juego

Ahora tenemos una función que nos indica si un objeto concreto está dentro de la línea de visión de la IA. Simplemente pruebo cada objeto, usando una posición de la cámara como origen y la distancia desde el plano lejano de la cámara como radio, verificando el rango de superposición. Llamo a la función SeeGameObject anterior para cada objeto y guardo los objetos vistos en una matriz.

Public bool SeeGameObject(GameObject go)

{

//Si el objeto tiene un renderizador y es visible para cualquier cámara, y esta cámara lo recorta en cabecera

if(go.renderer!= null & go.renderer.is visible&GeometryUtility.TestPlanesAABB(GeometryUtility.calculatefirtumplanes(_ camera), go.renderer.bounds) )

{

RaycastHit hitInfo

//De forma predeterminada, utilizamos límites de renderizador aproximados

vector 3 center = go renderer junctions . p>vector 3 extends = go . rendererbounds .extensions;

float coefreduc = 0.8f

vector 3[]gobounds // Puntero para verificar la línea transmitida desde la cámara

Filtro de malla MeshFilter = ir. GetComponent & ltMesh Filter& gt();

if(meshfilter!= null) //Casi todos los objetos interesantes del juego tienen una malla

{

center = go . transformar posición;

extensiones = filtro de malla. límites de malla;

rango.

scale(go . transform . lossyscale);

gobounds = new Vector3[33]{ //Podemos agregar más o eliminar algunos, lo que puede mejorar sin agregar demasiado tiempo o sobrecarga de memoria Precisión

vector 3.cero,

ir a .transform.transform dirección (nuevo vector 3(extents.x,extents.y,extents.z)*0.9f),

p>

ir . transformar . transformar dirección (nuevo vector 3 (extensiones. x, extensiones.y, -extents.z)*0.9f),

ir a transformar . 3(extensiones. x, -extents.y, extensiones.z)*0.9f),

ir a transformar. transformar dirección (nuevo vector 3(extensiones. z)*0.9f),

go.transformar.transformar dirección(nuevo vector 3(-extents.x, extensiones.y, extensiones.z)*0.9f),

transformar dirección(nuevo vector 3). (-extents. x, extensiones.y, -extents.z)*0.9f),

go. transform. transformar dirección (nuevo vector 3(-extents. x, -extents.y, extensiones. z)*0.9f),

go . transform . transform dirección(nuevo vector 3(-extents . *0.9f),

go . transform . transform dirección(nuevo vector 3 (extensiones. x, extensiones.y, extensiones.z) *0.5f),

ir a transformar. transformar dirección (nuevo vector 3(extensiones. x, extensiones.y, -extents.z)* 0.5f),

ir . transformar . transformar dirección (nuevo vector 3(extents. x, -extents .y,extents.z)*0.5f),

ir . . transformar dirección(nuevo vector 3(extensiones. x,-extents.y,-extents.z)*0.5f),

go transformar dirección(nuevo vector 3(-extensiones. x, extensiones.y, extensiones.z)*0.5f),

ir a transformar . transformar dirección (nuevo vector 3(-extents. extensiones.z)*0.5f),

ir . transformar . transformar dirección (nuevo vector 3(-extents. x, -extents.y, -extents.z)*0.5f),

ir transformar . . x, extensiones.y, extensiones.z)*0.75f),

ir a transformar. Transformar dirección (nuevo vector 3(extensiones.x,extents.y,-extents.z)*0.75f). ),

go .transform.transform dirección (nuevo vector 3 (extensiones. 0.75f),

go . transform . transforma dirección (nuevo vector 3 (extensiones . x, -extents .y, -extents.z)*0.75f),

ir . transformar . transformar dirección (nuevo vector 3(-extents. x,extents.y,extents.z)*0.75f),

ir . extensiones.y, -extents.z)*0.75f),

ir . transformar . transformar dirección (nuevo vector 3(-extents. x, -extents.y, extends.z)*0.75f) ,

go . transform . transformar dirección(nuevo vector 3(-extents . x, -extents.y, -extents.z)*0.75f),

ir . transformar . transformar dirección(nuevo vector 3(extensiones. x, extensiones.y, extensiones.z)*0.25f),

ir transformar . extensiones. -extents.z)*0.25f),

ir . transformar . transformar dirección (nuevo vector 3(extents. x, -extents.y, extends.z)*0.25f),

ir . transformar . transformar dirección (nuevo vector 3(extents. x, -extents.y, -extents.z)*0.25f),

ir transformar . vector 3 (-extents. )*0.25f),

go. transform . transformar dirección (nuevo vector 3(-extents. x, -extents.y, extends.z)*0.25f),

ir . transformar . transformar dirección (nuevo vector 3(-extents.x,-extents.y,-extents.z)*0.25f)

};

}

else //Solo si el objeto del juego no tiene malla (= casi ninguna) (muy aproximado usando límites de renderizador en lugar de puntos de control de límites de malla)

{

gobounds = nuevo Vector3[9]{

Vector3.zero,

Nuevo Vector3(extensiones.x, extensiones.y, extensiones.z)*coefreduc,

Nuevo vector 3(extensiones.x, extensiones.y, -extents.z)*coefreduc,

Nuevo vector 3(extensiones.x, -extents.y, extensiones.z)*coefreduc ,

Nuevo vector 3(extents.x,-extents.y,-extents.z)*coefreduc,

Nuevo vector 3(-extents.x, extensiones.y, extensiones .z)*coefreduc,

Nuevo vector 3(-extents.x, extends.y, -extents.z)*coefreduc,

Nuevo vector 3(-extents.x, -extents.y, extends.z)*coefreduc,

Nuevo vector 3(-extents.x, -extents.y, -extents.z)*coefreduc

};

}

foreach(vector 3 v, en gigabytes)

{

//Prueba si se puede ver GameObject

if(GeometryUtility. TestPlanesAABB(GeometryUtility.calculatefirtumplanes(_ camera), new Bounds(v+center, Vector3.zero)) // si el punto está en ver frustum

& amp& amp(!Physics.Linecast(transform.position, v+center, out hitInfo) | hitInfo .game object = = go))//Si no hay nada entre la posición de visualización y el punto

{

if( gráficoDebug)

{

Depurar. DrawLine(transform.position, v+center, Color.red, 0.01f, false);

}

Devuelve verdadero

}

}

}

Devuelve falso

}

Si hay algo que no entiendes, puedes buscar en Baidu: Memorias de programación. Actualmente están grabando tutoriales en esta área, comenzando desde cero y progresando de superficial a profundo.