using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Serialization; public class BikeAnimation : MonoBehaviour { #region Variables [Header("Wheels - rotating around center")] public GameObject rearWheel; public GameObject frontWheel; [Header("Other with defined rotation axis")] public Rotatable crankSet; public Rotatable fork; [Header("Parameters")] public float wheelCircumference = 2.096f; public float defaultCadence = 80; private BicycleController bicycleController; private readonly Dictionary initialPositions = new Dictionary(); private readonly Dictionary initialRotations = new Dictionary(); #endregion // Start is called before the first frame update void Start() { bicycleController = GetComponentInParent(); initialPositions[crankSet] = crankSet.gameObject.transform.localPosition; initialPositions[fork] = fork.gameObject.transform.localPosition; initialRotations[crankSet] = crankSet.gameObject.transform.localRotation; initialRotations[fork] = fork.gameObject.transform.localRotation; } void Update() { var cadence = BikeSensorData.Instance.PowermeterData?.InstantaneousCadence ?? defaultCadence; //rpm var cadenceAngle = cadence / 60 * 360 * Time.deltaTime; //rps * 360 deg for one round RotateWheels(); RotateAroundDefinedAxis(fork, bicycleController.CurrentSteerAngle); RotateAroundDefinedAxis(crankSet, cadenceAngle, false); } private void RotateWheels() { var speed = bicycleController.rigidBody.velocity.magnitude; var rps = speed / wheelCircumference; var angle = rps * Time.deltaTime; //TODO: only works for this specific model rearWheel.transform.RotateAround(rearWheel.transform.position, -rearWheel.transform.right, angle); frontWheel.transform.RotateAround(frontWheel.transform.position, -frontWheel.transform.right, angle); } private void RotateAroundDefinedAxis(Rotatable rotatable, float angle, bool resetBeforeRotate = true) { if (resetBeforeRotate) { rotatable.gameObject.transform.localPosition = initialPositions[rotatable]; rotatable.gameObject.transform.localRotation = initialRotations[rotatable]; } Vector3 axis; if (rotatable.rotateAxis == RotateAxis.Up) axis = rotatable.rotateAround.up; else if (rotatable.rotateAxis == RotateAxis.Forward) axis = rotatable.rotateAround.forward; else axis = rotatable.rotateAround.right; fork.gameObject.transform.RotateAround(rotatable.rotateAround.position, axis, angle); } //rotates the meshes void RotateObject(GameObject obj, float multiplier) { obj.transform.Rotate( Time.deltaTime * bicycleController.rigidBody.velocity.magnitude * (360f / 12f) * multiplier, 0, 0); //obj.transform.Rotate(Time.deltaTime * rotSpeed * (360f / oneRotationSpeed) * multiplier, 0, 0); } }