Estoy haciendo un juego de carreras. Cuando el coche que hice sube por una rampa, se pone un poco nervioso. No creas que es el problema de la cámara, ya que el juego se ve fluido en terrenos llanos y al bajar por una rampa. Este es el video del movimiento nervioso del automóvil en la rampa: https://youtu.be/6YC6SLsokCw
Seguí este tutorial: https://www.youtube.com/watch?v=cqATTzJmFDY&list=PLllUqr_Vxwvto-j8J-Fk2XmjQhn2PcwlZ&index=2
Noté que en este tutorial, el resultado final del autor también es un poco nervioso en las rampas. Este es el código:
{ sphereRb.transform.parent = null; } private void Update() { speedInput = 0; if (Input.GetAxis("Vertical") > 0) { GetInputForMoving(forwardAccel); } else if (Input.GetAxis("Vertical") < 0) { GetInputForMoving(reverseAccel); } turnInput = Input.GetAxis("Horizontal"); if (grounded) { Turning(); } SetWheelsRotation(); transform.position = sphereRb.transform.position; } void GetInputForMoving(float directionAccel) { speedInput = Input.GetAxis("Vertical") * directionAccel * multiplier; } void Turning() { transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + new Vector3(0f, turnInput * turnStrength * Time.deltaTime, 0f)); } void SetWheelsRotation() { leftFrontWheel.localRotation = Quaternion.Euler(leftFrontWheel.localRotation.eulerAngles.x, (turnInput * maxWheelTurn) - 180, leftFrontWheel.localRotation.eulerAngles.z); rightFrontWheel.localRotation = Quaternion.Euler(rightFrontWheel.localRotation.eulerAngles.x, (turnInput * maxWheelTurn), rightFrontWheel.localRotation.eulerAngles.z); } private void FixedUpdate() { grounded = false; RaycastHit hit; //if hits ground if (Physics.Raycast(groundRayPoint.position, -transform.up, out hit, groundRayLength, whatisGround)) { grounded = true; transform.rotation = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation; } if (grounded) { Moving(); } else { Dropping(); } } void Moving() { sphereRb.drag = dragOnGround; if (Mathf.Abs(speedInput) > 0) { sphereRb.AddForce(transform.forward * speedInput); } } void Dropping() { sphereRb.drag = 0.1f; sphereRb.AddForce(Vector3.up * -gravityForce * 100); }Por favor ayuda, estoy realmente luchando. Lo siento por mi inglés, gracias de antemano!
El movimiento del automóvil en realidad se ve bien y parece traducirse sin problemas.
El problema real es la rotación del coche .
Si miras esta línea:
transform.rotation = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation;Le está diciendo al automóvil que alinee su eje y de acuerdo con la malla normal . Sin embargo, una pendiente o rampa nunca será perfectamente curvada . Los polígonos dan forma a la pendiente y las normales entre cada "parte" de la pendiente cambian abruptamente: es por eso que la rotación del automóvil es tan pronunciada a lo largo de la pendiente . Puede verlo en la vista de escena habilitando el modo de sombreado de estructura alámbrica (opción disponible justo debajo de la pestaña "Escena").
Lo que puede hacer es interpolar entre la rotación actual del automóvil y la rotación objetivo con algo como el siguiente código :
Quaternion toRotation = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation; float angle = Vector3.Angle(transform.up, hit.normal); transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, angle * Time.fixedDeltaTime * rotateSpeed);Tendrás que modificar la velocidad de rotación hasta que coincida con lo que creas que está bien. Quaternion.RotateTowards interpolará suavemente entre la rotación actual y la rotación de destino a la velocidad de ángulo x rotarVelocidad grados por segundo. Hay mejores maneras de hacer todo esto, pero espero que esto te desbloquee con lo que tienes actualmente.