Je suis en train de développer un système de conduite à la Mario Kart, Wipeout...
Ce système n'utilisent pas de composants Wheel Collider mais des raycasts qui permet de soulever le véhicule lorsque ces derniers touchent la route (même principe qu'un déplacement d'une voiture volante style Wipeout).
Vidéo Explicative : https://www.youtube.com/watch?v=LG1CtlFRmpU
Pour le développement je me suis basé sur ces deux tutoriaux : La voiture ou le kart est juste un cube pour sa collision qui contient 4 raycast vers le bas comme si c'était les suspensions de nos 4 roues.
Voici le code actuellement
Code : Tout sélectionner
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaycastCar : MonoBehaviour {
Rigidbody m_rigidBody;
public Transform m_centerOfMass;
public float m_forwardAcceleration = 10000f;
public float m_reverseAcceleration = 2500f;
public float m_turn = 300f;
public float m_groundedDrag = 3f; // rigidbody drag on grounded (same on rigidbody drag at start)
public LayerMask m_layerMask;
public float m_hoverHeight = 1f;
public float m_hoverForce = 900f;
public List<Transform> m_hoverPoints;
public float m_maxSpeed = 180f;
float m_deadZone = 0.1f; //make the controller not so sensitive to small movements.Basically any input below the deadZone threshold is ignored.
float m_currThrust;
float m_currTurn;
void Awake()
{
m_rigidBody = GetComponent<Rigidbody>();
}
void Start()
{
m_rigidBody.centerOfMass = m_centerOfMass.localPosition;
}
void Update () {
m_currThrust = 0f;
float vertical = Input.GetAxis("Vertical");
if (vertical > m_deadZone) // on appuie vers le haut
m_currThrust = vertical * m_forwardAcceleration;
else if (vertical < -m_deadZone)
m_currThrust = vertical * m_reverseAcceleration;
// Controle pour tourner
m_currTurn = 0f;
float horizontal = Input.GetAxis("Horizontal");
if(Mathf.Abs(horizontal) > m_deadZone)
{
m_currTurn = horizontal;
}
}
void FixedUpdate () {
//print(m_rigidBody.velocity);
// Avant/Arrière
if (Mathf.Abs(m_currThrust) > 0)
m_rigidBody.AddForce(transform.forward * m_currThrust);
//Tourner
if(m_currTurn > 0)
{
m_rigidBody.AddRelativeTorque(Vector3.up * m_currTurn * m_turn);
}else if(m_currTurn < 0)
{
m_rigidBody.AddRelativeTorque(Vector3.up * m_currTurn * m_turn);
}
// Limit max velocity
if (m_rigidBody.velocity.sqrMagnitude > (m_rigidBody.velocity.normalized * m_maxSpeed).sqrMagnitude)
{
m_rigidBody.velocity = m_rigidBody.velocity.normalized * m_maxSpeed;
}
RaycastHit hit;
bool grounded = false;
foreach(Transform hoverPoint in m_hoverPoints)
{
Debug.DrawRay(hoverPoint.position, -Vector3.up * m_hoverHeight, Color.green);
if (Physics.Raycast(hoverPoint.position, -Vector3.up,out hit,m_hoverHeight,m_layerMask))
{
Debug.DrawRay(hoverPoint.position, -Vector3.up * m_hoverHeight, Color.red);
float compressFactor = (1f - (hit.distance / m_hoverHeight)); // Spring compression
m_rigidBody.AddForceAtPosition(Vector3.up * m_hoverForce * compressFactor, hoverPoint.position);
grounded = true;
}
else
{
// Self levelling - returns the vehicle to horizontal when not grounded
if (transform.position.y > hoverPoint.transform.position.y)
{
m_rigidBody.AddForceAtPosition(hoverPoint.transform.up * m_hoverForce, hoverPoint.transform.position);
}
else
{
m_rigidBody.AddForceAtPosition(hoverPoint.transform.up * -m_hoverForce, hoverPoint.transform.position);
}
}
}
if(grounded)
{
m_rigidBody.drag = m_groundedDrag;
}
else
{
m_rigidBody.drag = 0.1f;
m_currThrust /= 100f;
m_currTurn /= 100f;
}
}
}
Raycast Vert : Suspension Relâchée (Extended)
Raycast Rouge (au sol) : Suspension Compressée
Le système fonctionne plutôt bien pour des voitures volantes, vaisseau (Wipeout) ... avec hoverHeight > 1
Cependant quand j'essaye de faire un voiture (hoverHeight = 0.5f par exemple) qui roule sur des routes penchées et loopings, la voiture ne suit pas la courbure de la route et les suspensions sont relachées :
Est-ce que vous auriez un conseil ou des solutions afin de donner l'impression que l'on conduit une voiture type kart ? Please
En attendant j'espère que ce script peut vous être utile si vous voulez faire des prototype de jeux de courses.