Browse Source

Cleaner BicycleController + Leaning + KeyboardController

wwdmbvbb 3 years ago
parent
commit
bb715f891e

+ 4 - 3
.idea/.idea.VR Cycling/.idea/indexLayout.xml

@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ContentModelUserStore">
-    <attachedFolders />
+    <attachedFolders>
+      <Path>../../Users/marce/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.test-framework@1.1.18</Path>
+    </attachedFolders>
     <explicitIncludes>
       <Path>Library/PackageCache/com.autodesk.fbx@3.1.0-preview.2</Path>
       <Path>Library/PackageCache/com.unity.collab-proxy@1.2.16</Path>
@@ -20,16 +22,15 @@
       <Path>Library/PackageCache/com.unity.xr.openvr.standalone@2.0.5</Path>
       <Path>Packages</Path>
       <Path>ProjectSettings</Path>
-      <Path>../../Users/marce/AppData/Local/Unity/cache/packages/packages.unity.com/com.unity.test-framework@1.1.18</Path>
     </explicitIncludes>
     <explicitExcludes>
       <Path>.git</Path>
       <Path>.idea</Path>
+      <Path>Docu</Path>
       <Path>External</Path>
       <Path>Integrations</Path>
       <Path>Library</Path>
       <Path>Logs</Path>
-      <Path>Temp</Path>
       <Path>obj</Path>
     </explicitExcludes>
   </component>

+ 3 - 0
Assembly-CSharp.csproj

@@ -255,7 +255,10 @@
      <Compile Include="Assets\Scripts\ANT+\PowerMeterReceiver.cs" />
      <Compile Include="Assets\Scripts\ANT+\SpeedSensorReceiver.cs" />
      <Compile Include="Assets\Scripts\BicyleController\AntSetup.cs" />
+     <Compile Include="Assets\Scripts\BicyleController\BicycleController - Copy.cs" />
      <Compile Include="Assets\Scripts\BicyleController\BicycleController.cs" />
+     <Compile Include="Assets\Scripts\BicyleController\KeyboardBikeController.cs" />
+     <Compile Include="Assets\Scripts\BicyleController\WheelConfig.cs" />
      <Compile Include="Assets\Scripts\HrDisplay.cs" />
      <Compile Include="Assets\Scripts\Polar\PolarAccData.cs" />
      <Compile Include="Assets\Scripts\Polar\PolarListener.cs" />

+ 89 - 46
Assets/Scenes/MainScene.unity

@@ -6574,7 +6574,7 @@ Transform:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 317568724}
   m_LocalRotation: {x: 1.2246469e-16, y: -0, z: -1.2246469e-16, w: 1}
-  m_LocalPosition: {x: 0.009263754, y: -0.3948611, z: 0.983485}
+  m_LocalPosition: {x: 0, y: -0.3948611, z: 0.983485}
   m_LocalScale: {x: 1, y: 0.973, z: 1}
   m_Children: []
   m_Father: {fileID: 806528343}
@@ -10184,6 +10184,7 @@ GameObject:
   m_Component:
   - component: {fileID: 495763388}
   - component: {fileID: 495763391}
+  - component: {fileID: 495763395}
   - component: {fileID: 495763390}
   - component: {fileID: 495763389}
   - component: {fileID: 495763392}
@@ -10204,7 +10205,7 @@ Transform:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 495763387}
   m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
-  m_LocalPosition: {x: -28.88, y: 0, z: -0.000000059604645}
+  m_LocalPosition: {x: 3.2, y: 0, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children:
   - {fileID: 1445554698}
@@ -10218,7 +10219,7 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 495763387}
-  m_Enabled: 1
+  m_Enabled: 0
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 7047fa022a2846339e78755e09e91fda, type: 3}
   m_Name: 
@@ -10233,7 +10234,7 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 495763387}
-  m_Enabled: 1
+  m_Enabled: 0
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: b0229a2c3c97c2944b6be12287119878, type: 3}
   m_Name: 
@@ -10260,32 +10261,23 @@ MonoBehaviour:
   rearWheel: {fileID: 317568724}
   frontWheel: {fileID: 467365019}
   crank: {fileID: 1053385332}
