Red de conocimiento informático - Conocimiento del nombre de dominio - ¿Cómo utilizar la cámara Unity para determinar la línea de visión del agente de IA?

¿Cómo utilizar la cámara Unity para determinar la línea de visión del agente de IA?

Mi idea es vincular una cámara a cada agente inteligente y sensor de visión. La cámara está configurada con un cierto campo de visión y un plano lejano. Unity tiene dos métodos muy convenientes para probar la cámara. El primero devuelve 6 secciones para definir el tronco de la cámara y el segundo indica si un objeto delimitador está dentro o fuera del tronco de la cámara.

Ahora podemos saber si un objeto de juego está dentro de nuestra vista, pero no si podemos verlo, ya que puede estar ocluido por otro objeto más cercano a la posición de la cámara. Entonces uso linecasts para saber si podemos ver este objeto. ¿Pero qué posición debo convertir? La posición central del objeto es una buena elección, pero no necesariamente lo suficientemente precisa. Utilizo un borde de cuadrícula de objetos y reviso todas las posiciones del borde, deteniéndome cuando la transmisión de línea no pasa por nada, entonces sé si se puede ver el objeto.

La forma perfecta sería hacer un linecast entre cada vértice de la malla, pero llevaría demasiado tiempo.

Obtener todos los GameObjects

Ahora que tenemos una función que nos dice si un objeto específico está dentro de la línea de visión de la IA, simplemente pruebo cada objeto, dada la posición de la cámara como el origen. La verificación del rango de superposición se realiza utilizando la distancia desde el plano lejano de la cámara como radio. Llamo a la función SeeGameObject anterior para cada objeto y guardo los objetos a la vista en una matriz.

public bool SeeGameObject(GameObject go)

{

// si el objeto tiene un renderizador y es visible para cualquier cámara y está en esta cámara frustum

if(go.renderer != null && go.renderer.isVisible && GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(_camera), go.renderer.bounds))

