Tengo problemas con la física en unity 3d. Quiero que mi pelota rebote en las paredes y vaya en otra dirección. Cuando la pelota golpea la pared, simplemente rebota hacia atrás. He intentado cambiar la dirección para que sea ortogonal a la dirección en la que golpea la pared, pero no cambia de dirección. Debido a esto, la pelota sigue golpeando la pared y rebotando hacia atrás.
En segundo lugar, a veces la pelota atraviesa la pared. Las paredes tienen colisionadores de caja mientras que la bola tiene un colisionador de esfera. Todos tienen dinámica continua como modo de detección de colisión.
Aquí hay un enlace a un hilo similar:
http://forum.unity3d.com/threads/22063-Disparé-una-flecha-en-el-aire...?highlight=shooting+arrow
Personalmente, codificaría la rotación usando LookAt como sugiere GargarathSunman en este enlace, pero si quieres hacerlo con física, probablemente necesitarás construir la alabarda en al menos un par de partes, como sugieren los otros en el enlace. , y agregue diferentes valores de arrastre y arrastre angular a cada parte, tal vez también densidad. Si arrojaras una jabalina al vacío, nunca aterrizaría con la punta hacia abajo porque la resistencia del aire juega un papel muy importante (todas las cosas caen a la misma velocidad, independientemente de su masa, gracias, Sir Isaac Newton). Es una simulación difícil de hacer bien para el motor de física.
Tal vez intente obtener el punto de colisión entre su esfera y su pared, luego tome la velocidad de su cuerpo rígido y revierta el punto de colisión normal.
un ejemplo de un script para hacer eso ---> (ponga este script en una pared con colisionador)
public class WallBumper : MonoBehaviour { private Vector3 _revertDirection; public int speedReflectionVector = 2; /*********************************************** * name : OnCollisionEnter * return type : void * Make every gameObject with a RigidBody bounce againt this platform * ********************************************/ void OnCollisionEnter(Collision e) { ContactPoint cp = e.contacts[0]; _revertDirection = Vector3.Reflect(e.rigidbody.velocity, cp.normal * -1); e.rigidbody.velocity = (_revertDirection.normalized * speedReflectionVector); } }Recientemente tuve un problema con un cohete que atravesaba objetivos debido a la velocidad e incluso con la detección dinámica continua de colisiones, no podía evitar que esto sucediera mucho.
Resolví esto usando un script "DontGoThroughThings" publicado en wiki.unity3d.com. Esto usa raycasting entre las posiciones actual y anterior y luego asegura que el marco termina con los colisionadores conectados para mensajes de un evento OnTrigger. Ha funcionado siempre desde entonces y solo es cuestión de adjuntar el script para que sea muy fácil de usar.
Creo que la respuesta de la física es, como otros han sugerido, usar múltiples componentes con diferente arrastre, aunque normalmente creo que solo quieres un solo RigidBody en el padre. En lugar de dirección usando transform.LookAt, podría intentar calcular usando Quaternion.LookRotation desde rigidbody.velocity. Luego use Vector3.Angle para averiguar cuánto hay de descuento. Cuanto mayor sea la diferencia de ángulo, más fuerza se debe experimentar y luego use RigidBody.ApplyTorque. Tal vez use Sin (diferencia de ángulo) * una constante para que se aplique menos fuerza al par a medida que se acerca a la rotación adecuada.
Aquí hay un código que usé en mi cohete, aunque tendrás que sustituir algunas cosas ya que estaba apuntando hacia un objetivo fijo y querrás usar tu velocidad.
var rotationDirection = Quaternion.LookRotation(lockedTarget.transform.position - this.transform.position); var anglesToGo = Vector3.Angle(this.transform.rotation.eulerAngles, rotationDirection.eulerAngles); if (anglesToGo > RotationVelocity) { var rotationDirectionToMake = (rotationDirection * Quaternion.Inverse(this.transform.rotation)).eulerAngles.normalized * RotationVelocity; transform.Rotate(rotationDirectionToMake); }