-  bike: {fileID: 1445554695}
+  pedalL: {fileID: 0}
+  pedalR: {fileID: 0}
   fork: {fileID: 1406744202}
+  bike: {fileID: 1445554695}
   centerOfMass: {fileID: 1344013520}
-  controller: 0
+  rigidBody: {fileID: 1445554697}
+  wheelConfig:
+    frontLeft: {fileID: 1485411601}
+    frontRight: {fileID: 731889964}
+    rearLeft: {fileID: 366287529}
+    rearRight: {fileID: 1990711643}
+  offsetCollidersFromWheel: 0.25
   oneRotationSpeed: 2.7
   crankMultiplier: 2
-  axleInfos:
-  - wheel: {fileID: 366287529}
-    motor: 1
-    steering: 0
-  - wheel: {fileID: 1990711643}
-    motor: 1
-    steering: 0
-  - wheel: {fileID: 1485411601}
-    motor: 0
-    steering: 0
-  - wheel: {fileID: 731889964}
-    motor: 0
-    steering: 1
   maxMotorTorque: 1000
   maxSteeringAngle: 5
   relativeLeanAmount: 0.01
-  leftWheels: {fileID: 1994511757}
-  rightWheels: {fileID: 982685521}
-  rotSpeed: 10
-  rb: {fileID: 1445554697}
 --- !u!114 &495763392
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -10327,11 +10319,31 @@ MonoBehaviour:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 495763387}
-  m_Enabled: 1
+  m_Enabled: 0
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 191e6394491f45a0affa3a8a9b152ffc, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+--- !u!114 &495763395
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 495763387}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 512442fc2be9462480455b716456ef5d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  torqueIncreasePerSecond: 10
+  brakeTorqueIncreasePerSecond: 10
+  leaningAngleIncreasePerSecond: 8
+  steeringAngleIncreasePerSecond: 4
+  maxMotorTorque: 400
+  maxBrakeTorque: 600
+  maxLeaningAngle: 35
+  maxSteeringAngle: 70
 --- !u!1001 &503746343
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -16446,7 +16458,7 @@ Transform:
   - {fileID: 1053385333}
   - {fileID: 1104579083}
   m_Father: {fileID: 1445554698}
-  m_RootOrder: 2
+  m_RootOrder: 3
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1001 &811670814
 PrefabInstance:
@@ -30274,11 +30286,12 @@ Transform:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1445554695}
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: -0, y: 0.55, z: 31.44}
+  m_LocalPosition: {x: 0.0004502861, y: 0.54999, z: 5.820766e-11}
   m_LocalScale: {x: 0.5000001, y: 0.5, z: 0.5000001}
   m_Children:
   - {fileID: 1773753918}
   - {fileID: 1344013520}
+  - {fileID: 1817007193}
   - {fileID: 806528343}
   - {fileID: 1566254955}
   m_Father: {fileID: 495763388}
@@ -38590,6 +38603,36 @@ Transform:
     type: 3}
   m_PrefabInstance: {fileID: 1124400309}
   m_PrefabAsset: {fileID: 0}
+--- !u!1 &1817007192
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1817007193}
+  m_Layer: 9
+  m_Name: Bottom
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1817007193
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1817007192}
+  m_LocalRotation: {x: 9.3108976e-10, y: 2.0792095e-11, z: -0.0000000018626449, w: 1}
+  m_LocalPosition: {x: 0, y: -1.0378, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1445554698}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1001 &1817035781
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -42116,32 +42159,23 @@ MonoBehaviour:
   rearWheel: {fileID: 5876215622878374135}
   frontWheel: {fileID: 5538839489649729767}
   crank: {fileID: 1313009432}
-  bike: {fileID: 5134572704663073518}
+  pedalL: {fileID: 0}
+  pedalR: {fileID: 0}
   fork: {fileID: 201399530}
+  bike: {fileID: 5134572704663073518}
   centerOfMass: {fileID: 2217413905054478849}
