Skip to content

Commit

Permalink
Improved wheel rotation, no noticeable lag
Browse files Browse the repository at this point in the history
many changes in whell drive script
  • Loading branch information
AitorSimona committed Jan 4, 2021
1 parent 4553fa5 commit d21f355
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ PhysicMaterial:
dynamicFriction: 0
staticFriction: 0
bounciness: 1
frictionCombine: 1
frictionCombine: 0
bounceCombine: 0
22 changes: 21 additions & 1 deletion BottomGear/Assets/Game/Scenes/TestScenes/Vehicle.unity
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ Transform:
m_GameObject: {fileID: 838703698}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 7.61152, y: 0, z: 20.054111}
m_LocalScale: {x: 21.212807, y: 21.212807, z: 21.212807}
m_LocalScale: {x: 59.46586, y: 59.46586, z: 59.46586}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 6
Expand Down Expand Up @@ -521,6 +521,18 @@ PrefabInstance:
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 865184823, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: m_Drag
value: 0
objectReference: {fileID: 0}
- target: {fileID: 865184823, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: m_AngularDrag
value: 0
objectReference: {fileID: 0}
- target: {fileID: 865184823, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: m_CollisionDetection
value: 2
objectReference: {fileID: 0}
- target: {fileID: 1389970386, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: m_IsActive
value: 1
Expand All @@ -529,6 +541,14 @@ PrefabInstance:
propertyPath: test
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1817820544, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: maxTorque
value: 2500
objectReference: {fileID: 0}
- target: {fileID: 1817820544, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: criticalSpeed
value: 5
objectReference: {fileID: 0}
- target: {fileID: 1864884027688733411, guid: 75980be8169e8844595d320b13a7e456, type: 3}
propertyPath: m_Name
value: CustomCar
Expand Down
297 changes: 144 additions & 153 deletions BottomGear/Assets/Game/Scripts/Car/WheelDrive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,192 +2,183 @@
using System;
using Photon.Pun;

[Serializable]
public enum DriveType
namespace BottomGear
{
RearWheelDrive,
FrontWheelDrive,
AllWheelDrive
}

public class WheelDrive : MonoBehaviour
{
[Header("Wheels")]
[Tooltip("The vehicle's wheel count")]
public int wheelCount = 4;
[Tooltip("The vehicle's drive type: rear-wheels drive, front-wheels drive or all-wheels drive.")]
public DriveType driveType;
[Tooltip("Maximum steering angle of the wheels")]
public float maxAngle = 30f;
[Tooltip("Maximum torque applied to the driving wheels")]
public float maxTorque = 300f;
[Tooltip("Maximum brake torque applied to the driving wheels")]
public float brakeTorque = 30000f;

[Header("Controller")]
[Tooltip("The vehicle's speed when the physics engine can use different amount of sub-steps (in m/s).")]
public float criticalSpeed = 5f;
[Tooltip("The vehicle's limit speed.")]
public float maxSpeed = 30;
[Tooltip("Simulation sub-steps when the speed is above critical.")]
public int stepsBelow = 5;
[Tooltip("Simulation sub-steps when the speed is below critical.")]
public int stepsAbove = 1;

private PhotonView photonView;

Rigidbody rigidbody;
private Wheel[] m_Wheels;
public Transform centerOfMass;

struct Wheel
{
public WheelCollider collider;
public GameObject mesh;
}

public void Awake()
[Serializable]
public enum DriveType
{
photonView = GetComponent<PhotonView>();
RearWheelDrive,
FrontWheelDrive,
AllWheelDrive
}

// Find all the WheelColliders down in the hierarchy.
void Start()
{
m_Wheels = new Wheel[wheelCount];
WheelCollider[] cWheels = GetComponentsInChildren<WheelCollider>();

for (int i = 0; i < cWheels.Length; ++i)
{
m_Wheels[i].collider = cWheels[i];
[RequireComponent(typeof(Rigidbody))]

if (m_Wheels[i].collider)
{
MeshRenderer mr = m_Wheels[i].collider.gameObject.GetComponentInChildren<MeshRenderer>();

if (mr)
m_Wheels[i].mesh = mr.gameObject;
else
Debug.LogError("No wheel mesh found in wheel collider's subtree");
}
else
Debug.LogError("No wheel collider found in object's subtree");
}


rigidbody = GetComponent<Rigidbody>();

if (rigidbody != null && centerOfMass != null)
public class WheelDrive : MonoBehaviour
{
[Header("Wheels")]
[Tooltip("The vehicle's wheel count")]
public int wheelCount = 4;
[Tooltip("The vehicle's drive type: rear-wheels drive, front-wheels drive or all-wheels drive.")]
public DriveType driveType;
[Tooltip("Maximum steering angle of the wheels")]
public float maxAngle = 30f;
[Tooltip("Maximum torque applied to the driving wheels")]
public float maxTorque = 300f;
[Tooltip("Maximum brake torque applied to the driving wheels")]
public float brakeTorque = 30000f;

[Header("Controller")]
[Tooltip("The vehicle's speed when the physics engine can use different amount of sub-steps (in m/s).")]
public float criticalSpeed = 5f;
[Tooltip("The vehicle's limit speed.")]
public float maxSpeed = 30;
[Tooltip("Simulation sub-steps when the speed is above critical.")]
public int stepsBelow = 5;
[Tooltip("Simulation sub-steps when the speed is below critical.")]
public int stepsAbove = 1;

private PhotonView photonView;
private Rigidbody rb;
private Wheel[] m_Wheels;
public Transform centerOfMass;

struct Wheel
{
rigidbody.centerOfMass = centerOfMass.localPosition;
public WheelCollider collider;
public GameObject mesh;
public float rotation;
}

//for (int i = 0; i < m_Wheels.Length; ++i)
//{
// var wheel = m_Wheels[i];

// // Create wheel shapes only when needed.
// if (wheelShape != null)
// {
// var ws = Instantiate (wheelShape);
// ws.transform.parent = wheel.collider.transform;
// }
//}
}

// This is a really simple approach to updating wheels.
// We simulate a rear wheel drive car and assume that the car is perfectly symmetric at local zero.
// This helps us to figure our which wheels are front ones and which are rear.
void Update()
{
// --- Only update if this is the local player ---
if (!photonView.IsMine && Photon.Pun.PhotonNetwork.IsConnectedAndReady)
public void Awake()
{
return;
photonView = GetComponent<PhotonView>();
rb = GetComponent<Rigidbody>();
}

m_Wheels[0].collider.ConfigureVehicleSubsteps(criticalSpeed, stepsBelow, stepsAbove);

float angle = maxAngle * Input.GetAxis("Horizontal");
float torque = maxTorque * Input.GetAxis("Vertical");

// --- Limit car speed ---
if(rigidbody.velocity.magnitude > maxSpeed)
{
torque = 0;
}

float handBrake = Input.GetKey(KeyCode.X) ? brakeTorque : 0;

for (int i = 0; i < m_Wheels.Length; ++i)
// Find all the WheelColliders down in the hierarchy.
void Start()
{
ref WheelCollider wheel = ref m_Wheels[i].collider;
m_Wheels = new Wheel[wheelCount];
WheelCollider[] cWheels = GetComponentsInChildren<WheelCollider>();

// A simple car where front wheels steer while rear ones drive.
if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh")
wheel.steerAngle = angle;

if (m_Wheels[i].mesh.name == "Wheel3Mesh"
|| m_Wheels[i].mesh.name == "Wheel4Mesh")
for (int i = 0; i < cWheels.Length; ++i)
{
wheel.brakeTorque = handBrake;
m_Wheels[i].collider = cWheels[i];

if (m_Wheels[i].collider)
{
MeshRenderer mr = m_Wheels[i].collider.gameObject.GetComponentInChildren<MeshRenderer>();

if (mr)
m_Wheels[i].mesh = mr.gameObject;
else
Debug.LogError("No wheel mesh found in wheel collider's subtree");
}
else
Debug.LogError("No wheel collider found in object's subtree");
}

if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh"
&& driveType != DriveType.FrontWheelDrive)
// --- Set rigidbody's center of mass ---
if (rb != null && centerOfMass != null)
{
wheel.motorTorque = torque;
rb.centerOfMass = centerOfMass.localPosition;
}

if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh"
&& driveType != DriveType.RearWheelDrive)
else
{
wheel.motorTorque = torque;
Debug.LogError("Rigidbody is null or center of mass object does not exist");
}
}

// Update visual wheels if any.
if (m_Wheels[i].mesh)
void Update()
{
// --- Only update if this is the local player ---
if (!photonView.IsMine && Photon.Pun.PhotonNetwork.IsConnectedAndReady)
{
Quaternion q;
Vector3 p;
wheel.GetWorldPose (out p, out q);
return;
}

// Assume that the only child of the wheelcollider is the wheel shape.
Transform shapeTransform = m_Wheels[i].mesh.transform;
Debug.Log(-wheel.rpm / 60 * 360 * Time.deltaTime);
m_Wheels[0].collider.ConfigureVehicleSubsteps(criticalSpeed, stepsBelow, stepsAbove);

float rotation = wheel.rpm / 60 * 360 * Time.deltaTime;
float angle = maxAngle * Input.GetAxis("Horizontal");
float torque = maxTorque * Input.GetAxis("Vertical");

// --- Limit car speed ---
if (rb.velocity.magnitude > maxSpeed)
{
torque = 0;
}

float handBrake = Input.GetKey(KeyCode.X) ? brakeTorque : 0;

//Mathf.Clamp(rotation, 0.1f, rotation);
for (int i = 0; i < m_Wheels.Length; ++i)
{
ref WheelCollider wheel = ref m_Wheels[i].collider;

if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh")
{
//shapeTransform.rotation = q*Quaternion.Euler(wheel.rpm / 60 * 360 * Time.deltaTime, 0, 0);
// A simple car where front wheels steer while rear ones drive.
if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh")
wheel.steerAngle = angle;

if (m_Wheels[i].mesh.name == "Wheel3Mesh"
|| m_Wheels[i].mesh.name == "Wheel4Mesh")
{
wheel.brakeTorque = handBrake;
}

shapeTransform.Rotate(-rotation, 0, 0);
shapeTransform.rotation = Quaternion.Euler(shapeTransform.rotation.eulerAngles.x,
q.eulerAngles.y + 180, q.eulerAngles.z);
if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh"
&& driveType != DriveType.FrontWheelDrive)
{
wheel.motorTorque = torque;
}

//shapeTransform.rotation = q * Quaternion.Euler(0, 180, 0);
//shapeTransform.position = p;
if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh"
&& driveType != DriveType.RearWheelDrive)
{
wheel.motorTorque = torque;
}
else
{
shapeTransform.Rotate(rotation, 0, 0);
shapeTransform.rotation = Quaternion.Euler(shapeTransform.rotation.eulerAngles.x,
q.eulerAngles.y, q.eulerAngles.z);
//shapeTransform.rotation = q*Quaternion.Euler(wheel.rpm / 60 * 360 * Time.deltaTime, 0, 0);
//shapeTransform.position = p;
//shapeTransform.rotation = q;

}
}

private void LateUpdate()
{
for (int i = 0; i < m_Wheels.Length; ++i)
{
ref WheelCollider wheel = ref m_Wheels[i].collider;

// --- Update visual wheel's mesh ---
if (m_Wheels[i].mesh)
{
Quaternion q;
Vector3 p;
wheel.GetWorldPose(out p, out q);

// --- Rotate wheel according to collider's rotation ---
Transform shapeTransform = m_Wheels[i].mesh.transform;

m_Wheels[i].rotation += wheel.rpm / 60f * 360f * Time.deltaTime;

if (m_Wheels[i].mesh.name == "Wheel1Mesh"
|| m_Wheels[i].mesh.name == "Wheel2Mesh")
{

shapeTransform.rotation = Quaternion.Euler(-q.eulerAngles.x,
q.eulerAngles.y + 180, q.eulerAngles.z);

shapeTransform.Rotate(-m_Wheels[i].rotation, 0, 0);
}
else
{
shapeTransform.rotation = Quaternion.Euler(q.eulerAngles.x,
q.eulerAngles.y, q.eulerAngles.z);

shapeTransform.Rotate(m_Wheels[i].rotation, 0, 0);
}
}
}
}
}
}
}

0 comments on commit d21f355

Please sign in to comment.