{

RaycastHit hitInfo;

// por defecto usamos los límites aproximados del renderizador

Vector3 center = go.renderer.bounds.center;

Vector3 extends = go.renderer.bounds.extents;

float coefreduc = 0.8f;

Vector3[] gobounds; // puntos para verificar la transmisión de línea desde la cámara

MeshFilter meshfilter = go.GetComponent();

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

{

centro = go.transform.position;

extensiones = meshfilter.mesh.bounds.extents;

extensiones.Scale(go.transform.lossyScale);

gobounds = new Vector3[33]{ // Podemos agregar más o eliminar algunos, aumenta la precisión sin demasiado tiempo ni costo de memoria

Vector3.zero,

go.transform.TransformDirection(nuevo Vector3(extents.x,extents.y,extents.z)*0.9f),

go.transform.TransformDirection(nuevo Vector3(extents.x,exten

ts.y,-extents.z)*0.9f),

go.transform.TransformDirection(new Vector3(extents.x,-extents.y,extents.z)*0.9f), p>

go.transform.TransformDirection(nuevo Vector3(extents.x,-extents.y,-extents.z)*0.9f),

go.transform.TransformDirection(nuevo Vector3 (- extensiones.x, extensiones.y, extensiones.z)*0.9f),

go.transform.TransformDirection(new Vector3(-extents.x,extents.y,-extents.z)* 0.9f ),

go.transform.TransformDirection(new Vector3(-extents.x,-extents.y,extents.z)*0.9f),

go.transform. TransformDirection( nuevo Vector3(-extents.x,-extents.y,-extents.z)*0.9f),

go.transform.TransformDirection(nuevo Vector3(extents.x,extents.y,extents .z )*0.5f),

go.transform.TransformDirection(new Vector3(extents.x,extents.y,-extents.z)*0.5f),

go .transform .TransformDirection(new Vector3(extents.x,-extents.y,extents.z)*0.5f),

go.transform.TransformDirection(new Vector3(extents.x,-extents.y ,- extensiones.z)*0.5f),

go.transform.TransformDirection(new Vector3(-extents.x,extents.y,extents.z)*0.5f),

go.transform.TransformDirection(nuevo Vector3(-extents.x,extents.y,-extents.z)*0.5f),

go.transform.TransformDirection(nuevo Vector3(-extents.x ,- extensiones.y,extents.z)*0.5f),

go.transform.TransformDirection(new Vector3(-extents.x,-extents.y,-extents.z)*0.5f) ,

go.transform.TransformDirection(nuevo Vector3(extents.x,extents.y,extents.z)*0.75f),

go.transform.TransformDirection(nuevo Vector3( extensiones.x,extents.y,-extents.z)*0.75f),

go.transform.TransformDirection(new

Vector3(extensión.x,-extensión.y,extensión.z)*0.75f),

go.transform.TransformDirection(nuevo Vector3(extensión.x,-extensión.y,-extensión.z) *0.75f),

go.transform.TransformDirection(new Vector3(-extents.x,extents.y,extents.z)*0.75f),

go.transform. TransformDirection(nuevo Vector3(-extents.x,extents.y,-extents.z)*0.75f),

go.transform.TransformDirection(nuevo Vector3(-extents.x,-extents.y, extensiones.z)*0.75f),

go.transform.TransformDirection(new Vector3(-extents.x,-extents.y,-extents.z)*0.75f),

go.transform.TransformDirection(new Vector3(extents.x,extents.y,extents.z)*0.25f),

go.transform.TransformDirection(new Vector3(extents.x,extents. y,-extents.z)*0.25f),

go.transform.TransformDirection(new Vector3(extents.x,-extents.y,extents.z)*0.25f),

go.transform.TransformDirection(new Vector3(extents.x,-extents.y,-extents.z)*0.25f),

go.transform.TransformDirection(new Vector3(-extents. x,extents.y,extents.z)*0.25f),

go.transform.TransformDirection(new Vector3(-extents.x,extents.y,-extents.z)*0.25f),

go.transform.TransformDirection(nuevo Vector3(-extents.x,-extents.y,extents.z)*0.25f),

go.transform.TransformDirection(nuevo Vector3 (-extents.x,-extents.y,-extents.z)*0.25f)

};

}

else // Solo si el objeto del juego no tiene malla (= casi nunca) (Más o menos verificando los puntos usando los límites del renderizador y no los límites de la malla)

{

gobounds = nuevo Vector3[9]{

Vector3.zero,

nuevo Vector3(extents.x,extents.y,extents.z)* coefreduc,

nuevo Vector3(extents.x,extents.y,-extents.z)*coefreduc,

nuevo Vector3(extents.x,-extents.y,extents.z )*coefreduc,

nuevo Vector3(extents.x,-extents.y,-extents.z)*coefreduc,

nuevo Vector3(-extents.x,extents.y, extensiones.z)*coefreduc,

nuevo Vector3(-extents.x,extents.y,-extents.z)*coefreduc,

nuevo Vector3(-extents.x,- extensiones.y,extents.z)*coefreduc,

nuevo Vector3(-extents.x,-extents.y,-extents.z)*coefreduc

};

}

foreach(Vector3 v in gobounds)

{

// prueba si puede ver el objeto del juego

if (GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(_camera), new Bounds(v+center, Vector3.zero)) // si apunta a ver el frustrum

&& (!Physics.Linecast(transform.position, v +centro, fuera hitInfo) || hitInfo.collider.gameObject == ir )) //

si no hay nada entre la posición de visualización y el punto

{

if(graphicalDebug)

{

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

}

devuelve verdadero;

}

}

}

return false;

}

Si aún no entiendes nada, puedes buscar en Baidu: Memorias de programación, son Ahora, al grabar tutoriales en esta área, todos comenzamos desde cero y avanzamos desde lo menos profundo a lo más avanzado.