-  controller: 1
+  rigidBody: {fileID: 2984639160424219301}
+  wheelConfig:
+    frontLeft: {fileID: 0}
+    frontRight: {fileID: 0}
+    rearLeft: {fileID: 0}
+    rearRight: {fileID: 0}
+  offsetCollidersFromWheel: 0
   oneRotationSpeed: 2.7
   crankMultiplier: 2
-  axleInfos:
-  - wheel: {fileID: 6090953275851904658}
-    motor: 1
-    steering: 0
-  - wheel: {fileID: 6058664054282743039}
-    motor: 0
-    steering: 1
-  - wheel: {fileID: 5445233383830585977}
-    motor: 1
-    steering: 0
-  - wheel: {fileID: 4568543931324426609}
-    motor: 0
-    steering: 1
   maxMotorTorque: 5000
   maxSteeringAngle: 5
   relativeLeanAmount: 0.01
-  leftWheels: {fileID: 8158359824615092702}
-  rightWheels: {fileID: 6678954028052817760}
-  rotSpeed: 10
-  rb: {fileID: 2984639160424219301}
 --- !u!1001 &1941347970
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -42455,6 +42489,15 @@ PrefabInstance:
       propertyPath: m_Layer
       value: 8
       objectReference: {fileID: 0}
+    - target: {fileID: 107946, guid: dc06161b6d97feb419f45f03b62e14b9, type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 107946, guid: dc06161b6d97feb419f45f03b62e14b9, type: 3}
+      propertyPath: m_Icon
+      value: 
+      objectReference: {fileID: 419385456094870383, guid: 0000000000000000d000000000000000,
+        type: 0}
     - target: {fileID: 109154, guid: dc06161b6d97feb419f45f03b62e14b9, type: 3}
       propertyPath: m_Layer
       value: 8
@@ -42549,7 +42592,7 @@ PrefabInstance:
       objectReference: {fileID: 0}
     - target: {fileID: 447954, guid: dc06161b6d97feb419f45f03b62e14b9, type: 3}
       propertyPath: m_RootOrder
-      value: 3
+      value: 4
       objectReference: {fileID: 0}
     - target: {fileID: 447954, guid: dc06161b6d97feb419f45f03b62e14b9, type: 3}
       propertyPath: m_LocalEulerAnglesHint.x

+ 1 - 1
Assets/Scripts/BicyleController/AntSetup.cs

