- Home /
Car braking in mobile input
Hi Unity Answers,
I'm making a racing game for mobile devices, and I've encountered a problem with the braking. In the editor, the braking works fine. When I build it to iOS/Android, when I tap the brake UI button, the car is put in reverse and stays in reverse. I'm not sure if it has something to do with the physics or the input.
Any ideas about why this is happening? Thanks!
EDIT: Here's the code for the CarController.cs
public partial class CarController : Generic.GenericVehicleController
{
// public -- external prefabs
public GameObject skidmarkSmokePrefab = null;
public GameObject carDamageSmokePrefab = null;
public GameObject carDamageFirePrefab = null;
// public
public bool debug = false;
public CarDriveType carDriveType = CarDriveType.FourWheelDrive;
public Vector3 CentreOfMassOffset = Vector3.zero;
public float MaximumSteerAngle = 10;
public float SteerHelper = 1; // 0 is raw physics , 1 the car will grip in the direction it is facing
public float TractionControl = 1; // 0 is no traction control, 1 is full interference
public float TopSpeed = 100;
public float FullTorqueOverAllWheels = 2500;
public float ReverseTorque = 500;
public float MaxHandbrakeTorque = 0;
public float BrakeTorque = 20000;
public float Downforce = 100f;
public SpeedType SpeedType = SpeedType.MPH;
public int NoOfGears = 5;
public float RevRangeBoundary = 1f;
public float SlipLimit = 0.3f;
public bool driveAllowed = true;
public bool lockedTo2D = false;
public bool alternateAxis = false;
public bool manual2DRotationAllowedIn = false;
// private
int index = -1;
// private
GameObject WheelsHubs = null;
WheelCollider[] WheelColliders = new WheelCollider[4];
GameObject[] WheelMeshes = new GameObject[4];
WheelEffects[] WheelEffects = new WheelEffects[4];
// private -- particles
EllipsoidParticleEmitter carDamageSmoke = null;
// private -- fake wheels
List<GameObject> fakeWheelList = new List<GameObject>();
// private
Quaternion[] WheelMeshLocalRotations;
Vector3[] WheelMeshLocalPositions;
float SteerAngle = 0;
int GearNum = 0;
float GearFactor = 0;
float OldRotation = 0;
float CurrentTorque = 0;
Rigidbody Rigidbody = null;
const float k_ReversingThreshold = 0.01f;
// private
GameObject Lights = null;
GameObject HeadlightLeftSpot = null;
GameObject HeadlightRightSpot = null;
// private
bool haveToLoad = true;
// private -- for AI
Transform Target; // 'target' the target object to aim for.
int actualWayPointIndex = 0;
CarAIControl carAIControl = null;
// public -- for AI
public float BaseMaxTorque = 0;
public float SpecialSpeedMultiplier = 1;
// private -- for AI (new)
public float speedLimiter = 1;
public float extraSpeedLimiter = 0;
// private
Vector3 lastRestorePosition = Vector3.zero;
Vector3 lastRestoreDirection = Vector3.zero;
// private
Transform Driver = null;
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// AwakeExtended -- OVERRIDED
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
protected override void AwakeExtended()
{
// save position to restore car
lastRestorePosition = this.transform.position;
lastRestoreDirection = this.transform.forward;
// get AI control
this.carAIControl = this.gameObject.GetComponent<CarAIControl>();
// save max torque
this.BaseMaxTorque = FullTorqueOverAllWheels;
// disable parts
SetPartsEnabled(false);
// get lights
this.Lights = BasicFunctions.GetTransformInChildsByName(this.transform, "Lights").gameObject;
this.HeadlightLeftSpot = BasicFunctions.GetTransformInChildsByName(this.transform, "HeadlightLeftSpot").gameObject;
this.HeadlightRightSpot = BasicFunctions.GetTransformInChildsByName(this.transform, "HeadlighRightSpot").gameObject;
// get driver
Driver = BasicFunctions.GetTransformInChildsByName(this.transform, "Driver");
Load();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// OnCollisionEnter
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void OnCollisionEnter(Collision col)
{
CarController actualCarController = BasicFunctions.GetParentCarController(col.collider.transform);
if (actualCarController && !actualCarController.gameObject.Equals(this.gameObject))
{
//Debug.Log("OnCollisionEnter: " + actualCarController.name);
if (boostAllowed && (actualBoostTime > 0))
{
Debug.Log("Disable boost for " + this.gameObject.name);
actualBoostTime = 0;
Vector3 forwardFixed = this.transform.forward;
forwardFixed.y = 0;
this.gameObject.GetComponent<Rigidbody>().velocity = this.transform.forward;
this.gameObject.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// HideDriver
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
public void HideDriver()
{
if (Driver) Driver.gameObject.SetActive(false);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Index
/// # return actual car index (defined by CarManager
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
public int Index
{
get { return index; }
set { index = value; }
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// GetActualWayPointIndex
/// # return actual waypoint index for this controller
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
public int GetActualWayPointIndex()
{
return actualWayPointIndex;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// ChangeWayPoint
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
public void ChangeWayPoint(WayPoint actualWayPoint)
{
CarStats carStats = this.gameObject.GetComponent<CarStats>();
carStats.numWayPointsPassed++;
//print ("ChangeWaypoint -> actualWayPoint: " + actualWayPointIndex);
if (actualWayPoint == CarManager.Singleton.GetActualWayPointTargetByCarController(this))
{
//print ("ChangeWaypoint -> previous: " + wayPointList [actualWayPointIndex].index);
actualWayPointIndex++;
if (actualWayPointIndex >= CarManager.Singleton.GetWayPointList().Count)
{
actualWayPointIndex = 0;
}
SetTarget(CarManager.Singleton.GetActualWayPointTargetByCarController(this).transform);
//print ("ChangeWaypoint -> actual: " + wayPointList [actualWayPointIndex].index);
carStats.ResetLastDistanceToTargetSaved(false);
// save restore position
lastRestorePosition = actualWayPoint.transform.position;
lastRestorePosition.y = transform.position.y;
lastRestoreDirection = actualWayPoint.GetRealDirection();
}
else
{
carStats.ResetLastDistanceToTargetSaved(true);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Load
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void Load()
{
if (haveToLoad)
{
haveToLoad = false;
if (tag == "Player") {
if (GameSettings.SelectedCar != null) {
TopSpeed = GameSettings.SelectedCar.TopSpeed;
SteerHelper = GameSettings.SelectedCar.Handling;
boostForce = GameSettings.SelectedCar.Ignitro;
if (GameSettings.SelectedCar.DriveTrainId == 0) {
carDriveType = CarDriveType.FrontWheelDrive;
} else if (GameSettings.SelectedCar.DriveTrainId == 1) {
carDriveType = CarDriveType.RearWheelDrive;
} else {
carDriveType = CarDriveType.FourWheelDrive;
}
}
}
WheelsHubs = BasicFunctions.GetTransformInChildsByName(this.transform, "WheelsHubs").gameObject;
WheelColliders[0] = BasicFunctions.GetTransformInChildsByName(this.transform, "WheelHubFrontRight").GetComponent<WheelCollider>() as WheelCollider;
WheelColliders[1] = BasicFunctions.GetTransformInChildsByName(this.transform, "WheelHubFrontLeft").GetComponent<WheelCollider>() as WheelCollider;
WheelColliders[2] = BasicFunctions.GetTransformInChildsByName(this.transform, "WheelHubRearRight").GetComponent<WheelCollider>() as WheelCollider;
WheelColliders[3] = BasicFunctions.GetTransformInChildsByName(this.transform, "WheelHubRearLeft").GetComponent<WheelCollider>() as WheelCollider;
WheelEffects[0] = WheelColliders[0].GetComponent<WheelEffects>() as WheelEffects;
WheelEffects[1] = WheelColliders[1].GetComponent<WheelEffects>() as WheelEffects;
WheelEffects[2] = WheelColliders[2].GetComponent<WheelEffects>() as WheelEffects;
WheelEffects[3] = WheelColliders[3].GetComponent<WheelEffects>() as WheelEffects;
WheelEffects[0].LoadWheelEffects(skidmarkSmokePrefab);
WheelEffects[1].LoadWheelEffects(skidmarkSmokePrefab);
WheelEffects[2].LoadWheelEffects(skidmarkSmokePrefab);
WheelEffects[3].LoadWheelEffects(skidmarkSmokePrefab);
WheelMeshes[0] = BasicFunctions.GetTransformInChildsByName(WheelColliders[0].transform, "CarWheelFrontRight").gameObject;
WheelMeshes[1] = BasicFunctions.GetTransformInChildsByName(WheelColliders[1].transform, "CarWheelFrontLeft").gameObject;
WheelMeshes[2] = BasicFunctions.GetTransformInChildsByName(WheelColliders[2].transform, "CarWheelRearRight").gameObject;
WheelMeshes[3] = BasicFunctions.GetTransformInChildsByName(WheelColliders[3].transform, "CarWheelRearLeft").gameObject;
WheelMeshLocalRotations = new Quaternion[4];
WheelMeshLocalPositions = new Vector3[4];
for (int i = 0; i < 4; i++)
{
WheelMeshLocalRotations[i] = WheelMeshes[i].transform.localRotation;
WheelMeshLocalPositions[i] = WheelMeshes[i].transform.localPosition;
}
WheelColliders[0].attachedRigidbody.centerOfMass = CentreOfMassOffset;
MaxHandbrakeTorque = float.MaxValue;
Rigidbody = GetComponent<Rigidbody>();
CurrentTorque = FullTorqueOverAllWheels - (TractionControl * FullTorqueOverAllWheels);
// instantiate carDamageSmokePrefab particles
if (carDamageSmokePrefab)
{
if (GetComponent<DestructibleObject>())
{
GameObject clone = Instantiate(carDamageSmokePrefab);
//print ("carDamageSmoke loaded A");
carDamageSmoke = clone.GetComponent<EllipsoidParticleEmitter>();
carDamageSmoke.emit = false;
carDamageSmoke.transform.parent = this.transform;
carDamageSmoke.transform.localPosition = Vector3.zero;
carDamageSmoke.transform.localRotation = Quaternion.identity;
carDamageSmoke.transform.Rotate(new Vector3(0, 180, 0));
carDamageSmoke.name = carDamageSmokePrefab.name + "_" + index;
//print ("carDamageSmoke loaded B");
}
}
else
{
//Debug.LogWarning ("No particle system found on car to generate carDamageSmoke particles");// in " + this.transform.parent.parent.name);
}
// enable parts
SetPartsEnabled(true);
}
}
}
Other Code:
public void EnableBoost()
{
if (boostAllowed)
{
actualBoostTime = boostTime;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// HandleBoost
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void HandleBoost()
{
if (boostAllowed)
{
if (actualBoostTime > 0)
{
Vector3 forwardFixed = this.transform.forward;
forwardFixed.y = 0;
this.gameObject.GetComponent<Rigidbody>().velocity = (boostForce * forwardFixed);
}
actualBoostTime -= Time.deltaTime;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// HandlerFirstAcceleration
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void HandlerFirstAcceleration(float v)
{
if (v > 0)
{
if (firstAccelerationAllowed)
{
firstAccelerationAllowed = false;
this.gameObject.GetComponent<Rigidbody>().velocity = (firstAccelerationForce * this.transform.forward);
//Debug.Log("First acceleration force");
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Move
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
public void Move(float steering, float accel, float footbrake, float handbrake)
{
//Debug.Log ("steering: " + steering + " accel: " + accel + " footbrake: " + footbrake + " footbrake: " + footbrake);
if (!driveAllowed)
{
// Car should not be moving,
// use handbrake to stop
InternalMove(0, 0, 0f, 1f);
}
else
{
InternalMove(steering, accel, footbrake, handbrake);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// InternalMove
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void InternalMove(float steering, float accel, float footbrake, float handbrake)
{
if (WheelColliders[0])
{
for (int i = 0; i < 4; i++)
{
Quaternion quat;
Vector3 position;
WheelColliders[i].GetWorldPose(out position, out quat);
WheelMeshes[i].transform.position = position;
WheelMeshes[i].transform.rotation = quat;
if ((i == 0) || (i == 2))
{
//WheelMeshes [i].transform.Rotate (180 * Vector3.up);
}
//WheelMeshes [i].transform.localPosition = WheelMeshLocalPositions[i];
}
//clamp input values
steering = Mathf.Clamp(steering, -1, 1);
AccelInput = accel = Mathf.Clamp(accel, 0, 1);
BrakeInput = footbrake = -1 * Mathf.Clamp(footbrake, -1, 0);
handbrake = Mathf.Clamp(handbrake, 0, 1);
//Set the steer on the front wheels.
//Assuming that wheels 0 and 1 are the front wheels.
SteerAngle = steering * MaximumSteerAngle;
WheelColliders[0].steerAngle = SteerAngle;
WheelColliders[1].steerAngle = SteerAngle;
HandleSteerHelper();
ApplyDrive(accel, footbrake);
CapSpeed();
//Set the handbrake.
//Assuming that wheels 2 and 3 are the rear wheels.
//if (handbrake > 0f)
{
var hbTorque = handbrake * MaxHandbrakeTorque;
WheelColliders[2].brakeTorque = hbTorque;
WheelColliders[3].brakeTorque = hbTorque;
}
CalculateRevs();
GearChanging();
AddDownForce();
CheckForWheelSpin();
HandleTractionControl();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// CapSpeed
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void CapSpeed()
{
float speed = Rigidbody.velocity.magnitude;
switch (SpeedType)
{
case SpeedType.MPH:
{
speed *= 2.23693629f;
if (speed > MaxSpeed)
{
//print ("speed: +speed");
Rigidbody.velocity = (MaxSpeed / 2.23693629f) * Rigidbody.velocity.normalized;
}
}
break;
case SpeedType.KPH:
{
speed *= 3.6f;
if (speed > MaxSpeed)
{
Rigidbody.velocity = (MaxSpeed / 3.6f) * Rigidbody.velocity.normalized;
}
}
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// ApplyDrive
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////
void ApplyDrive(float accel, float footbrake)
{
float thrustTorque;
switch (carDriveType)
{
case CarDriveType.FourWheelDrive:
{
thrustTorque = accel * (CurrentTorque / 4f);
for (int i = 0; i < 4; i++)
{
WheelColliders[i].motorTorque = thrustTorque;
}
}
break;
case CarDriveType.FrontWheelDrive:
{
thrustTorque = accel * (CurrentTorque / 2f);
WheelColliders[0].motorTorque = WheelColliders[1].motorTorque = thrustTorque;
}
break;
case CarDriveType.RearWheelDrive:
{
thrustTorque = accel * (CurrentTorque / 2f);
WheelColliders[2].motorTorque = WheelColliders[3].motorTorque = thrustTorque;
}
break;
}
for (int i = 0; i < 4; i++)
{
if (CurrentSpeed > 5 && Vector3.Angle(transform.forward, Rigidbody.velocity) < 50f)
{
WheelColliders[i].brakeTorque = BrakeTorque * footbrake;
}
else if (footbrake > 0)
{
WheelColliders[i].brakeTorque = 0f;
WheelColliders[i].motorTorque = -ReverseTorque * footbrake;
}
}
}
We can't just guess at the problem. Post the relevant code so people can give informed answers.
Edit: This is a bit nit-picky, but please make sure it's just the relevant code, not the entire file. Where in that massive text dump is braking handled?
Edit 2: I actually looked through it, and I don't see any code that handles input, acceleration, or braking.
This may help:
void Internal$$anonymous$$ove(float steering, float accel, float footbrake, float handbrake)
{
if (WheelColliders[0])
{
for (int i = 0; i < 4; i++)
{
Quaternion quat;
Vector3 position;
WheelColliders[i].GetWorldPose(out position, out quat);
Wheel$$anonymous$$eshes[i].transform.position = position;
Wheel$$anonymous$$eshes[i].transform.rotation = quat;
if ((i == 0) || (i == 2))
{
//Wheel$$anonymous$$eshes [i].transform.Rotate (180 * Vector3.up);
}
//Wheel$$anonymous$$eshes [i].transform.localPosition = Wheel$$anonymous$$eshLocalPositions[i];
}
//clamp input values
steering = $$anonymous$$athf.Clamp(steering, -1, 1);
AccelInput = accel = $$anonymous$$athf.Clamp(accel, 0, 1);
BrakeInput = footbrake = -1 * $$anonymous$$athf.Clamp(footbrake, -1, 0);
handbrake = $$anonymous$$athf.Clamp(handbrake, 0, 1);
//Set the steer on the front wheels.
//Assu$$anonymous$$g that wheels 0 and 1 are the front wheels.
SteerAngle = steering * $$anonymous$$aximumSteerAngle;
WheelColliders[0].steerAngle = SteerAngle;
WheelColliders[1].steerAngle = SteerAngle;
HandleSteerHelper();
ApplyDrive(accel, footbrake);
CapSpeed();
//Set the handbrake.
//Assu$$anonymous$$g that wheels 2 and 3 are the rear wheels.
//if (handbrake > 0f)
{
var hbTorque = handbrake * $$anonymous$$axHandbrakeTorque;
WheelColliders[2].brakeTorque = hbTorque;
WheelColliders[3].brakeTorque = hbTorque;
}
CalculateRevs();
GearChanging();
AddDownForce();
CheckForWheelSpin();
HandleTractionControl();
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612105739im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
UI Buttons working in editor but not in mobile 0 Answers
Can't Enable/Disable Unity CrossPlatformInput in runtime ? 1 Answer
How do I make a "move pad" on the screen? (Mobile) 1 Answer
is possible press 2 buttons at the same time Mobile touch? 0 Answers
Detect if running on mobile vs desktop 2 Answers