using System.Collections; using System.Collections.Generic; using UnityEngine; public class BicycleController : MonoBehaviour { [Header ("GameObjects")] //public GameObject rearWheel; public GameObject frontWheel; //public GameObject crank; //public GameObject pedalL; //public GameObject pedalR; //public GameObject fork; public Transform centerOfMass; [Header("Values")] public float oneRotationSpeed = 2.7f; public float crankMultiplier = 2f; public List axleInfos; // the information about each individual axle public float maxMotorTorque = 12f; // maximum torque the motor can apply to wheel public float maxSteeringAngle = 5f; // maximum steer angle the wheel can have [Range(0,1)] public float relativeLeanAmount = 0.01f; public Transform leftWheels; public Transform rightWheels; private float currentSteerAngle = 0f; private float currentSpeed = 0f; private float currentLeaningAngle = 0f; public float rotSpeed = 10; private Vector3[] wheelPositions; public Rigidbody rb; private Quaternion startForkRot; private Vector3 upDirection = Vector3.up; // Start is called before the first frame update void Start() { //rb = GetComponent(); rb.centerOfMass = centerOfMass.localPosition; //startForkRot = fork.transform.localRotation; wheelPositions = new Vector3[axleInfos.Count]; for (int i = 0; i < axleInfos.Count; i++) { wheelPositions[i] = axleInfos[i].wheel.center; } } // Update is called once per frame void Update() { RotateMeshes(); //RotateFork(); Debug.Log("rotation: " + currentSteerAngle); } public void FixedUpdate() { ApplyWheelForce(); Lean(); //RotateStraight(); } void RotateMeshes() { //RotateObject(crank, 1); //RotateObject(pedalL, -1); //RotateObject(pedalR, -1); //RotateObject(rearWheel, crankMultiplier); RotateObject(frontWheel, crankMultiplier); } /*void RotateFork() { fork.transform.localRotation = startForkRot; fork.transform.RotateAround(fork.transform.position, fork.transform.up, maxSteeringAngle * rotationValue); }*/ void Lean() { upDirection = Vector3.Normalize(Vector3.up + transform.right * (maxSteeringAngle * relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude) / 100); } void ApplyWheelForce() { float motor = maxMotorTorque; float steering = maxSteeringAngle * currentSteerAngle; leftWheels.localPosition = - Vector3.up * (relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude); rightWheels.localPosition = Vector3.up * (relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude); //rb.velocity = new Vector3(currentSpeed, rb.velocity.y, rb.velocity.z); foreach (AxleInfo axleInfo in axleInfos) { if (axleInfo.steering) { axleInfo.wheel.steerAngle = steering; } if (axleInfo.motor && rb.velocity.magnitude < currentSpeed) { axleInfo.wheel.motorTorque = motor; } else if(axleInfo.motor) { axleInfo.wheel.motorTorque = 0; } } } public void SetSpeed(float speed) { currentSpeed = speed; } public void SetLeaningAngle(float angle) { currentLeaningAngle = angle; } public void SetSteeringAngle(float angle) { currentSteerAngle = angle; } //rotates the meshes void RotateObject(GameObject obj, float multiplier) { obj.transform.Rotate(Time.deltaTime * rb.velocity.magnitude * (360f / oneRotationSpeed) * multiplier, 0, 0); //obj.transform.Rotate(Time.deltaTime * rotSpeed * (360f / oneRotationSpeed) * multiplier, 0, 0); } } [System.Serializable] public class AxleInfo { public WheelCollider wheel; public bool motor; // is this wheel attached to motor? public bool steering; // does this wheel apply steer angle? }