@@ -41,7 +41,7 @@ public class AntSetup : MonoBehaviour
     void Update()
     {
         //transform.Translate(Vector3.forward * (Time.deltaTime * (speedSensorReceiver?.Speed ?? 0)));
-        bicycleController.SetSpeed(speedSensorReceiver?.Speed ?? 0);
+        //bicycleController.SetSpeed(speedSensorReceiver?.Speed ?? 0);
         //bicycleController.SetTorque(powerMeterReceiver?.CrankTorque ?? 0); //TODO crank to wheel torque;
         if (speedDisplayAvailable)
         {

+ 198 - 0
Assets/Scripts/BicyleController/BicycleController - Copy.cs

@@ -0,0 +1,198 @@
+/*using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using Valve.VR.InteractionSystem;
+
+public enum Controller
+{
+    Sensors,
+    SpeedSensorOnly,
+    Keyboard,
+    KeyboardSpeedPolarSteer
+}
+
+public class BicycleController : MonoBehaviour
+{
+    [Header("GameObjects")] public GameObject rearWheel;
+    public GameObject frontWheel;
+    public GameObject crank;
+
+    public GameObject bike;
+
+    //public GameObject pedalL;
+    //public GameObject pedalR;
+    public GameObject fork;
+    public Transform centerOfMass;
+
+    [Header("Configuration")] public Controller controller = Controller.Sensors;
+
+    [Header("Values")] public float oneRotationSpeed = 2.7f;
+    public float crankMultiplier = 2f;
+    public List<AxleInfo> axleInfos;
+    public float maxMotorTorque = 1000;
+    public float maxSteeringAngle = 5f;
+    [Range(0, 1)] public float relativeLeanAmount = 0.01f;
+    public Transform leftWheels;
+    public Transform rightWheels;
+
+    private float currentSteerAngle = 0f;
+    private float desiredSpeed = 0f;
+    private float currentLeaningAngle = 0f;
+    public float rotSpeed = 10;
+
+    private Vector3[] wheelPositions;
+    public Rigidbody rb;
+    private Quaternion startForkRot;
+    private Vector3 upDirection = Vector3.up;
+
+    private float calculatedWheelSpeed;
+
+    private float currentMotorTorque;
+
+    private readonly float maxSpeed = 11.111f;
+
+
+    // Start is called before the first frame update
+    void Start()
+    {
+        //rb = GetComponent<Rigidbody>();
+        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;
+        }
+    }
+
+    private void OnGUI()
+    {
+        GUI.TextField(new Rect(114, 10, 280, 20),
+            $"Wanted speed {(desiredSpeed * 3.6):n2} km/h; Current Speed {(rb.velocity.magnitude * 3.6):n2}");
+    }
+
+    // Update is called once per frame
+    void Update()
+    {
+        if (controller == Controller.Keyboard || controller == Controller.KeyboardSpeedPolarSteer)
+        {
+            desiredSpeed = Input.GetAxis("Vertical") * 4.3333f;
+        }
+
+        if (controller == Controller.Keyboard)
+        {
+            currentSteerAngle = Input.GetAxis("Horizontal") * maxSteeringAngle;
+        }
+
+        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 * currentSteerAngle);
+    }
+
+    void Lean()
+    {
+        upDirection = Vector3.Normalize(Vector3.up + transform.right *
+            (maxSteeringAngle * relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude) / 100);
+    }
+
+
+    void ApplyWheelForce()
+    {
+        ControlSteer(axleInfos.Where(a => a.steering).Select(a => a.wheel));
+        ControlTorque(axleInfos.Where(a => a.motor).Select(a => a.wheel));
+    }
+
+    private void ControlSteer(IEnumerable<WheelCollider> colliders)
+    {
+        float steering = maxSteeringAngle * currentSteerAngle * 0.2f;
+        leftWheels.localPosition = -Vector3.up * (relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude * 0.2f);
+        rightWheels.localPosition = Vector3.up * (relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude * 0.2f);
+        colliders.ForEach(c => c.steerAngle = steering);
+    }
+
+    private void ControlTorque(IEnumerable<WheelCollider> colliders)
+    {
+        var currentSpeed = rb.velocity.magnitude;
+        var speedDif = desiredSpeed - currentSpeed;
+        var ratio = speedDif / maxSpeed;
+        var torque = maxMotorTorque * ratio;
+        if (speedDif >= .1f) // 0.36 km/h
+        {
+            Debug.Log($"SpeedDif = {speedDif} -> applying Torque {torque} (Ratio: {ratio})");
+            colliders.ForEach(c =>
+            {
+                c.brakeTorque = 0;
+                c.motorTorque = torque;
+            });
+        }
+        else if (speedDif <= -.1f)
+        {
+            Debug.Log($"SpeedDif = {speedDif} -> applying brake Torque {torque} (Ratio: {ratio})");
+            colliders.ForEach(c =>
+            {
+                c.motorTorque = 0;
+                c.brakeTorque = -torque;
+            });
+        }
+    }
+
+
+    public void SetSpeed(float speed)
+    {
+        if (controller == Controller.Keyboard || controller == Controller.KeyboardSpeedPolarSteer) return;
+        desiredSpeed = speed;
+    }
+
+    public void SetLeaningAngle(float angle)
+    {
+        if (controller == Controller.Keyboard) return;t
+        currentLeaningAngle = angle;
+    }
+
+    public void SetSteeringAngle(float angle)
+    {
+        if (controller == Controller.Keyboard || controller == Controller.SpeedSensorOnly) return;
+        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?
+    }
+}*/

+ 3 - 0
Assets/Scripts/BicyleController/BicycleController - Copy.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 9075f70ff85744088a8b23a9ff0c0312
+timeCreated: 1606311992

+ 96 - 120
Assets/Scripts/BicyleController/BicycleController.cs

@@ -3,196 +3,172 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
+using UnityEngine.EventSystems;
+using UnityEngine.Serialization;
 using Valve.VR.InteractionSystem;
 
-public enum Controller
-{
-    Sensors,
-    SpeedSensorOnly,
-    Keyboard,
-    KeyboardSpeedPolarSteer
-}
 
 public class BicycleController : MonoBehaviour
 {
-    [Header("GameObjects")] public GameObject rearWheel;
+    [Header("Visible Game Objects")] public GameObject rearWheel;
     public GameObject frontWheel;
     public GameObject crank;
-
-    public GameObject bike;
-
-    //public GameObject pedalL;
-    //public GameObject pedalR;
+    public GameObject pedalL;
+    public GameObject pedalR;
     public GameObject fork;
-    public Transform centerOfMass;
+    public GameObject bike;
 
-    [Header("Configuration")] public Controller controller = Controller.Sensors;
+    [Header("Game Objects for Physics")] public Transform centerOfMass;
+    [FormerlySerializedAs("rb")] public Rigidbody rigidBody;
+    public WheelConfig wheelConfig;
 
-    [Header("Values")] public float oneRotationSpeed = 2.7f;
+    [Header("Values")] public float offsetCollidersFromWheel = 0.25f;
+    public float oneRotationSpeed = 2.7f;
     public float crankMultiplier = 2f;
-    public List<AxleInfo> axleInfos;
     public float maxMotorTorque = 1000;
     public float maxSteeringAngle = 5f;
     [Range(0, 1)] public float relativeLeanAmount = 0.01f;
-    public Transform leftWheels;
-    public Transform rightWheels;
 
-    private float currentSteerAngle = 0f;
-    private float desiredSpeed = 0f;
-    private float currentLeaningAngle = 0f;
-    public float rotSpeed = 10;
+    private WheelCollider[] allWheelColliders;
+
+
+    public float CurrentSteerAngle { get; set; } = 0f;
+
+    public float CurrentMotorTorque { get; set; } = 0f;
+
+    public float CurrentBrakeTorque { get; set; } = 0f;
+
+    public float CurrentLeaningAngle { get; set; } = 0f;
+
 
-    private Vector3[] wheelPositions;
-    public Rigidbody rb;
     private Quaternion startForkRot;
     private Vector3 upDirection = Vector3.up;
 
     private float calculatedWheelSpeed;
+    private float initialWheelColliderY;
 
-    private float currentMotorTorque;
 
-    private readonly float maxSpeed = 11.111f;
+    private void OnGUI()
+    {
+        GUI.TextField(new Rect(300, 10, 700, 40),
+            $"Motor Torque = {CurrentMotorTorque}; Brake Torque = {CurrentBrakeTorque}; Leaning Angle = {CurrentLeaningAngle}; Steering Angle = {CurrentSteerAngle}");
 
+    }
 
     // Start is called before the first frame update
     void Start()
     {
-        //rb = GetComponent<Rigidbody>();
-        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;
-        }
-    }
+        rigidBody.centerOfMass = centerOfMass.localPosition;
+        allWheelColliders = wheelConfig.AllWheels;
+        wheelConfig.AdjustToGameObjects(frontWheel.transform, rearWheel.transform, offsetCollidersFromWheel);
+        initialWheelColliderY = allWheelColliders[0].transform.localPosition.y;
 
-    private void OnGUI()
-    {
-        GUI.TextField(new Rect(114, 10, 280, 20),
-            $"Wanted speed {(desiredSpeed * 3.6):n2} km/h; Current Speed {(rb.velocity.magnitude * 3.6):n2}");
+        //startForkRot = fork.transform.localRotation; wheelPositions = new Vector3[wheelColliders.Count];
     }
 
-    // Update is called once per frame
     void Update()
     {
-        if (controller == Controller.Keyboard || controller == Controller.KeyboardSpeedPolarSteer)
-        {
-            desiredSpeed = Input.GetAxis("Vertical") * 4.3333f;
-        }
-
-        if (controller == Controller.Keyboard)
-        {
-            currentSteerAngle = Input.GetAxis("Horizontal") * maxSteeringAngle;
-        }
-
         RotateMeshes();
         //RotateFork();
-        Debug.Log("rotation: " + currentSteerAngle);
+        Debug.Log("rotation: " + CurrentSteerAngle);
     }
 
 
-    public void FixedUpdate()
+    void FixedUpdate()
     {
-        ApplyWheelForce();
+        ApplyColliderForces();
         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 * currentSteerAngle);
-    }
-
-    void Lean()
+    private void ApplyColliderForces()
     {
-        upDirection = Vector3.Normalize(Vector3.up + transform.right *
-            (maxSteeringAngle * relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude) / 100);
+        ControlSteer(new[] {wheelConfig.frontLeft, wheelConfig.frontRight});
+        ControlTorque(new[] {wheelConfig.rearLeft, wheelConfig.rearRight});
     }
 
-
-    void ApplyWheelForce()
+    private void ControlSteer(IEnumerable<WheelCollider> colliders)
     {
-        ControlSteer(axleInfos.Where(a => a.steering).Select(a => a.wheel));
-        ControlTorque(axleInfos.Where(a => a.motor).Select(a => a.wheel));
+        //float steering = maxSteeringAngle * CurrentSteerAngle * 0.2f;
+        //leftWheels.localPosition = -Vector3.up * (relativeLeanAmount * CurrentSteerAngle * rigidBody.velocity.magnitude * 0.2f);
+        //rightWheels.localPosition = Vector3.up * (relativeLeanAmount * CurrentSteerAngle * rigidBody.velocity.magnitude * 0.2f);
+        colliders.ForEach(c => c.steerAngle = CurrentSteerAngle);
     }
 
-    private void ControlSteer(IEnumerable<WheelCollider> colliders)
+    private void ControlTorque(IEnumerable<WheelCollider> colliders)
     {
-        float steering = maxSteeringAngle * currentSteerAngle * 0.2f;
-        leftWheels.localPosition = -Vector3.up * (relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude * 0.2f);
-        rightWheels.localPosition = Vector3.up * (relativeLeanAmount * currentSteerAngle * rb.velocity.magnitude * 0.2f);
-        colliders.ForEach(c => c.steerAngle = steering);
+        foreach (var c in colliders)
+        {
+            c.motorTorque = CurrentMotorTorque;
+            c.brakeTorque = CurrentBrakeTorque;
+        }
     }
 
-    private void ControlTorque(IEnumerable<WheelCollider> colliders)
+    private void Lean()
     {
-        var currentSpeed = rb.velocity.magnitude;
-        var speedDif = desiredSpeed - currentSpeed;
-        var ratio = speedDif / maxSpeed;
-        var torque = maxMotorTorque * ratio;
-        if (speedDif >= .1f) // 0.36 km/h
+        //reset all wheels to being centered
+        if (CurrentLeaningAngle == 0) //TODO: maybe add a threshold for leaning, e.g. < -0.05 and > 0.05 
         {
-            Debug.Log($"SpeedDif = {speedDif} -> applying Torque {torque} (Ratio: {ratio})");
-            colliders.ForEach(c =>
-            {
-                c.brakeTorque = 0;
-                c.motorTorque = torque;
-            });
+            //leaning left, left wheels up, right wheels down
+            ApplyOffsetToTransform(wheelConfig.frontLeft.transform, initialWheelColliderY);
+            ApplyOffsetToTransform(wheelConfig.rearLeft.transform, initialWheelColliderY);
+            ApplyOffsetToTransform(wheelConfig.frontRight.transform, initialWheelColliderY);
+            ApplyOffsetToTransform(wheelConfig.rearRight.transform, initialWheelColliderY);
         }
-        else if (speedDif <= -.1f)
+        //CurrentLeaningAngle < 0 -> leaning left, > 0 -> right
+        var leaningAbs = Mathf.Abs(CurrentLeaningAngle * Mathf.Deg2Rad);
+
+        //calculate offset for wheels; description Docu folder
+        //1.57079633 rad = 90 deg
+        var verticalOffset = offsetCollidersFromWheel * Mathf.Sin(leaningAbs) / Mathf.Sin(1.57079633f - leaningAbs);
+        var yPlusOffset = initialWheelColliderY + verticalOffset;
+        var yMinusOffset = initialWheelColliderY - verticalOffset;
+        
+        if (CurrentLeaningAngle < 0) //TODO: maybe add a threshold for leaning, e.g. < -0.05 and > 0.05 
         {
-            Debug.Log($"SpeedDif = {speedDif} -> applying brake Torque {torque} (Ratio: {ratio})");
-            colliders.ForEach(c =>
-            {
-                c.motorTorque = 0;
-                c.brakeTorque = -torque;
-            });
+            //leaning left, left wheels up, right wheels down
+            ApplyOffsetToTransform(wheelConfig.frontLeft.transform, yPlusOffset);
+            ApplyOffsetToTransform(wheelConfig.rearLeft.transform, yPlusOffset);
+            ApplyOffsetToTransform(wheelConfig.frontRight.transform, yMinusOffset);
+            ApplyOffsetToTransform(wheelConfig.rearRight.transform, yMinusOffset);
+        }
+        else if (CurrentLeaningAngle > 0)
+        {
+            //leaning right, right wheels up, left wheels down
+            ApplyOffsetToTransform(wheelConfig.frontLeft.transform, yMinusOffset);
+            ApplyOffsetToTransform(wheelConfig.rearLeft.transform, yMinusOffset);
+            ApplyOffsetToTransform(wheelConfig.frontRight.transform, yPlusOffset);
+            ApplyOffsetToTransform(wheelConfig.rearRight.transform, yPlusOffset);
         }
     }
 
-
-    public void SetSpeed(float speed)
+    private void ApplyOffsetToTransform(Transform t, float newY)
     {
-        if (controller == Controller.Keyboard || controller == Controller.KeyboardSpeedPolarSteer) return;
-        desiredSpeed = speed;
+        var oldPos = t.localPosition;
+        t.localPosition = new Vector3(oldPos.x, newY, oldPos.z);
     }
 
-    public void SetLeaningAngle(float angle)
+    private void RotateMeshes()
     {
-        if (controller == Controller.Keyboard) return;
-        currentLeaningAngle = angle;
+        //RotateObject(crank, 1);
+        //RotateObject(pedalL, -1);
+        //RotateObject(pedalR, -1);
+        RotateObject(rearWheel, crankMultiplier);
+        RotateObject(frontWheel, crankMultiplier);
     }
 
-    public void SetSteeringAngle(float angle)
+    private void RotateFork()
     {
-        if (controller == Controller.Keyboard || controller == Controller.SpeedSensorOnly) return;
-        currentSteerAngle = angle;
+        fork.transform.localRotation = startForkRot;
+        fork.transform.RotateAround(fork.transform.position, fork.transform.up, maxSteeringAngle * CurrentSteerAngle);
     }
 
+
     //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 * rigidBody.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?
-    }
 }

