with unity trigger tag oncollisionenter evitar detectar colisión colisiones unity3d game-physics

unity3d - unity - ¿Cómo evitar que los colisionado se atraviesen?



unity 3d collision 2d (7)

Tengo problemas para mantener los objetos del juego dentro de un espacio contenido. Cuando alcanzan el borde, hay un empuje momentáneo hacia atrás pero luego pasan directamente a través de la pared.

Estoy usando un Box Collider en el reproductor y un Mesh Collider para la pared del nivel. Estoy teniendo problemas tanto con un personaje de jugador (una nave espacial) que el movimiento es controlado por el jugador. Y con proyectiles, que son fuego y olvidan moverse a una velocidad constante.

Este es mi código de movimiento para mi jugador. Se está ejecutando en la función FixedUpdate() .

//Movement haxis = Input.GetAxis("Horizontal") * speed; vaxis = Input.GetAxis("Vertical") * speed; moveVector.x = haxis; moveVector.z = vaxis; if(moveVector.magnitude > 1) { moveVector.Normalize(); } rigidbody.MovePosition(transform.position + moveVector * speed);

Con las balas, se les da una velocidad y el motor calcula sus películas. Están usando Box Collider y está configurado como Trigger para que no tengan física. Pero utilizo OnTriggerEnter para destruirlos.

//Projectiles without physics collisiions function OnTriggerEnter (other : Collider) { Destroy(gameObject); }

Algunas, pero no todas las balas se destruirán al golpear la pared del colisionador de malla. El jugador algunas veces lo golpeará y parará, pero generalmente puede atravesarlo. ¿Cómo puedo hacer que las colisiones con el colisionador de malla funcionen todo el tiempo?



Así que no he podido hacer que los colisionadores de malla funcionen. Creé un colisionador compuesto usando colisionadores de caja simple y funcionó exactamente como se esperaba.

Otras pruebas con Mesh Colliders simples han salido igual.

Parece que la mejor respuesta es construir un colisionador compuesto a partir de colisionadores simples de caja / esfera.

Para mi caso específico, escribí un asistente que crea un colisionador compuesto en forma de tubo.

@script AddComponentMenu("Colliders/Pipe Collider"); class WizardCreatePipeCollider extends ScriptableWizard { public var outterRadius : float = 200; public var innerRadius : float = 190; public var sections : int = 12; public var height : float = 20; @MenuItem("GameObject/Colliders/Create Pipe Collider") static function CreateWizard() { ScriptableWizard.DisplayWizard.<WizardCreatePipeCollider>("Create Pipe Collider"); } public function OnWizardUpdate() { helpString = "Creates a Pipe Collider"; } public function OnWizardCreate() { var theta : float = 360f / sections; var width : float = outterRadius - innerRadius; var sectionLength : float = 2 * outterRadius * Mathf.Sin((theta / 2) * Mathf.Deg2Rad); var container : GameObject = new GameObject("Pipe Collider"); var section : GameObject; var sectionCollider : GameObject; var boxCollider : BoxCollider; for(var i = 0; i < sections; i++) { section = new GameObject("Section " + (i + 1)); sectionCollider = new GameObject("SectionCollider " + (i + 1)); section.transform.parent = container.transform; sectionCollider.transform.parent = section.transform; section.transform.localPosition = Vector3.zero; section.transform.localRotation.eulerAngles.y = i * theta; boxCollider = sectionCollider.AddComponent.<BoxCollider>(); boxCollider.center = Vector3.zero; boxCollider.size = new Vector3(width, height, sectionLength); sectionCollider.transform.localPosition = new Vector3(innerRadius + (width / 2), 0, 0); } } }


La colisión con objetos que se mueven rápidamente es siempre un problema. Una buena forma de asegurarse de detectar todas las colisiones es utilizar Raycasting en lugar de confiar en la simulación física. Esto funciona bien para balas u objetos pequeños, pero no producirá buenos resultados para objetos grandes. http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html

Pseudo-codeish (no tengo código completado aquí y una mala memoria):

void FixedUpdate() { Vector3 direction = new Vector3(transform.position - lastPosition); Ray ray = new Ray(lastPosition, direction); RaycastHit hit; if (Physics.Raycast(ray, hit, direction.magnitude)) { // Do something if hit } this.lastPosition = transform.position; }


Tengo un prototipo de pinball que también me dio muchos problemas en las mismas áreas. Estos son todos los pasos que he dado para resolver casi todos estos problemas (aunque no del todo):

Para objetos en movimiento rápido:

  • Establezca Interpolate del cuerpo rígido en ''Interpolar'' (esto no afecta la simulación de física real, pero actualiza la representación del objeto correctamente; utilícelo solo en objetos importantes desde el punto de vista del renderizado, como el jugador o un pinball, pero no para proyectiles)

  • Establecer detección de colisión en dinámica continua

  • Adjunte el script DontGoThroughThings ( https://www.auto.tuwien.ac.at/wordpress/?p=260 ) a su objeto. Esta secuencia de comandos hábilmente utiliza la solución Raycasting que publiqué en mi otra respuesta para alejar los objetos ofensivos antes de los puntos de colisión.

En Editar -> Configuración del proyecto -> Física :

  • Establezca Penetración mínima para penalización a un valor muy bajo. Establecí el mío en 0.001

  • Establezca el conteo de iteración de solucionador en un valor superior. He establecido el mío en 50, pero probablemente puedas hacerlo bien con mucho menos.

Todo lo que va a tener una penalización en el rendimiento, pero eso es inevitable. Los valores predeterminados son suaves en cuanto al rendimiento, pero no son realmente adecuados para una simulación adecuada de objetos pequeños y de movimiento rápido.


  • Editar ---> Configuración del proyecto ---> Tiempo ... decrese "Fixed Timestep" value ... Esto resolverá el problema pero puede afectar negativamente el rendimiento.

  • Otra solución es calcular las coordenadas (por ejemplo, si tiene una bola y una pared. La bola chocará contra la pared. Así que calcule las coordenadas de la pared y establezca el proceso de golpe de acuerdo con estos cordinates)


1.) Nunca use MESH COLLIDER. Use una combinación de colisionador de caja y cápsula.

2.) Verifique las restricciones en RigidBody. Si marca Posición congelada X, pasará por el objeto en el eje X. (Lo mismo para el eje y)


Pregunta anterior, pero tal vez ayuda a alguien.

Vaya a Configuración del proyecto> Hora e intente dividir el lapso de tiempo fijo y el lapso de tiempo máximo permitido por dos o por cuatro.

Tuve el problema de que mi jugador podía pasar por aberturas más pequeñas que el colisionador de los jugadores y eso lo resolvió. También ayuda a detener los objetos que se mueven rápidamente.