- Home /
Physics, Force, Racing, and (Fixed)Update.
This may be quite a loaded question, and I'll do my best to comment the code in order to get across clearly what I am trying to accomplish.
This code here is supposed to drive my Ship forward. This project will become a mobile racing game that will eventually support Multiplayer. The problems I am having are as follows:
1) Choppy Force movement. I've messed with Update vs. FixedUpdate and neither have been able to supply me with a smooth fluid forward movement. I swear when I quit last night it was practically perfect, but this morning it is choppy and nasty. It steps forward regardless of FixedUpdate or Update. I have tried changing the FixedUpdate interval from .02 to .005 even.
2) The movement becomes ULTRA fluid once I remove my fingers from the screen, aka when there is no force being added to the ship.
3) Any wisdom on using Update vs. FixedUpdate for racing? I feel like FixedUpdate is necessary because the Update function will allow faster mobile devices to travel quicker, right?
using UnityEngine;
using System.Collections;
public class ShipController : MonoBehaviour {
public float basePower = 60.0F;
public float baseBoostSpeed = 100.0F;
public float baseBrakeSpeed = 25.0F;
public float baseBrakeDrag = 1.35F;
public float baseDrag = 0.75F;
public float baseHandling = 50.0F;
public GameObject Ship;
float regionWidth = Screen.width / 2;
Vector3 still = Vector3.zero;
bool first = true;
float[] throttleCoords = new float[4];
float brakeTime = 0.0F;
float speed = Mathf.Clamp(0.0F, 0, Mathf.Infinity);
void FixedUpdate(){
int fingers = Input.touchCount; // cache touchCount in q
Vector3 movement = Ship.rigidbody.GetPointVelocity(transform.position);
if (fingers == 1){ // if one finger only...
speed = basePower;
print(speed);
float touchPoint = Input.mousePosition.x;
if (touchPoint < regionWidth & movement == still) { // rotate left
clearDriveData(fingers, speed);
turnShip("left");
}
else if (touchPoint < (regionWidth * 2) & movement == still){ // rotate right
clearDriveData(fingers, speed);
turnShip("right");
}
else if (touchPoint < regionWidth) { //carry force into left turn
clearDriveData(fingers, speed);
turnShip("left");
moveShip("turn", speed);
}
else if (touchPoint < regionWidth * 2) { //carry force into right turn
clearDriveData(fingers, speed);
turnShip("right");
moveShip("turn", speed);
}
}
if (fingers > 1){ // if two fingers, move the ship forward
speed = basePower;
speed = boostCheck(speed);
moveShip(null, speed);
if (first) {
createThrottleCoords();
}
}
if (fingers == 0) {
speed = basePower;
clearDriveData(fingers, speed);
}
}
void turnShip(string direction) {
if (direction.Equals("right")) {
Ship.transform.Rotate(Vector3.up * baseHandling * Time.deltaTime);
}
if (direction.Equals("left")) {
Ship.transform.Rotate(Vector3.up * -baseHandling * Time.deltaTime);
}
}
void moveShip(string instructions, float speed){
if (instructions == null) {
Ship.rigidbody.AddForce(transform.forward * speed);
}
else if (instructions.Equals("turn")) { //cut speed for turning
Ship.rigidbody.AddForce(transform.forward * (speed / 3));
}
}
void createThrottleCoords() { // creates a set of coordinates used to determine boost or braking mechanism
float firstFinger = Input.GetTouch(0).position.y;
float secondFinger = Input.GetTouch(1).position.y;
throttleCoords[0] = firstFinger;
throttleCoords[1] = secondFinger;
first = false;
print(firstFinger);
print(secondFinger);
foreach (object x in throttleCoords) {
print(x);
}
}
void clearDriveData(int fingers, float speed) { //reset values
float[] throttleCoords = new float[4];
if (fingers != 2) {
resetSpeed(speed);
}
first = true;
}
void resetSpeed(float speed) {
speed = basePower;
Ship.rigidbody.drag = baseDrag;
}
float boostCheck(float speed) {
float newFirstFinger = Input.GetTouch(0).position.y;
float newSecondFinger = Input.GetTouch(1).position.y;
throttleCoords[2] = newFirstFinger;
throttleCoords[3] = newSecondFinger;
float boostSetA = throttleCoords[2] - throttleCoords[0];
float boostSetB = throttleCoords[3] - throttleCoords[1];
float brakeSetA = throttleCoords[0] - throttleCoords[2];
float brakeSetB = throttleCoords[1] - throttleCoords[3];
if (boostSetA > 75 & boostSetB > 75) {
print("BOOOOOSTING");
speed = baseBoostSpeed;
print(speed);
return speed;
}
else if (brakeSetA > 25 & brakeSetB > 25) {
Ship.rigidbody.drag = baseBrakeDrag;
brakeTime += Time.fixedDeltaTime;
print(brakeTime);
float brakeStrength = (brakeSetA + brakeSetB)/2;
print("Braking");
speed = Mathf.Clamp(speed - (brakeStrength * brakeTime), 0, Mathf.Infinity);
print(speed);
return speed;
}
else {
brakeTime = 0.0F;
resetSpeed(speed);
print("Nope");
return speed;
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613085844im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
FixedUpdate vs. Update for instantaneous ForceMode's 1 Answer
Slow motion all but one - yet another round, hopefully the last 6 Answers
2D physics jump issue. 1 Answer
Climb animation in Update or FixedUpdate or LateUpdate?, 1 Answer
Play method only ONCE when detected by the update function 3 Answers