+ 76 - 0
Assets/Scripts/BicyleController/KeyboardBikeController.cs

@@ -0,0 +1,76 @@
+using System;
+using UnityEngine;
+
+
+public class KeyboardBikeController : MonoBehaviour
+{
+    private BicycleController bicycleController;
+
+    public float torqueIncreasePerSecond = 10f;
+    public float brakeTorqueIncreasePerSecond = 20f;
+    public float leaningAngleIncreasePerSecond = 2f;
+    public float steeringAngleIncreasePerSecond = 2.5f;
+
+    public float maxMotorTorque = 400f;
+    public float maxBrakeTorque = 600f;
+    public float maxLeaningAngle = 35f;
+    public float maxSteeringAngle = 70f;
+
+    private void Start()
+    {
+        bicycleController = GetComponent<BicycleController>();
+    }
+
+    private void Update()
+    {
+        if (Input.GetKey(KeyCode.T))
+        {
+            bicycleController.CurrentBrakeTorque = 0f;
+            bicycleController.CurrentMotorTorque += torqueIncreasePerSecond * Time.deltaTime;
+        }
+        else if (Input.GetKeyUp(KeyCode.T))
+        {
+            bicycleController.CurrentMotorTorque = 0f;
+        }
+
+        if (Input.GetKey(KeyCode.G))
+        {
+            bicycleController.CurrentMotorTorque = 0f;
+            bicycleController.CurrentBrakeTorque += brakeTorqueIncreasePerSecond * Time.deltaTime;
+        }
+        else if (Input.GetKeyUp(KeyCode.G))
+        {
+            bicycleController.CurrentBrakeTorque = 0f;
+        }
+
+        if (Input.GetKey(KeyCode.F))
+        {
+            bicycleController.CurrentSteerAngle -= steeringAngleIncreasePerSecond * Time.deltaTime;
+        }
+
+        if (Input.GetKey(KeyCode.H))
+        {
+            bicycleController.CurrentSteerAngle += steeringAngleIncreasePerSecond * Time.deltaTime;
+        }
+
+        if (Input.GetKeyUp(KeyCode.F) || Input.GetKeyUp(KeyCode.H))
+        {
+            bicycleController.CurrentSteerAngle = 0f;
+        }
+
+        if (Input.GetKey(KeyCode.R))
+        {
+            bicycleController.CurrentLeaningAngle -= leaningAngleIncreasePerSecond * Time.deltaTime;
+        }
+
+        if (Input.GetKey(KeyCode.Z))
+        {
+            bicycleController.CurrentLeaningAngle += leaningAngleIncreasePerSecond * Time.deltaTime;
+        }
+
+        if (Input.GetKeyUp(KeyCode.R) || Input.GetKeyUp(KeyCode.Z))
+        {
+            bicycleController.CurrentLeaningAngle = 0f;
+        }
+    }
+}

