void FixedUpdate() { float steer1d = 0; Vector2 steer2d = Vector2.zero; float acc = 0; float brake = 0; if (playerControlled) { DrivingActions actions = input.GetDrivingActions(); steer1d = actions.steer1d; steer2d = actions.steer2d; acc = actions.acc; brake = actions.brake; } else if (ai != null) { DrivingActions actions = ai.GetDrivingActions(); steer1d = actions.steer1d; acc = actions.acc; } bool movingForward = Vector2.Dot(body.velocity, transform.up) > 0; // get the engine force for each powered wheel float engine = 0; if (acc > 0) { engine = engineAcc * acc; } else if (acc < 0) { engine = (movingForward ? engineBrk : engineRev) * acc; } // get the desired wheel angle and the closest angle we can get to it in one frame float targetWheelAngle = steer1d * maxWheelAngle; if (steer2d.magnitude > 0) { float vehicleAngleDiff = Vector2.SignedAngle(steer2d, transform.up * Mathf.Sign(acc)); targetWheelAngle = Mathf.Clamp(vehicleAngleDiff, -maxWheelAngle, maxWheelAngle) * Mathf.Sign(acc); steer1d = targetWheelAngle / maxWheelAngle; } wheelAngle += Mathf.Clamp(targetWheelAngle - wheelAngle, -wheelAngleVelocity, wheelAngleVelocity); foreach (Wheel wheel in wheels) { Rigidbody2D wheelBody = wheel.obj.GetComponent <Rigidbody2D>(); // set the rotation(angle) for the rotatable wheels if (wheel.rotatable) { float angleDiff = wheelAngle - GetCurrentAngle(wheel.obj.transform); HingeJoint2D joint = wheel.obj.GetComponent <HingeJoint2D>(); JointMotor2D motor = joint.motor; if (Mathf.Abs(angleDiff) > .01) { motor.motorSpeed = wheelMotorSpeed * Mathf.Sign(angleDiff); joint.motor = motor; } else if (motor.motorSpeed != 0) { motor.motorSpeed = 0; joint.motor = motor; } // wheel.transform.Rotate(new Vector3(0, 0, currentAngle - wheelAngle)); // prevent random wheel joint physics wheelBody.angularVelocity = 0; } // apply engine force if (wheel.powered) { wheelBody.AddRelativeForce(new Vector2(0, engine)); } Vector2 localWheelVelocity = transform.InverseTransformVector(wheelBody.velocity); // add rolling resistance Vector2 rollingVector = new Vector2(0, localWheelVelocity.y) * -rollingResistance; body.AddRelativeForce(rollingVector); // drawVector(wheel.transform, transform.rotation * rollingVector, Color.red); // add handbrake resistance if (brake == 1 && wheel.handbrake) { Vector2 brakeVector = new Vector2(0, localWheelVelocity.y) * -brakeResistance; wheelBody.AddRelativeForce(brakeVector); // drawVector(wheel.transform, transform.rotation * brakeVector, Color.magenta); } // kill sideways speed of wheel KillSidewaysSpeed(wheel.obj); } // kill sideways speed of car KillSidewaysSpeed(gameObject); // add extra torque when steering, to make up for angular drag float torque = (movingForward ? -1 : 1) * steer1d * (Mathf.Min(steerTorque * body.velocity.magnitude, maxSteerTorque) + (brake * brakeTorque * body.velocity.magnitude)); body.AddTorque(torque); // prevent excess sliding if (body.velocity.magnitude <= 0.2 && acc == 0) { body.velocity = Vector2.zero; } // angular friction when not steering if (wheelAngle == 0) { body.angularVelocity -= Mathf.Sign(body.angularVelocity) * torqueDamp; } // add air resistance Vector2 airVector = body.velocity * body.velocity.magnitude * -airResistance; body.AddForce(airVector); // drawVector(transform, airVector, Color.blue); // Debug.Log(body.velocity.magnitude); // drawVector(transform, body.velocity, Color.green); }
void FixedUpdate() { float acc = 0; float steer = 0; float brake = 0; if (playerControlled) { acc = Input.GetAxisRaw("Vertical"); // up: 1, down: -1 steer = Input.GetAxisRaw("Horizontal"); // left: -1, right: 1 brake = Input.GetAxisRaw("Handbrake"); } else if (ai != null) { DrivingActions actions = ai.GetDrivingActions(); acc = actions.acc; steer = actions.steer; } bool movingForward = Vector2.Dot(body.velocity, transform.up) > 0; // get the engine force for each powered wheel float engine = 0; if (acc > 0) { engine = engineAcc * acc; } else if (acc < 0) { engine = (movingForward ? engineBrk : engineRev) * acc; } steerDir += Mathf.Clamp((steer * maxWheelAngle) - steerDir, -wheelAngleVelocity, wheelAngleVelocity); foreach (Wheel wheel in wheels) { Rigidbody2D wheelBody = wheel.obj.GetComponent <Rigidbody2D>(); // set the rotation(angle) for the rotatable wheels if (wheel.rotatable) { float currentAngle = GetCurrentAngle(wheel.obj.transform); float angleDiff = steerDir - currentAngle; HingeJoint2D joint = wheel.obj.GetComponent <HingeJoint2D>(); JointMotor2D motor = joint.motor; if (Mathf.Abs(angleDiff) > .01) { motor.motorSpeed = wheelMotorSpeed * Mathf.Sign(angleDiff); joint.motor = motor; } else if (motor.motorSpeed != 0) { motor.motorSpeed = 0; joint.motor = motor; } // wheel.transform.Rotate(new Vector3(0, 0, currentAngle - steerDir)); // prevent random wheel joint physics wheelBody.angularVelocity = 0; } // apply engine force if (wheel.powered) { wheelBody.AddRelativeForce(new Vector2(0, engine)); } Vector2 localWheelVelocity = transform.InverseTransformVector(wheelBody.velocity); // add rolling resistance Vector2 rollingVector = new Vector2(0, localWheelVelocity.y) * -rollingResistance; body.AddRelativeForce(rollingVector); // drawVector(wheel.transform, transform.rotation * rollingVector, Color.red); // add handbrake resistance if (brake == 1 && wheel.handbrake) { Vector2 brakeVector = new Vector2(0, localWheelVelocity.y) * -brakeResistance; wheelBody.AddRelativeForce(brakeVector); // drawVector(wheel.transform, transform.rotation * brakeVector, Color.magenta); } // kill sideways speed of wheel KillSidewaysSpeed(wheel.obj); } // kill sideways speed of car KillSidewaysSpeed(gameObject); // add extra torque when steering, to make up for angular drag float torque = (movingForward ? -1 : 1) * steer * (Mathf.Min(steerTorque * body.velocity.magnitude, maxSteerTorque) + (brake * brakeTorque * body.velocity.magnitude)); body.AddTorque(torque); // prevent excess sliding if (body.velocity.magnitude <= 0.2 && acc == 0) { body.velocity = Vector2.zero; } // angular friction when not steering if (steerDir == 0) { body.angularVelocity -= Mathf.Sign(body.angularVelocity) * torqueDamp; } // add air resistance Vector2 airVector = body.velocity * body.velocity.magnitude * -airResistance; body.AddForce(airVector); // drawVector(transform, airVector, Color.blue); // Debug.Log(body.velocity.magnitude); // drawVector(transform, body.velocity, Color.green); }