+ 3 - 0
Assets/Scripts/BicyleController/KeyboardBikeController.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 512442fc2be9462480455b716456ef5d
+timeCreated: 1606327260

+ 37 - 0
Assets/Scripts/BicyleController/WheelConfig.cs

@@ -0,0 +1,37 @@
+using UnityEngine;
+
+[System.Serializable]
+public class WheelConfig
+{
+    public WheelCollider frontLeft;
+    public WheelCollider frontRight;
+    public WheelCollider rearLeft;
+    public WheelCollider rearRight;
+
+    public WheelCollider[] AllWheels => new[] {frontLeft, frontRight, rearLeft, rearLeft};
+
+    public void AdjustToGameObjects(Transform frontWheel, Transform rearWheel, float offset)
+    {
+        var x0 = Vector3.one - Vector3.right;
+
+        var posFront = frontWheel.localPosition;
+        var newXLeftFront = posFront.x - offset;
+        var newXRightFront = posFront.x + offset;
+        
+        var posRear = rearWheel.localPosition;
+        var newXLeftRear = posRear.x - offset;
+        var newXRightRear = posRear.x + offset;
+        
+        SetNewX(frontLeft.transform, newXLeftFront);
+        SetNewX(frontRight.transform, newXRightFront);
+        SetNewX(rearLeft.transform, newXLeftRear);
+        SetNewX(rearRight.transform, newXRightRear);
+    }
+
+    private void SetNewX(Transform transform, float newX)
+    {
+        var position = transform.localPosition;
+        position = new Vector3(newX, position.y, position.z);
+        transform.localPosition = position;
+    }
+}

+ 11 - 0
Assets/Scripts/BicyleController/WheelConfig.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bbf3a62418f66184c9a1a86f3fa20edb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 1
Assets/Scripts/Polar/PolarListener.cs

@@ -28,7 +28,7 @@ public class PolarListener : MonoBehaviour
         //Debug.Log(data.Timestamp);
         rotation = data.Values[0].y / divisionValue;
         Debug.Log($"Rotate {data.Values[0].y} degrees");
-        bicycleController.SetSteeringAngle(-rotation);
+        //bicycleController.SetSteeringAngle(-rotation);
         //transform.RotateAround(transform.position, Vector3.forward, data.Values[0].y);
     }
 

BIN
Docu/Leaning_Bicyle.jpg


BIN
obj/Debug/Assembly-CSharp.csprojAssemblyReference.cache