This commit is contained in:
2025-05-13 03:19:28 +03:00
parent e2847b060d
commit 762dcf4524
784 changed files with 542617 additions and 2 deletions
+40
View File
@@ -0,0 +1,40 @@
using UnityEngine;
using System.Collections;
public class Accumulator : IElecticEnergySource {
public float voltage = 12.0f;
public float maxPower = 520.0f;
public override float Voltage {
get {
return voltage;
}
}
public override float MaxPower {
get {
return maxPower;
}
}
public override string Name {
get {
return "Accumulator";
}
}
public override string ShortDescription {
get {
return "Accumulator";
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 37417f8d68420ec4baa192c11dc66130
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+132
View File
@@ -0,0 +1,132 @@
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class AdvancedGizmo {
public static void DrawCircle(Vector3 center, Vector3 normal, float radius, Color color, int tesselation = 12, bool drawNormal = false, int diagonalCount = 0){
if (tesselation < 3) {
Debug.LogError("Invalid tesselation value! Should be >= 3");
}
Vector3 right = Vector3.right;
if (Mathf.Abs (Vector3.Dot (right, normal)) > 0.999f) {
right = Vector3.up;
}
Vector3 front = Vector3.Cross (right, normal).normalized;
Gizmos.color = color;
for(int i = 0; i < tesselation; ++i){
//Gizmos.DrawLine(
Gizmos.DrawLine(
center + Quaternion.AngleAxis((360.0f / tesselation) * (i + 0), normal) * front * radius,
center + Quaternion.AngleAxis((360.0f / tesselation) * (i + 1), normal) * front * radius
);
}
for (int i = 0; i < diagonalCount; ++i) {
float a1 = (180.0f / diagonalCount) * i;
float a2 = a1 + 180.0f;
Gizmos.DrawLine(
center + Quaternion.AngleAxis(a1, normal) * front * radius,
center + Quaternion.AngleAxis(a2, normal) * front * radius
);
}
}
public static void DrawGrid(Vector3 center, float width, float height, int wSections = 1, int hSections = 1){
Vector3 topLeft = new Vector3 (-width * 0.5f, 0, height * 0.5f);
Vector3 wStep = new Vector3 (width / wSections, 0, 0);
Vector3 hStep = new Vector3 (0, 0, -height / hSections);
//draw horizontal lines
for (int i = 0; i <= hSections; ++i) {
Vector3 p1 = topLeft + hStep * i + center;
Debug.DrawLine(p1, p1 + new Vector3(width, 0, 0));
}
//draw vertical lines
for (int i = 0; i <= hSections; ++i) {
Vector3 p1 = topLeft + wStep * i + center;
Debug.DrawLine(p1, p1 + new Vector3(0, 0, -height));
}
}
public delegate float fx(float x);
public static void Plot2D(fx func, Matrix4x4 tranfsorm, Vector3 center, Vector3 xAxis, Vector3 yAxis, float xLen, float xScale, float yScale, int sampleCount, Color color){
float xStep = xLen / (sampleCount - 1);
Vector3[] points = new Vector3[sampleCount];
for (int i = 0; i < sampleCount; ++i) {
float x1 = i * xStep;
float arg1 = (x1 / xLen) * xScale;
float y1 = func(arg1) * yScale;
points[i] = center + xAxis * x1 + yAxis * y1;
}
#if UNITY_EDITOR
Color backup = Handles.color;
Handles.matrix = tranfsorm;
Handles.color = color;
Handles.DrawPolyLine(points);
Handles.color = backup;
Handles.matrix = Matrix4x4.identity;
#endif
}
public static void DrawMesh(Vector3[] vertices, int[] indices, bool drawNormals){
for(int i = 0; i < indices.Length; i+=3){
Vector3 v0 = vertices[indices[i + 0]];
Vector3 v1 = vertices[indices[i + 1]];
Vector3 v2 = vertices[indices[i + 2]];
Debug.DrawLine(v0, v1);
Debug.DrawLine(v1, v2);
Debug.DrawLine(v2, v0);
if(drawNormals){
Vector3 center = (v0 + v1 + v2) / 3.0f;
Vector3 normal = Vector3.Cross((v1 - v0), (v2 - v0));
Debug.DrawRay(center, normal);
}
}
}
public static void DrawMesh(Vector3[] vertices, bool drawNormals){
for(int i = 0; i < vertices.Length; i+=3){
Vector3 v0 = vertices[i + 0];
Vector3 v1 = vertices[i + 1];
Vector3 v2 = vertices[i + 2];
Debug.DrawLine(v0, v1);
Debug.DrawLine(v1, v2);
Debug.DrawLine(v2, v0);
if(drawNormals){
Vector3 center = (v0 + v1 + v2) / 3.0f;
Vector3 normal = Vector3.Cross((v1 - v0), (v2 - v0));
Debug.DrawRay(center, normal);
}
}
}
public static void DrawTriangle(Vector3 v0, Vector3 v1, Vector3 v2, bool drawNormal){
Debug.DrawLine(v0, v1);
Debug.DrawLine(v1, v2);
Debug.DrawLine(v2, v0);
if(drawNormal){
Vector3 center = (v0 + v1 + v2) / 3.0f;
Vector3 normal = Vector3.Cross((v1 - v0), (v2 - v0));
Debug.DrawRay(center, normal);
}
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ffe24c9424a34e34784f84b7268ac367
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 9ea2979d086da60468850bad54c0e1e3
folderAsset: yes
timeCreated: 1454272673
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
using UnityEngine;
using System.Collections;
public class EngineRod : MonoBehaviour
{
public Transform anchor;
public Transform piston;
public float rodLength;
public Vector3 upVector;
private Vector3 startPosition;
private Quaternion rotation;
private Quaternion pistonRotation;
// Use this for initialization
void Start ()
{
upVector = piston.position - anchor.position;
rodLength = (transform.localPosition - transform.parent.InverseTransformPoint(piston.position)).magnitude;
upVector.Normalize();
startPosition = transform.localPosition;
upVector = transform.parent.InverseTransformVector(upVector);
rotation = transform.localRotation;
pistonRotation = piston.localRotation;
}
public float projectionDistance;
// Update is called once per frame
void Update () {
if (anchor != null)
{
transform.position = anchor.position;
Ray r = new Ray(startPosition, upVector);
var localPosProjected = r.Project(transform.localPosition);
projectionDistance = (localPosProjected - transform.localPosition).magnitude;
float pistonOffset = Mathf.Sqrt(rodLength*rodLength - projectionDistance*projectionDistance);
float angle = (90.0f - Mathf.Asin(pistonOffset/rodLength) * Mathf.Rad2Deg) *- Mathf.Sign(Vector3.Dot(transform.localPosition - localPosProjected, Vector3.forward));
transform.localRotation = Quaternion.AngleAxis(angle, Vector3.right) * rotation;
piston.localRotation = pistonRotation * Quaternion.AngleAxis(-angle, Vector3.right);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dd6ab127f9809c7448d4d9b971a91c0b
timeCreated: 1454273101
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
using UnityEngine;
using System.Collections;
public class RotationAnimation : MonoBehaviour
{
public Vector3 axis = Vector3.right;
public float angle;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
transform.localRotation = Quaternion.AngleAxis(angle*Time.deltaTime, axis.normalized)* transform.localRotation;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cefd9fdcf43268c488994d0c89f25194
timeCreated: 1454272681
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+77
View File
@@ -0,0 +1,77 @@
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class CameraController : MonoBehaviour {
public bool Active = false;
public float sensitivity = 2F;
float rotationY = 0F;
Vector3 Speed = new Vector3();
public float MaxSpeed = 10f;
public float AccelerationTime = 1f;
public float BrakingTime = 0.5f;
void Start ()
{
rotationY = -transform.localEulerAngles.x;
}
void Update ()
{
if(Input.GetKeyDown("mouse 1")){
Active = !Active;
}
if (!Active) return;
float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivity;
rotationY += Input.GetAxis("Mouse Y") * sensitivity;
rotationY = Mathf.Clamp (rotationY, -90, 90);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
Vector3 AccelerationForce = new Vector3(
((Input.GetKey("d")? 1f:0f)-(Input.GetKey("a")? 1f:0f)),
((Input.GetKey("space")? 1f:0f)-(Input.GetKey("left ctrl")? 1f:0f)),
((Input.GetKey("w")? 1f:0f)-(Input.GetKey("s")? 1f:0f))
);
AccelerationForce *= (Time.deltaTime/AccelerationTime);
Speed += AccelerationForce;
Vector3 BrakingForce = new Vector3(
(Input.GetKey("d")|Input.GetKey("a"))? 0f:1f,
(Input.GetKey("space")|Input.GetKey("left ctrl"))? 0f:1f,
(Input.GetKey("w")|Input.GetKey("s"))? 0f:1f
);
BrakingForce *= (Time.deltaTime/BrakingTime);
Speed.Set(
Speed.x-(Mathf.Sign(Speed.x)*Mathf.Min(BrakingForce.x,Mathf.Abs(Speed.x))),
Speed.y-(Mathf.Sign(Speed.y)*Mathf.Min(BrakingForce.y,Mathf.Abs(Speed.y))),
Speed.z-(Mathf.Sign(Speed.z)*Mathf.Min(BrakingForce.z,Mathf.Abs(Speed.z))));
Speed.Set(
Mathf.Clamp(Speed.x,-1f,1f),
Mathf.Clamp(Speed.y,-1f,1f),
Mathf.Clamp(Speed.z,-1f,1f));
transform.Translate(Time.deltaTime*Speed*MaxSpeed,Space.Self);
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fbc9b5ceeae8bd24cbedbe3c800c3dd0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+20
View File
@@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Transform target;
public Vector3 cameraOffset;
// Use this for initialization
void Start () {
if(target != null) {
cameraOffset = transform.position - target.position;
}
}
// Update is called once per frame
void Update () {
if(target != null) {
transform.position = target.position + cameraOffset;
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 4631c89c576451b4bae21e0103bd2d7a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+159
View File
@@ -0,0 +1,159 @@
using UnityEngine;
using System.Collections;
using System;
public enum CarPedal{
Clutch = 0,
Brake = 1,
Accelerator = 2
}
[SelectionBase]
public class Car : MonoBehaviour {
public Chassis chassis;
public SteeringWheel SteeringWheel;
public CarEngine engine;
private float _torque = 0;
public GameObject Driver;
public float dragCoeff = 0.35f;
public float frontalArea = 1.99f;
private float[] _pedals = new float[3];
private Rigidbody _rigidBody;
public AnimationCurve throlleCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
public CarElectricSystem electric;
public Transmission transmission;
public float[] Pedals{
get{ return _pedals;}
}
void OnGUI() {
// var rb = gameObject.GetComponent<Rigidbody>();
//Label3D.AtWorldPosition(transform.position + Vector3.up * 2, "Velocity: " + rb.velocity.ToStringEx() + " Km/h: " + rb.velocity.magnitude * 3.6f);
}
public void SetPedalState(CarPedal pedal, float state){
_pedals [(int)pedal] = Mathf.Clamp01 (state);
}
public float GetPedalState(CarPedal pedal){
return _pedals [(int)pedal];
}
public Rigidbody GetRigidBody(){
return _rigidBody;
}
public float D{
get { return 1; } //(Wheels[2].Target.transform.position - Wheels[0].Target.transform.position).magnitude;}
}
public float L{
get { return 1; } // (Wheels[1].Target.transform.position - Wheels[0].Target.transform.position).magnitude;}
}
public static float OuterWheelAngle(float innerDegree, float d, float l){
float sign = Mathf.Sign (innerDegree);
float rad = Mathf.Deg2Rad * innerDegree * sign;
float ctgB = Mathf.Cos (rad) / Mathf.Sin (rad);
return Arcctg (ctgB + d / l) * Mathf.Rad2Deg * sign;
//ctgA = ctgB + d/L
}
static float Arcctg(float x){
return Mathf.PI / 2.0f - Mathf.Atan (x);
}
// Use this for initialization
void Start () {
_rigidBody = gameObject.GetComponent<Rigidbody> ();
electric.ignition.Attach (this);
/*foreach (var w in Wheels) {
w.OnStart();
}*/
//SteeringWheel.OnStart ();
}
// Update is called once per frame
void Update () {
}
public float Torque(){
return _torque;
}
void OnDrawGizmos(){
//var rb = gameObject.GetComponent<Rigidbody> ();
//float airDrag = CarMath.Drag(1.25f, rb.velocity.magnitude, dragCoeff, frontalArea);
//var drag = -airDrag * rb.velocity.normalized ;
//Gizmos.DrawLine(transform.position + Vector3.up, transform.position + Vector3.up + drag);
}
float lastSpeed;
float measureTime;
public float testSpeed = 100.0f;
void FixedUpdate(){
var rb = gameObject.GetComponent<Rigidbody> ();
var vel = rb.velocity.magnitude * 3.6f; //km/h
if(lastSpeed == 0 && vel != 0) {
measureTime = Time.fixedTime;
Debug.Log("Go go go");
} else if(lastSpeed < testSpeed && vel >= testSpeed) {
Debug.LogFormat("Reached {0} Km/h in {1}", testSpeed, (Time.fixedTime - measureTime));
}
lastSpeed = vel;
chassis.suspension[0].wheel.driveTorque =
chassis.suspension[2].wheel.driveTorque = 1000*GetPedalState(CarPedal.Accelerator);
chassis.suspension[0].wheel.brakeTorque =
chassis.suspension[2].wheel.brakeTorque = 1000 * GetPedalState(CarPedal.Brake);
/* if (rb) {
float airDrag = CarMath.Drag(1.25f, rb.velocity.magnitude, dragCoeff, frontalArea);
var drag = -airDrag * rb.velocity.normalized;
rb.AddForce(-airDrag * rb.velocity.normalized);
}*/
/*float torqueSpeed = 20.0f;
if (Input.GetKey (KeyCode.UpArrow)) {
_torque += torqueSpeed * Time.fixedDeltaTime;
} else if (Input.GetKey (KeyCode.DownArrow)) {
_torque -= torqueSpeed * Time.fixedDeltaTime;
} else {
_torque *= 0.7f;
}*/
//_torque = Mathf.Clamp (_torque, -_maxTorque, _maxTorque);
//Wheels [0].Collider.motorTorque = _torque;
//Wheels [2].Collider.motorTorque = _torque;
chassis.Integrate(Time.fixedDeltaTime, this);
/*foreach (var w in Wheels) {
if(w != null){
var wheelVelocity = rb.GetPointVelocity(w.transform.position);
Vector3 wheelForce;
w.Integrate(Time.fixedDeltaTime, wheelVelocity, (rb.mass / 4.0f * 9.81f), out wheelForce);
rb.AddForceAtPosition(wheelForce, w.transform.position);
}
}*/
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cb64e1fd180c4e24490bb6ef339e6970
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+6
View File
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 7df5d0173a73f4a4bacb78f66bac9966
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
+44
View File
@@ -0,0 +1,44 @@
using UnityEngine;
using System.Collections;
public class Brake : MonoBehaviour {
public float _friction = 100;
public float _radius = 0.2f;
public float _area = 0.2f;
public float _max_pressure = 10;
public float _bias = 1;
private float _threshold = 4.0e-4f;
private bool _is_locked;
public Brake() {
}
public Brake (float sliding, float radius, float area, float max_pressure, float bias) {
_friction = sliding;
_radius = radius;
_area = area;
_max_pressure = max_pressure * bias;
_bias = bias;
}
public float GetTorque(float factor, float rotational_speed) {
// `factor' is the fraction of maximum pressure applied.
float pressure = factor * _bias * _max_pressure;
float normal = pressure * _area;
float torque = _friction * normal * _radius;
float velocity = _radius * rotational_speed;
if(velocity < 0.0f)
torque *= -1;
// See if the brake is locked.
if(Mathf.Abs(velocity) < (_threshold * normal)) {
_is_locked = true;
torque = 0.0f;
} else {
_is_locked = false;
}
return torque;
}
}
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c2696fc12f129fb43910ceeaa8bcea37
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+110
View File
@@ -0,0 +1,110 @@
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
[Serializable]
public class IdleThrolleController
{
public double IdleSpeed;
public double SpeedThreshold = 1.0;
public double LagConstant = 1.0;
public double IdleThrolle = 0.0;
public void Integrate(double dt, double speed)
{
var throlleDerivative = ((0.5f*(1.0 - Math.Tanh(4.0*(speed - IdleSpeed)/SpeedThreshold))) - IdleThrolle)/LagConstant;
IdleThrolle += throlleDerivative * dt;
}
}
public class CarEngine : MonoBehaviour {
public Flywheel flywheel;
public int cylinderCount = 4;
public float startRpm = 50;
public double inertia = 0.3f;
public double inputInertia = 0.0;
public double inputTorque = 0.0;
/*public abstract Curve TorqueCurve { get;}
public abstract Curve FrictionCurve { get;}*/
public float Weight = 100;
public Starter starter;
public double inputThrolle = 0.0f;
public double engineThrolle = 0.0f;
public IdleThrolleController idleThrolleController;
public double crankshaftAngle = 0.0; //radians
public double angularSpeed;
public double angularSpeedRPM;
public double k_Friction = 0.000003;
public Curve powerCurve;
public double k_FrictionTorque = 0.75f;
public double kinematicFrictionTorque = 0;
public double Rpm
{
get { return angularSpeed * MathEx.RadSToRpm; }
}
/* private static KeyValuePair<int, float>[] _starterTable = new KeyValuePair<int, float>[]{
new KeyValuePair<int, float>(2, 12.5f),
new KeyValuePair<int, float>(4, 8.0f),
new KeyValuePair<int, float>(6, 6.5f),
new KeyValuePair<int, float>(8, 6.0f),
new KeyValuePair<int, float>(12, 5.5f)
};*/
void FixedUpdate()
{
Integrate(Time.fixedDeltaTime);
}
public void Integrate(double dt) {
//do idle throlle
idleThrolleController.Integrate(dt, Rpm);
engineThrolle = Math.Max(inputThrolle, idleThrolleController.IdleThrolle);
//integrate angular acceleration and speed
var angularDerivative = (GetTorque(engineThrolle, Rpm) - inputTorque) / (inertia + inputInertia);
angularSpeed += angularDerivative * dt;
angularSpeedRPM = MathEx.RadSToRpm * angularSpeed;
//integrate angle
crankshaftAngle += angularSpeed * dt;
kinematicFrictionTorque = (angularSpeedRPM/60.0)*k_FrictionTorque;
}
public double GetTorque(double throlle, double rpm)
{
var t = GetTorque(rpm);
t = t * throlle - k_Friction * rpm * rpm * (1.0 - throlle);
return t;
}
public double GetTorque(double rpm){
if (powerCurve == null)
{
return 0;
}
return powerCurve.Sample((float)rpm);
}
public static float GetWatts(float torque, float rpm){
return torque * rpm / 9549.0f;
}
public static float GetHp(float torque, float rpm){
return GetWatts(torque, rpm) * 1.36f;
}
public bool Started = false;
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 84c8f10b9cc105c4d8c0f3565df12479
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,24 @@
using UnityEngine;
using System.Collections;
public class CarEngineDebug : MonoBehaviour{
public CarEngine engine;
void OnGUI()
{
if (engine != null)
{
GUI.Label(new Rect(0, 10, 200, 30), "Engine RPM: " + engine.Rpm);
}
if (GUI.Button(new Rect(0, 70, 100, 30), "Reset engine"))
{
engine.engineThrolle = 0.0548135214770327;
engine.inputThrolle = 0;
engine.angularSpeed = MathEx.RpmToRadS * 500;
engine.angularSpeedRPM = MathEx.RadSToRpm * engine.angularSpeed;
engine.crankshaftAngle = 0.0;
engine.idleThrolleController.IdleThrolle = 0.0548135214770327;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8a5446a43ae59804f8686e318dd3d03a
timeCreated: 1453922163
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+19
View File
@@ -0,0 +1,19 @@
using UnityEngine;
using System.Collections;
using System;
[Serializable]
public class CarWheelAxis {
public Suspension leftWheel;
public Suspension rightWheel;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2cdc318b1a3403e40b45e62d9bd84067
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+16
View File
@@ -0,0 +1,16 @@
using UnityEngine;
using System.Collections;
public class Chassis : MonoBehaviour {
public Suspension[] suspension;
public CarWheelAxis[] axisCollection;
public void Integrate(float dt, Car car){
foreach(var s in suspension){
s.Integrate(dt, car);
}
}
}
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b0f74529597105e4b93451888357b273
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+61
View File
@@ -0,0 +1,61 @@
using UnityEngine;
using System.Collections;
public class Differential : MonoBehaviour {
public float gearRatio = 3.5f;
public DriveShaft left;
public DriveShaft right;
public DriveShaft center;
// Use this for initialization
void Start () {
/*if (left != null) {
left.target = this;
}
if (right != null) {
right.target = this;
}
if (center != null) {
center.target = this;
}*/
}
// Update is called once per frame
void Update () {
}
/*
void OnDrawGizmos(){
AdvancedGizmo.DrawCircle (transform.position, Vector3.up, 0.2f, Color.green, 12, false, 1);
Gizmos.color = Color.red;
if (left != null) {
Gizmos.DrawLine(left.transform.position, gameObject.transform.position);
}
if (right != null) {
Gizmos.DrawLine(right.transform.position, gameObject.transform.position);
}
if (center != null) {
Gizmos.color = Color.blue;
Gizmos.DrawLine(center.transform.position, gameObject.transform.position);
}
var pt = Tools.WorldToGuiPoint (transform.position);
if (pt.z > 0) {
Tools.BeginGui ();
var textRect = new Rect (pt.x, pt.y, 100, 20);
Tools.DrawRectangle(textRect, new Color(0,0,0,0.7f));
GUI.Label (textRect, "Gear: " + gearRatio);
Tools.EndGui ();
}
}*/
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c7f2e113d7104154882152882f45afdd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+57
View File
@@ -0,0 +1,57 @@
using UnityEngine;
using System.Collections;
public class DriveShaft : MonoBehaviour
{
public Transform endpoint0;
public Transform endpoint1;
float inv_inertia;
public float Inv_inertia {
get {
return inv_inertia;
}
set {
inv_inertia = value;
}
}
float ang_velocity;
float angle;
public float Angle{
get{return angle;}
}
public float AngularVelocity{
get{return ang_velocity;}
set {
ang_velocity = value;
}
}
public DriveShaft() {
inv_inertia = 1;
ang_velocity = 0;
angle = 0;
}
// amount of momentum to reach angular velocity
public float GetMomentum(float angvel)
{
return (angvel - ang_velocity) / inv_inertia;
}
// update angular velocity
public void ApplyMomentum(float momentum)
{
ang_velocity += inv_inertia * momentum;
}
// update angle
public void Integrate(float dt){
angle += ang_velocity * dt;
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: bb743870935c8804bb18ddd60eeca428
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e3a5c241b3709404b8e82672a96f1b12
folderAsset: yes
timeCreated: 1453140670
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,32 @@
using System;
using UnityEngine;
using System.Collections;
public class EnginePowerCurve : Curve
{
public float maxPower = 150000; //in Watts
public float rpmAtMaxPower = 8000;
public float k_p1 = 1;
public float k_p2 = 1;
public float k_p3 = 1;
public override float Sample(float arg) {
var o_max = rpmAtMaxPower;
double o_e = arg;
var p = new double[4];
p[0] = 0;
p[1] = maxPower / o_max * k_p1;
p[2] = maxPower / (o_max * o_max) * k_p2;
p[3] = -maxPower / (o_max * o_max * o_max) * k_p3;
double Pe = 0.0;
for (int i = 0; i < 4; ++i) {
Pe += p[i] * Math.Pow(o_e, i);
}
var t = MathEx.Torque(Pe, MathEx.RpmToRadS * (arg + 0.000001));
return (float)t;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 242e7bc229da7d840be56306cd243fc1
timeCreated: 1454257928
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+26
View File
@@ -0,0 +1,26 @@
using UnityEngine;
using System.Collections;
public class Flywheel : MonoBehaviour
{
public uint teethCount = 129;
public float mass = 6.6f;
public float radius = 0.14f;
public float inertia = 0.06468f;
[ContextMenu("Calculate inertia")]
void CalcInertia()
{
inertia = (mass*radius*radius)*0.5f;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d20f72f97cc2b864389b190cb34b1d47
timeCreated: 1454252724
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+15
View File
@@ -0,0 +1,15 @@
using UnityEngine;
using System.Collections;
public enum GearboxControlType{
Manual,
Automatic
}
public abstract class Gearbox : MonoBehaviour {
public abstract GearboxControlType ControlType{ get;}
public abstract float MaxOutputTorque{ get;}
public abstract int GearsCount{ get;}
public abstract float GetGearRatio(int gear);
public abstract int Gear{ get; set;}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 47ea6b7730855674fba79ad64b9691a1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
@@ -0,0 +1,34 @@
using UnityEngine;
using System.Collections;
public class PacejkaParameters : MonoBehaviour {
[ContextMenuItem("Reset coeffs", "resetPacejkaCoeffs")]
public PacejkaCoeffs _coeffs = new PacejkaCoeffs();
[ContextMenuItem("Reset coeffs2", "resetPacejkaCoeffs2")]
public PacejkaCoeffs2 _coeffs2;
public double minLoad = 0;
public double maxLoad = 8900;
private void resetPacejkaCoeffs() {
_coeffs = new PacejkaCoeffs();
}
private void resetPacejkaCoeffs2() {
_coeffs2 = new PacejkaCoeffs2();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cb98de270c82d434c8c66084fdbf89af
timeCreated: 1453140700
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,109 @@
using UnityEngine;
using System.Collections;
public class SimpleSteerController : SteerController {
private float _steer;
public float maxSteerAngle = 30.0f;
public WheelPhysics frontLeftWheel;
public WheelPhysics frontRightWheel;
public WheelPhysics rearLeftWheel;
public WheelPhysics rearRightWheel;
private Vector3 frontLeftStartAngle;
private Vector3 frontRightStartAngle;
public SteeringWheel steeringWheel;
public override float Steer {
get {
return _steer;
}
set {
_steer = Mathf.Clamp(value, -1.0f, 1.0f);
UpdateWheelAngles();
}
}
void UpdateWheelAngles(){
float d = (frontRightWheel.transform.position - frontLeftWheel.transform.position).magnitude;
float l = (frontRightWheel.transform.position - rearRightWheel.transform.position).magnitude;
float innerAngle = maxSteerAngle * _steer;
float outerAngle = OuterWheelAngle (innerAngle, d, l);
if (_steer < 0.0f) {
UpdateWheelSteering (frontLeftWheel, frontLeftStartAngle, innerAngle);
UpdateWheelSteering (frontRightWheel, frontRightStartAngle, outerAngle);
} else {
UpdateWheelSteering (frontRightWheel, frontRightStartAngle, innerAngle);
UpdateWheelSteering (frontLeftWheel, frontLeftStartAngle, outerAngle);
}
steeringWheel.SetAngle(steeringWheel.degrees*0.5f*_steer);
}
void UpdateWheelSteering(WheelPhysics wheel, Vector3 initialAngles, float steerAngle){
initialAngles.y += steerAngle;
wheel.transform.localEulerAngles = initialAngles;
}
public static float OuterWheelAngle(float innerDegree, float d, float l){
float sign = Mathf.Sign (innerDegree);
float rad = Mathf.Deg2Rad * innerDegree * sign;
float ctgB = Mathf.Cos (rad) / Mathf.Sin (rad);
return Arcctg (ctgB + d / l) * Mathf.Rad2Deg * sign;
}
static float Arcctg(float x){
return Mathf.PI / 2.0f - Mathf.Atan (x);
}
// Use this for initialization
void Start () {
frontLeftStartAngle = frontLeftWheel.transform.localEulerAngles;
frontRightStartAngle = frontRightWheel.transform.localEulerAngles;
}
void OnGUI(){
Steer = GUI.HorizontalSlider (new Rect (10, 10, 300, 20), Steer, -1, 1);
}
public float testSteerSpeed = 20.0f;
public float torque = 1000;
void FixedUpdate()
{
float finalTorque = Input.GetKey(KeyCode.W) ? torque : (Input.GetKey(KeyCode.S) ? -torque : 0);
frontLeftWheel.driveTorque = finalTorque;
frontRightWheel.driveTorque = finalTorque;
double breakTorque = 0;
if (Input.GetKey(KeyCode.Space))
{
breakTorque = 1600;
}
frontLeftWheel.brakeTorque = breakTorque;
frontRightWheel.brakeTorque = breakTorque;
rearLeftWheel.brakeTorque = breakTorque;
rearRightWheel.brakeTorque = breakTorque;
}
// Update is called once per frame
void Update () {
float steerDelta = testSteerSpeed * Time.fixedDeltaTime;
if (Input.GetKey (KeyCode.D)) {
Steer += steerDelta;
}
if (Input.GetKey (KeyCode.A)) {
Steer -= steerDelta;
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5ff6449b097dd764d99cf320db63ebce
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,33 @@
using UnityEngine;
using System.Collections;
public class SimpleSuspension : Suspension {
private Quaternion _startupRotation;
// Use this for initialization
void Start () {
_startupRotation = transform.localRotation;
}
// Update is called once per frame
void Update () {
}
public override void OnSteerChanged()
{
transform.localRotation = _startupRotation * Quaternion.AngleAxis((float)Steer, Vector3.up);
}
void OnDrawGizmos(){
var up = transform.up;
var center = transform.position;
Gizmos.DrawLine(center + up * (float)((1.0 - suspensionTarget) * travelDistance), center - up * (float)(suspensionTarget* travelDistance));
bool front = wheel.name[wheel.name.Length - 2] == 'f';
Vector3 vOffset = front ? Vector3.up : Vector3.up * 0.5f;
Gizmos.DrawLine(dbgWheelForcePos + vOffset, dbgWheelForcePos + dbgWheelForce + vOffset);
Gizmos.DrawLine(dbgWheelForcePos + vOffset, dbgWheelForcePos);
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6d16ee8693777b14b952662a59be4ad7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,7 @@
using UnityEngine;
using System.Collections;
public abstract class SteerController : MonoBehaviour {
public abstract float Steer{ get; set; }
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: dd8405aff4937ff4e948598fa5c04f53
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+142
View File
@@ -0,0 +1,142 @@
using UnityEngine;
using System.Collections;
public abstract class Suspension : MonoBehaviour {
private double _steer;
protected double _normalForce;
public WheelPhysics wheel;
public double travelDistance = 0.2f;
public double suspensionTarget = 0.2f;
private double _displacement;
protected double _previousFraction;
private double _overtravel;
private double _lastDisplacement;
public double springForce = 9000;
public double springDamping = 400;
public double Steer{
get{return _steer;}
set
{
_steer = value;
OnSteerChanged();
}
}
public virtual void OnSteerChanged() {
}
// Use this for initialization
void Start () {
}
public double Displacement {
get{return _displacement;}
set{
_lastDisplacement = _displacement;
_displacement = MathEx.Clamp(value, 0, travelDistance);
_overtravel = value - travelDistance;
if(_overtravel < 0){
_overtravel = 0;
}
}
}
public void CalculateForce(double dt){
double velocity = ((_displacement - _lastDisplacement) / travelDistance) / dt;
double spring = (_displacement / travelDistance) * springForce;
double damping = velocity * springDamping;
_normalForce = damping + spring;
}
double computeImpulseDenominator(Vector3 pos, Vector3 normal, Rigidbody rb){
Vector3 r0 = pos - rb.worldCenterOfMass;
Vector3 c0 = Vector3.Cross(r0, normal);
var tensorLocal = Matrix4x4.TRS(rb.worldCenterOfMass, rb.inertiaTensorRotation, rb.inertiaTensor);
var tensorWorld = transform.localToWorldMatrix * tensorLocal;
tensorWorld = Matrix4x4.Inverse(tensorWorld);
Vector3 vec = Vector3.Cross(tensorWorld.MultiplyPoint(c0), r0);
return 1.0f / rb.mass + Vector3.Dot(normal, vec);
}
protected Vector3 dbgWheelForce;
protected Vector3 dbgWheelForcePos;
public void Integrate(double dt, Car car){
if(wheel != null){
//var rb = car.GetRigidBody();
//raycast wheel
wheel.UpdateContactPoint(car.transform.up);
double fraction;
double relativeDisplacement = wheel.TotalWheelRadius - wheel.Contact.hit.distance;
Displacement += relativeDisplacement;
fraction = _displacement / travelDistance;
CalculateForce(dt);
var wheelWorldVelocity = car.GetRigidBody().GetPointVelocity(wheel.transform.position);
if (_overtravel > 0)
{
double correction_factor = 0.0f;
double dv = Vector3.Dot(wheelWorldVelocity, transform.up);// body->getVelocityInLocalPoint(suspension_force_application_point).dot(forcedirection);
dv -= correction_factor * _overtravel / dt;
// double effectiveMass = 1.0 / computeImpulseDenominator(wheel.transform.position, transform.up, car.GetRigidBody());//1.0 / body->computeImpulseDenominator(wheel_position[i], forcedirection);
// double correction = -effectiveMass * dv / dt;
/*if (correction > 0)
{
_normalForce = correction;
}*/
}
if(!wheel.Contact.hasHit) {
_normalForce = 0;
}
if(_normalForce > 0.0f){
car.GetRigidBody().AddForceAtPosition(wheel.Contact.hit.normal * (float)_normalForce, transform.position);
}
wheel.transform.position = GetWheelPosition(fraction);
Vector3 wheelForce;
wheel.Integrate(dt, wheelWorldVelocity, _normalForce, out wheelForce);
car.GetRigidBody().AddForceAtPosition(wheelForce, wheel.transform.position);
dbgWheelForce = wheelForce;
dbgWheelForcePos = wheel.transform.position;
}
}
public void CalculateSuspensionForce(double dt, double fraction) {
_normalForce = springForce * (suspensionTarget - fraction) + springDamping * (_previousFraction - fraction) / dt;
_previousFraction = fraction;
}
public Vector3 GetWheelPosition(double fraction) {
var up = transform.up;
var center = transform.position;
var top = center + up * (float)((1.0 - suspensionTarget) * travelDistance);
var bottom = center - up * (float)(suspensionTarget * travelDistance);
return bottom + (top - bottom) * Mathf.Clamp01((float)fraction);
}
// Update is called once per frame
void Update () {
/* */
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: cd4c241e105bc7144a70f4d5e141b4bb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+150
View File
@@ -0,0 +1,150 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System;
[ExecuteInEditMode]
public class Tyre : MonoBehaviour {
public double height = 0.15f;
public double k_RollLinear = 0.0038;
public double k_RollQuad = 0.000026;
public double GetRollingResistance(double Fz, double wheelEffectiveRadius, double velocity, double resistanceFactor) {
return Fz * wheelEffectiveRadius * resistanceFactor * (k_RollLinear + k_RollQuad * (velocity )) * Math.Sign(velocity);
}
private double oldLatSlip;
public double latFilter = 0.85f;
public PacejkaParameters pacejkaParams;
/* public void Slip(double patch_speed, Vector3 hub_velocity, out double slipLon, out double slipLat) {
var absLongVelocity = (double)Mathf.Abs(hub_velocity.z);
absLongVelocity = Math.Max(absLongVelocity, dampAbsRoadVelo);
slipLon = CalcSlipRatio(patch_speed, hub_velocity) * 100.0f;
slipLat = (Mathf.Atan2(hub_velocity.x, (float)absLongVelocity)) * Mathf.Rad2Deg;
}
public Double3 FrictionForce(double normalForce, double slipLon, double slipLat, double camber, PacejkaCoeffs coeffs) {
if(normalForce < 1e-4f) { return Double3.zero; }
normalForce = MathEx.Clamp(normalForce, 0, 100000);
//compute Pacejka params
var lateralParams = Pacejka.LateralParams(normalForce, camber, coeffs);
var longitudinalParams = Pacejka.LongitudinalParams(normalForce, coeffs);
var aligningParams = Pacejka.AligningParams(normalForce, camber, coeffs);
//compute friction forces
Double3 result;
result.x = Pacejka.MagicFormula(slipLon, longitudinalParams);
result.y = Pacejka.MagicFormula(slipLat, lateralParams);
result.z = Pacejka.MagicFormula(slipLat, aligningParams);
/* //do combined friction
double d_lon = slipLon / (1.0 + slipLon);
double d_lat = Math.Tan(slipLat) / (1.0 + slipLon);
double d = Math.Sqrt(d_lat * d_lat + d_lon * d_lon);
if(d > 0.001) {
result.x *= (float)Math.Abs(d_lon / d);
result.y *= (float)Math.Abs(d_lat / d);
}*/
// return result;
// }
void OnValidate() {
if(enabled) {
if(transform.parent != null && gameObject.activeInHierarchy)
{
SceneView.RepaintAll();
// transform.parent.gameObject.SendMessage("OnValidate");
}
}
}
// SAE950311 implementation
// private double lastU;
// private double signU = 1;
//private double oldSlip = 0;
// public double tau;
// public double B = 0.091f;//relaxationLengthLong
public double relaxLong = 0.00172688486f;
// private double _integratedSlip;
public double speedThreshold = 3.0f;
public double dampAbsRoadVelo = 1;
public double kBLong = 0.35f;
public double fixedTimeBase = 0.02f;
public double CalcSlipRatio(double patch_speed, Vector3 hub_velocity) {
bool IsOnSurface = true;
if(!IsOnSurface) {
// _integratedSlip = 0;
return 0;
}
/* double deltaTime = Time.fixedDeltaTime;
double dampSRreversal = 0.5f;
double B = relaxLong*100;
double fixedTimeStepScalar = fixedTimeBase / Time.fixedDeltaTime;
double invFixedTimeStepScalar = 1.0f / fixedTimeStepScalar;
if(B < kBLong * invFixedTimeStepScalar)
B = kBLong * invFixedTimeStepScalar;
// damp sliAngle and slipRatio oscilation
double factor = hub_velocity.z * 3.6f * 0.02f; // divided by 50
if(factor < 1)
factor = 1;
B *= factor;
*/
// SAE950311 algorithm
var longVelocity = (double)hub_velocity.z;
// var absLongVelocity = Math.Abs(longVelocity);
if (Math.Abs(longVelocity - patch_speed) > 1.0e-4)
{
double denom = Math.Max(Math.Abs(longVelocity), dampAbsRoadVelo);
return MathEx.Clamp((patch_speed - longVelocity)/denom, -1.0, 1.0);
}
else
{
return 0;
}
/*
absLongVelocity = Math.Max(absLongVelocity, dampAbsRoadVelo);
if((lastU < 0 && longVelocity >= 0) || (lastU >= 0 && longVelocity < 0)) {
_integratedSlip = -dampSRreversal * _integratedSlip;
}
lastU = Math.Sign(longVelocity);
double derivative = (patch_speed - longVelocity) - absLongVelocity * _integratedSlip;
derivative /= B;
// Integrate
_integratedSlip += derivative * deltaTime;
return MathEx.Clamp(_integratedSlip + tau * derivative, -1.5, 1.5);*/
}
}
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 70404261169dc6f498752a2108433b55
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+366
View File
@@ -0,0 +1,366 @@
/*
using UnityEngine;
[ExecuteInEditMode]
public class Wheel : MonoBehaviour {
public Tyre tyre;
public Brake brake;
public DriveShaft _shaft;
public float discRadius = 0.385f; //15 inch by default
private float _totalWheelRadius;
public float TotalWheelRadius {
get {
return _totalWheelRadius;
}
}
public float _slipLon;
public float _slipLat;
private Vector3 _localVelocity;
private Vector3 _friction;
private Vector3 _peakSlip;
public float camber;
public bool DrawDebug = true;
public float weight = 50;
public float driveTorque = 0.0f;
public float brakeTorque = 0.0f;
public float brakingState = 0.0f;
private WheelContact _contact;
public Oscilloscope oscilloscope;
private int t;
public bool Grounded {
get {
return _contact.grounded;
}
}
public WheelContact Contact {
get {
return _contact;
}
}
[ContextMenuItem("Reset coeffs", "resetPacejkaCoeffs")]
public PacejkaCoeffs _coeffs = new PacejkaCoeffs();
public float dtMul = 1;
private void resetPacejkaCoeffs() {
_coeffs = new PacejkaCoeffs();
}
public float AngularVelocity {
get { return _shaft.AngularVelocity; }
set {
_shaft.AngularVelocity = value;
}
}
// Use this for initialization
void Start () {
InitWheel();
float normalForce = 3.210758f * 1000.0f;
var lateralParams = Pacejka.LateralParams(normalForce, 0, _coeffs);
var longitudinalParams = Pacejka.LongitudinalParams(normalForce, _coeffs);
var aligningParams = Pacejka.AligningParams(normalForce, 0, _coeffs);
_peakSlip.x = Pacejka.Extremum(longitudinalParams);
_peakSlip.y = Pacejka.Extremum(lateralParams);
_peakSlip.z = Pacejka.Extremum(aligningParams);
if(oscilloscope != null)
{
oscilloscope.channels[0].sampler = Sampler0;
oscilloscope.channels[1].sampler = Sampler1;
oscilloscope.channels[2].sampler = Sampler2;
}
}
float Sampler0()
{
return _slipLat;
}
float Sampler1()
{
return localVelocity.x;
}
float Sampler2()
{
return 0;//Mathf.Repeat(_shaft.Angle, Mathf.PI * 2);
}
float Inertia{
get{return 1.0f / _shaft.Inv_inertia;}
set{_shaft.Inv_inertia = 1.0f / value;}
}
void InitWheel() {
if (_shaft == null) {
_shaft = new DriveShaft();
}
if (tyre != null) {
_totalWheelRadius = discRadius + tyre.height;
}
Inertia = weight*_totalWheelRadius*_totalWheelRadius*0.5f;
}
void OnValidate() {
InitWheel();
}
public void SetBraking(float amount) {
brakingState = Mathf.Clamp01(amount);
}
void SetTorque(float torque, float dt) {
_shaft.ApplyMomentum(torque * dt);
}
void OnDrawGizmosSelected() {
if (!DrawDebug) {
return;
}
var p = _coeffs;
Curve[] curves = new Curve[]{new Curve(), new Curve(), new Curve()};
int sampleCnt = 250;
float minArg = -100;
float maxArg = 100;
float argDiff = maxArg - minArg;
for (int i = 0; i < sampleCnt; ++i) {
var arg = minArg + argDiff / ((float)sampleCnt - 1) * i;
curves[0].AddArg(arg);
curves[1].AddArg(arg);
curves[2].AddArg(arg);
curves[0].AddVal(Pacejka.LongitudinalForce (5000.0f, arg, p));
curves[1].AddVal(Pacejka.LateralForce (5000.0f, camber, arg, p));
curves[2].AddVal(Pacejka.AligningForce (5000.0f, camber, arg, p));
}
float maxSlip = MathEx.FindExtremumValue(x => Pacejka.LongitudinalForce(5000.0f, x, p), 0, 100, 0.5f);
Tools.BeginGui ();
GUI.Label(new Rect(20,30,300,100), "Maximum wheel slip: " + maxSlip + " Value at that slip: " + Pacejka.LongitudinalForce(5000.0f, maxSlip, p));
Plot2D plot = new Plot2D(curves[0]);
plot.Title = "Longitudinal friction";
plot.OnGUI(new Rect(90,100,500,400));
camber = GUI.HorizontalSlider (new Rect (10, 10, 100, 10), camber, -10, 10);
Tools.EndGui ();
}
float GetTorque(float new_angvel, float dt) {
return _shaft.GetMomentum(new_angvel) / dt;
}
private float roll_resistance_lin = 0.00001f;
private float roll_resistance_quad = 0.00001f;
float getRollingResistance(
float velocity,
float resistance_factor)
{
// surface influence on rolling resistance
float rolling_resistance = resistance_factor * roll_resistance_lin;
// heat due to tire deformation increases rolling resistance
// approximate by quadratic function
rolling_resistance += velocity * velocity * roll_resistance_quad;
// rolling resistance direction
float resistance = -rolling_resistance;
if (velocity < 0) resistance = -resistance;
return resistance;
}
public void UpdateContactPoint(Vector3 up){
var raycastRay = new Ray (transform.position, -up);
_contact.hasHit = false;
_contact.grounded = false;
if (Physics.Raycast (raycastRay, out _contact.hit)) {
_contact.hasHit = true;
if(_contact.hit.distance <= _totalWheelRadius){
_contact.grounded = true;
}
}
}
int pp = 0;
private Vector3 lonForce;
private Vector3 latForce;
private float wheel_torque;
public float dampOsc = 0.85f;
public float fixedTimeBase = 0.02f;
private Vector3 localVelocity;
public void Integrate(float dt, Vector3 wheelWorldVelocity, float normal_force, out Vector3 force)
{
//normal_force = 5000.0f;
float wheel_drive_torque = driveTorque;
float patch_speed = AngularVelocity * _totalWheelRadius;
localVelocity = transform.InverseTransformDirection(wheelWorldVelocity);
tyre.Slip(patch_speed, localVelocity, out _slipLon, out _slipLat);
Vector3 friction_force = tyre.FrictionForce(normal_force, _slipLon, _slipLat, 0, _coeffs);
lonForce = transform.forward * friction_force[0];
latForce = -transform.right * friction_force[1];
Vector3 tire_force = lonForce + latForce;
float tire_friction_torque = friction_force[0] * _totalWheelRadius;
//calculate brake torque
float wheel_lock_torque = -AngularVelocity / dt * Inertia;
float wheel_brake_torque = wheel_lock_torque - wheel_drive_torque + tire_friction_torque;
float maxBreakTorque = brakeTorque;
if (wheel_brake_torque > 0 && wheel_brake_torque > maxBreakTorque)
{
wheel_brake_torque = maxBreakTorque;
}
else if (wheel_brake_torque < 0 && wheel_brake_torque < -maxBreakTorque)
{
wheel_brake_torque = -maxBreakTorque;
}
//limit the reaction torque to the applied drive and braking torque
float reaction_torque = tire_friction_torque;
float applied_torque = wheel_drive_torque + wheel_brake_torque;
if ( ( applied_torque > 0 && reaction_torque > applied_torque ) ||
( applied_torque < 0 && reaction_torque < applied_torque ) )
reaction_torque = applied_torque;
Vector3 tire_torque = Vector3.right * reaction_torque;// - direction::up * friction_force[2];
//set wheel torque due to tire rolling resistance
float rollResistanceCoefficient = 0;
float rolling_resistance = getRollingResistance(AngularVelocity, rollResistanceCoefficient);
float rolling_resistance_torque = rolling_resistance * _totalWheelRadius - tire_friction_torque;
wheel_torque = wheel_drive_torque + wheel_brake_torque + rolling_resistance_torque;
//have the wheels internally apply forces, or just forcibly set the wheel speed if the brakes are locked
float oldAngularVelocity = AngularVelocity;
SetTorque(wheel_torque, dt);
/ *float fixedTimeStepScalar = fixedTimeBase / Time.fixedDeltaTime;
float invFixedTimeStepScalar = 1.0f / fixedTimeStepScalar;
// damp low speed wheel oscillations
float deltaAngularVelocity = AngularVelocity - oldAngularVelocity;
float delta = deltaAngularVelocity * dampOsc * Mathf.Clamp01(invFixedTimeStepScalar);
AngularVelocity -= delta;* /
_shaft.Integrate(dt);
//viscous tire contact drag (hack)
float rollingDrag = 0.0f;
Vector3 wheel_drag = _localVelocity * rollingDrag;
force = Vector3.zero;
//apply forces to body
// Vector3 tire_pos = wheel_position[i] - body->getCenterOfMassPosition();
Vector3 world_tire_force = tire_force;
//Vector3 world_tire_torque = quatRotate ( wheel_orientation[i], tire_torque);
world_tire_force += wheel_drag;
//world_tire_torque += tire_pos.cross(world_tire_force);
force = world_tire_force;
//torque = torque + world_tire_torque;
}
float RPM
{
get {
return _shaft.AngularVelocity * 30.0f / 3.1415926535f;
}
}
public DriveShaft Shaft {
get {
return _shaft;
}
}
void OnGUI()
{
DrawLabels();
}
void DrawLabels() {
Label3D.AtWorldPosition(transform.position + Vector3.up * 1, "RPM: " + RPM);
Label3D.AtWorldPosition(transform.position + Vector3.up * 1.3f, "F: " + _friction.x + " S: " + _slipLon);
}
void OnDrawGizmos() {
if (tyre == null || _shaft == null) {
return;
}
DrawLabels();
var forward = transform.forward;
var right = transform.right;
//draw wheel radius
var wheelCenter = transform.position;
var rollMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(_shaft.Angle * Mathf.Rad2Deg, right), Vector3.one);
var radiusP0 = -forward * _totalWheelRadius;
var radiusP1 = forward * _totalWheelRadius * 1.2f;
radiusP0 = rollMatrix.MultiplyPoint3x4 (radiusP0);
radiusP1 = rollMatrix.MultiplyPoint3x4 (radiusP1);
Gizmos.DrawLine (wheelCenter + radiusP0, wheelCenter + radiusP1);
//draw wheel outer circle
AdvancedGizmo.DrawCircle(wheelCenter, right, _totalWheelRadius, Color.green, 36);
//draw wheel inner circle
AdvancedGizmo.DrawCircle(wheelCenter, right, discRadius, Color.green, 36);
//draw forces
Gizmos.color = Color.red;
Gizmos.DrawLine(wheelCenter, wheelCenter + lonForce);
Gizmos.color = Color.green;
Gizmos.DrawLine(wheelCenter, wheelCenter + latForce);
Gizmos.color = Color.blue;
Gizmos.DrawLine(wheelCenter, wheelCenter + latForce + lonForce);
Gizmos.color = Color.black;
Gizmos.DrawLine(wheelCenter, wheelCenter + forward * 100);
}
}
*/
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a0c7faf1940de454e9a95ef9e629f173
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+169
View File
@@ -0,0 +1,169 @@
using UnityEngine;
using System.Collections;
using System.Net.Security;
using System;
public struct WheelContact {
public RaycastHit hit;
public bool hasHit;
public bool grounded;
}
public class WheelPhysics : MonoBehaviour {
public Tyre tyre;
public Brake brake;
public double driveTorque = 0.0f;
public double brakeTorque = 0.0f;
public double angularVelocity; //rad/sec
public double inertiaMomentum = 3.45f;
public double angle; //radian
private WheelContact _contact;
public bool Grounded {
get {
return _contact.grounded;
}
}
public double discRadius = 0.385f; //15 inch by default
public double TotalWheelRadius {
get {
return discRadius + tyre.height;
}
}
public WheelContact Contact {
get {
return _contact;
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
}
private double _slipLon;
private double _slipLat;
private Vector3 localVelocity;
private int t = 0;
public double reactionTorque;
public void Integrate(double dt, Vector3 wheelWorldVelocity, double normal_force, out Vector3 force) {
t++;
localVelocity = transform.InverseTransformDirection(wheelWorldVelocity);
double patchSpeed = angularVelocity * TotalWheelRadius;
// tyre.Slip(patchSpeed, localVelocity, out _slipLon, out _slipLat);
var Vc = new Double3(localVelocity.z, localVelocity.x, localVelocity.y);
Double3 frictionForces = Pacejka.CalcPacejka(Vc, angularVelocity, TotalWheelRadius, TotalWheelRadius, normal_force, 0, tyre.pacejkaParams._coeffs2, true);
frictionForces.y *= -1.0;
// Double3 frictionForces = tyre.FrictionForce(normal_force, _slipLon, _slipLat, 0, tyre.pacejkaParams._coeffs);
/* if (name[name.Length - 2] == 'f' && t % 250 == 0) {
Debug.LogFormat("Fz = {0} Fx = {1} Slip = {2} Vlon = {4} Name = {3}", normal_force, frictionForces.x, _slipLon, name, localVelocity.z);
}*/
double T_engine = driveTorque;
double T_break = brakeTorque * -Math.Sign(angularVelocity);
double T_input = T_engine + T_break;
double T_reaction = frictionForces.x * TotalWheelRadius;
reactionTorque = T_reaction;
/*if (T_input < 0 && (T_reaction < T_input) || (T_input > 0 && (T_reaction > T_input)))
{
T_reaction = T_input;
}*/
double T_rolling_resist = tyre.GetRollingResistance(normal_force, TotalWheelRadius, localVelocity.z, 1.0f);
double angularAcceleration = (T_engine - T_reaction + T_break - T_rolling_resist) /inertiaMomentum;
angularVelocity += angularAcceleration * dt;
//dw/dt = (T_engine + T_reaction - T_break - T_friction) / WheelInertia
angle += angularVelocity * dt;
Vector3 lonForce = transform.forward * (float)frictionForces.x;
Vector3 latForce = -transform.right * (float)frictionForces.y;
force = lonForce + latForce;
}
public void UpdateContactPoint(Vector3 up) {
var raycastRay = new Ray(transform.position, -up);
_contact.hasHit = false;
_contact.grounded = false;
if (Physics.Raycast(raycastRay, out _contact.hit)) {
_contact.hasHit = true;
if (_contact.hit.distance <= TotalWheelRadius) {
_contact.grounded = true;
}
}
}
void OnDrawGizmos() {
if (tyre == null) {
return;
}
//DrawLabels();
var forward = transform.forward;
var right = transform.right;
//draw wheel radius
var wheelCenter = transform.position;
//var rollMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(_shaft.Angle * Mathf.Rad2Deg, right), Vector3.one);
var rollMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(0, right), Vector3.one);
var radiusP0 = -forward * (float)TotalWheelRadius;
var radiusP1 = forward * (float)(TotalWheelRadius * 1.2);
radiusP0 = rollMatrix.MultiplyPoint3x4(radiusP0);
radiusP1 = rollMatrix.MultiplyPoint3x4(radiusP1);
Gizmos.DrawLine(wheelCenter + radiusP0, wheelCenter + radiusP1);
//draw wheel outer circle
AdvancedGizmo.DrawCircle(wheelCenter, right, (float)TotalWheelRadius, Color.green, 36);
//draw wheel inner circle
AdvancedGizmo.DrawCircle(wheelCenter, right, (float)discRadius, Color.green, 36);
//draw forces
/*Gizmos.color = Color.red;
Gizmos.DrawLine(wheelCenter, wheelCenter + lonForce);
Gizmos.color = Color.green;
Gizmos.DrawLine(wheelCenter, wheelCenter + latForce);
Gizmos.color = Color.blue;
Gizmos.DrawLine(wheelCenter, wheelCenter + latForce + lonForce);
Gizmos.color = Color.black;
Gizmos.DrawLine(wheelCenter, wheelCenter + forward * 100);*/
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f0f3b45c60aa04c4c9e0c48be7e96fa3
timeCreated: 1453062224
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+15
View File
@@ -0,0 +1,15 @@
using UnityEngine;
using System.Collections;
public class CarDashboard : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: de5d28a979b679246ababb0c34743987
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+21
View File
@@ -0,0 +1,21 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
[ExecuteInEditMode]
public class CarDebug : MonoBehaviour {
public bool showTorquePlot = true;
public bool showHpPlot = true;
void OnDrawGizmosSelected(){
if (enabled) {
var car = GetComponent<Car> ();
if (car != null) {
if(car.engine != null){
Handles.BeginGUI ();
Handles.EndGUI ();
}
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a53750ffe9e631f479429fe502b35b00
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+46
View File
@@ -0,0 +1,46 @@
using UnityEngine;
using System.Collections;
public enum PowerBusType{
Acc = 0,
On = 1
}
public class CarElectricSystem : MonoBehaviour {
public IElecticEnergySource energySource;
public IgnitionSystem ignition;
private PowerBus[] _powerBus;
// Use this for initialization
void Start () {
//create electric power buses
_powerBus = new PowerBus[]{new PowerBus(), new PowerBus()};
foreach (var bus in _powerBus) {
bus.ElectricSystem = this;
}
//attach to ignition system
if (ignition != null) {
ignition.PowerBus = _powerBus [(int)PowerBusType.On];
ignition.StateChanged += HandleIgnitionStateChanged;
} else {
Debug.LogWarning("Electric system: no ignition system attached");
}
}
void HandleIgnitionStateChanged (IgnitionSystem caller, IgnitionState oldState, IgnitionState newState){
_powerBus [(int)PowerBusType.Acc].Enabled = newState != IgnitionState.Lock;
_powerBus [(int)PowerBusType.On].Enabled = (newState != IgnitionState.Lock) && (newState != IgnitionState.Acc);
}
public PowerBus GetPowerBus(PowerBusType busType){
return _powerBus[(int)busType];
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 45b7fc88ee501014cb568bf406af0b88
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+37
View File
@@ -0,0 +1,37 @@
using UnityEngine;
using System.Collections;
public class CarGUI : MonoBehaviour {
private Car _car;
private VerticalProgressBar _pedalBar;
// Use this for initialization
void Start () {
_car = GetComponent<Car> ();
_pedalBar = new VerticalProgressBar ();
}
// Update is called once per frame
void Update () {
}
void OnGUI(){
if (_car != null) {
var pedals = _car.Pedals;
Vector2 topLeft = new Vector2(100,400);
Vector2 size = new Vector2(30,200);
float margin = 10;
for(int i = 0; i < pedals.Length; ++i){
var pedal = (CarPedal)i;
if(pedals != null && pedals.Length > i && pedals[i] != null){
_pedalBar.Value = pedals[i];
_pedalBar.OnGUI(new Rect(topLeft.x + (size.x + margin) * i,topLeft.y,size.x,size.y));
}
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6e9ab79b375a83341bb9a72438364ee6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+57
View File
@@ -0,0 +1,57 @@
using UnityEngine;
using System.Collections;
public interface IDevice {
string Name { get; }
string ShortDescription { get; }
}
public interface IElectricDevice : IDevice {
void SetPowerBus(PowerBus bus);
bool On { get; set; }
}
public abstract class IElecticEnergySource : MonoBehaviour, IDevice{
public abstract float Voltage{ get; }
public abstract float MaxPower{ get; }
public abstract string Name{ get; }
public abstract string ShortDescription{ get; }
}
public interface IGear{
float Direction{ get; }
float Radius{ get; }
float InternalStopMoment{ get; }
float ExternalStopMoment{ get; set; }
float Torque{ get; }
float Rpm{ get; }
}
public interface IMotor{
}
public class GearJoint{
private IGear _a;
private IGear _b;
private float _ratio;
public GearJoint(IGear a, IGear b){
_a = a;
_b = b;
_ratio = _a.Radius / _b.Radius;
}
public void Solve(){
//сначала обмениваемся стоп моментами чтобы понять есть ли преодолевшие его движки
_b.ExternalStopMoment = (_a.InternalStopMoment / _ratio);
_a.ExternalStopMoment = (_b.InternalStopMoment * _ratio);
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 412239d2566c97c4b9f8222fd26b1205
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+9
View File
@@ -0,0 +1,9 @@
using UnityEngine;
using System.Collections;
public static class CarMath {
public static float Drag(float environmentDensity, float velocity, float dragCoeff, float area){
return 0.5f * environmentDensity * (velocity * velocity) * dragCoeff * area;
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8ad7d95a56657c14c884da9586f8b794
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+23
View File
@@ -0,0 +1,23 @@
using UnityEngine;
using System.Collections;
public class CarSuspension : MonoBehaviour {
public float suspensionDistance = 0.2f;
public float targetPosition = 0.2f;
public float suspensionSpring = 35000.0f;
public float suspensionDamper = 4500.0f;
private float _suspensionForce;
private float previousLength = 0.0f;
private float currentLength = 0.0f;
private float _currentSuspensionPosition = 1;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 462523a99a69aab48ac5f29cd7e52713
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+414
View File
@@ -0,0 +1,414 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/*
public class CarWheelHit{
public Vector3 point;
public Vector3 normal;
}
public class CarWheelCollider : MonoBehaviour {
public float wheelRadius = 0.33f;
public float _steerAngle;
public bool DrawDebug = true;
[ContextMenuItem("Reset coeffs", "resetPacejkaCoeffs")]
public PacejkaCoeffs _coeffs = new PacejkaCoeffs();
private Rigidbody _chassisRigidBody;
*/
/*private CarWheelHit _hit = new CarWheelHit();
private bool _isGrounded;
private Vector3 _relativePosition; //Relative to car body
private Vector3 _velocity;
private Vector3 _localVelocity;
public float camber;
private Vector3 _friction = new Vector3 ();
public float _appliedTorque;
private Vector2 _slip; //X = lateral, Y = longitudinal
private Vector3 _peakSlip;
private float _driveTorque;
private float _breakTorque;*/
/*
private DriveShaft _driveShaft = new DriveShaft();
private void resetPacejkaCoeffs() {
_coeffs = new PacejkaCoeffs();
}
*/
/*public float SteerAngle {
get {
return _steerAngle;
}
set {
_steerAngle = value;
}
}*/
/*void SetTorque(float torque, float dt){
_driveShaft.applyMomentum(torque * dt);
}
float RPM{
get{return _driveShaft.AngularVelocity * 30.0f / 3.141593f;}
}
void Integrate(float dt){
_driveShaft.integrate(dt);
}
private void UpdateRelativePosition(){
_relativePosition = _chassisRigidBody.transform.InverseTransformPoint (transform.position);
}
// Use this for initialization
void Start () {
_chassisRigidBody = FindFirstParentRigidBody ();
UpdateRelativePosition ();
//_breakTorque = 10000;
float tire_mass = 4.0f;
float rim_mass = 15.0f;
float rim_radius = 0.331f;
float tire_radius = 0.556f;
float tire_inertia = tire_mass * tire_radius * tire_radius;
float rim_inertia = rim_mass * rim_radius * rim_radius;
SetInertia(tire_inertia + rim_inertia);
}
void SetInertia(float value)
{
_driveShaft.Inv_inertia = 1.0f / value;
}
private void UpdateSlipAngles(){
_localVelocity = transform.InverseTransformDirection (_velocity);
Quaternion q = Quaternion.AngleAxis (-SteerAngle, transform.up);
var trs = Matrix4x4.TRS (Vector3.zero, q, Vector3.one);
_localVelocity = trs.MultiplyPoint3x4 (_localVelocity);
float rot_velocity = AngularVelocity * wheelRadius;
float lon_velocity = _localVelocity.z;
float lat_velocity = _localVelocity.x;
float lon_slip_velocity = lon_velocity - rot_velocity;
if (Mathf.Abs (lon_slip_velocity) <= 1.0e-4f)
{
_slip = Vector2.zero;
return;
}
float denom = Mathf.Max(Mathf.Abs(lon_velocity), 1e-0f);
_slip.x = -lon_slip_velocity / denom;
_slip.y = Mathf.Atan(lat_velocity / denom);
}
private void UpdateFriction(){
float surfaceFriction = 0.9f;
var normalForce = 4000.0f;// Mathf.Clamp(-_suspensionForce, 0, 10000);
if(normalForce * surfaceFriction < 0.00001f){
_peakSlip = Vector3.one;
_friction = Vector3.zero;
return;
}
//compute Pacejka params
var lateralParams = Pacejka.LateralParams(normalForce, camber, _coeffs);
var longitudinalParams = Pacejka.LongitudinalParams(normalForce, _coeffs);
var aligningParams = Pacejka.AligningParams(normalForce, camber, _coeffs);
_peakSlip.x = Pacejka.Extremum(longitudinalParams);
_peakSlip.y = Pacejka.Extremum(lateralParams);
_peakSlip.z = Pacejka.Extremum(aligningParams);
float epsilon = 0.000001f;
Vector3 slip = new Vector3();
if(Mathf.Abs(_peakSlip.x) >= epsilon){
slip.x = _slip.x / _peakSlip.x;
}
if(Mathf.Abs(_peakSlip.y) >= epsilon){
slip.y = _slip.y / _peakSlip.y;
}
if(Mathf.Abs(_peakSlip.z) >= epsilon){
slip.z = _slip.y / _peakSlip.z;
}
//Combined friction (friction circle)
float slip_xy = new Vector3 (slip.x, slip.y, 0.0f).magnitude;
float slip_xz = new Vector3 (slip.x, 0.0f, slip.z).magnitude;
if ((Mathf.Abs(normalForce) > epsilon) && (_localVelocity.magnitude > 0.001f)) {
_friction.x = Pacejka.MagicFormula(Mathf.Sign(slip.x) * slip_xy * _peakSlip.x, longitudinalParams) * surfaceFriction;
_friction.y = Pacejka.MagicFormula(Mathf.Sign(slip.y) * slip_xy * _peakSlip.y, lateralParams) * surfaceFriction;
_friction.z = Pacejka.MagicFormula(slip_xz * _peakSlip.z, aligningParams) * surfaceFriction;
if (slip_xy > epsilon)
{
_friction.x *= Mathf.Abs (slip.x) / slip_xy;
_friction.y *= Mathf.Abs (slip.y) / slip_xy;
}
if (slip_xz > epsilon)
_friction.z *= slip.z / slip_xz;
}else{
_friction = Vector3.zero;
}
}
public float AngularVelocity{
get{return _driveShaft.AngularVelocity;}
}
public void FixedUpdate(){
UpdateRelativePosition ();
Quaternion q = Quaternion.AngleAxis (SteerAngle, transform.up);
var trs = Matrix4x4.TRS (Vector3.zero, q, Vector3.one);
var right = trs.MultiplyPoint3x4 (transform.right).normalized;
var forward = trs.MultiplyPoint3x4 (transform.forward).normalized;
//get wheel joint velocity
_velocity = _chassisRigidBody.GetPointVelocity (transform.position);
UpdateSlipAngles ();
UpdateFriction ();
*/
/*var raycastRay = new Ray (transform.position, -transform.up);
RaycastHit rayHit;
if (Physics.Raycast (raycastRay, out rayHit)) {
if(rayHit.distance <= (wheelRadius + suspensionDistance)){
_isGrounded = true;
currentLength = 1.0f - (rayHit.distance - wheelRadius) / suspensionDistance;
_suspensionForce = suspensionSpring * (targetPosition - currentLength) + suspensionDamper * (previousLength - currentLength) / Time.fixedDeltaTime;
//_chassisRigidBody.AddForceAtPosition(rayHit.normal * -_suspensionForce, transform.position);
previousLength = currentLength;
_hit.point = rayHit.point;
_hit.normal = rayHit.normal;
var friction = forward * _friction.x- right * _friction.y;
var frictionTorque = _friction.x * wheelRadius;
var reaction_torque = frictionTorque;
var applied_torque = _driveTorque + _breakTorque;
if ( ( applied_torque > 0 && reaction_torque > applied_torque ) ||
( applied_torque < 0 && reaction_torque < applied_torque ) )
reaction_torque = applied_torque;
var tire_torque = right * reaction_torque;
float matFriction = 0.8f;
float rolling = 0;// matFriction * (0.0136f + 0.4e-7f * AngularVelocity * AngularVelocity);
float rolling_resistance_torque = rolling * wheelRadius - frictionTorque;
float wheel_torque = _driveTorque + _breakTorque + rolling_resistance_torque;
this.SetTorque(wheel_torque, Time.fixedDeltaTime);
this.Integrate(Time.fixedDeltaTime);
_chassisRigidBody.AddForceAtPosition(friction, rayHit.point);
//_chassisRigidBody.AddForceAtPosition(forward * _friction.x, transform.position);
}else{
currentLength = suspensionDistance;
previousLength = currentLength;
_isGrounded = false;
_friction = Vector3.zero;
}
}
else{
currentLength = suspensionDistance;
previousLength = currentLength;
_isGrounded = false;
_friction = Vector3.zero;
}
_currentSuspensionPosition = currentLength;*/
/*}
private Rigidbody FindFirstParentRigidBody(){
var currentTransform = transform;
while (true) {
var parent = currentTransform.parent;
if(parent == null){
return null;
}
var rb = parent.gameObject.GetComponent<Rigidbody>();
if(rb != null){
return rb;
}
currentTransform = parent;
}
}
// Update is called once per frame
void Update () {
}
void OnGUI(){
int id = int.Parse (name [name.Length - 1].ToString ());
SteerAngle = GUI.HorizontalSlider (new Rect(10, 20 * id, 100,20), SteerAngle, -30, 30);
GUI.Label (new Rect (120, 20 * id, 100, 20), SteerAngle.ToString());
}
void OnDrawGizmosSelected(){
if (!DrawDebug) {
return;
}
var p = _coeffs;
Curve[] curves = new Curve[]{new Curve(), new Curve(), new Curve()};
int sampleCnt = 150;
float minArg = -20;
float maxArg = 20;
float argDiff = maxArg - minArg;
for (int i = 0; i < sampleCnt; ++i) {
var arg = minArg + argDiff / ((float)sampleCnt - 1) * (float)i;
curves[0].AddArg(arg);
curves[1].AddArg(arg);
curves[2].AddArg(arg);
curves[0].AddVal(Pacejka.LongitudinalForce (5000.0f, arg, p));
curves[1].AddVal(Pacejka.LateralForce (5000.0f, camber, arg, p));
curves[2].AddVal(Pacejka.AligningForce (5000.0f, camber, arg, p));
}
Tools.BeginGui ();
Plot2D plot = new Plot2D(curves[1]);
//Slip.peak_slip(
plot.Title = "Longitudinal friction";
plot.OnGUI(new Rect(90,100,500,400));
camber = GUI.HorizontalSlider (new Rect (10, 10, 100, 10), camber, -10, 10);
Tools.EndGui ();
}*/
//void OnDrawGizmos(){
//_suspensionForce = 5000.0f;
//UpdateSlipAngles ();
//UpdateFriction ();
/*if (suspensionDistance < 0.01f) {
suspensionDistance = 0.01f;
}*/
/*if (wheelRadius < 0.01f) {
wheelRadius = 0.01f;
}
//targetPosition = Mathf.Clamp01 (targetPosition);
Vector3 wheelPosition;
Vector3 bottom;
*/
/*if (Application.isPlaying) {
wheelPosition = transform.position - transform.up.normalized * (1 - _currentSuspensionPosition) * suspensionDistance;
}else{
wheelPosition = transform.position;
}*/
//bottom = transform.position - transform.up.normalized * suspensionDistance;
/*float kSuspW = 0.1f;
float suspHW = wheelRadius * kSuspW * 0.5f;
Quaternion q = Quaternion.AngleAxis (SteerAngle, transform.up);
var trs = Matrix4x4.TRS (Vector3.zero, q, Vector3.one);
var right = trs.MultiplyPoint3x4 (transform.right);
var forward = trs.MultiplyPoint3x4 (transform.forward);
*/
/*Gizmos.color = Color.red;
//draw suspension
Gizmos.DrawLine (transform.position, bottom);
Gizmos.DrawLine (transform.position - forward * suspHW * 1.5f, transform.position + forward * suspHW* 1.5f);
Gizmos.DrawLine (bottom - forward * suspHW, bottom + forward * suspHW);
*/
/*var colliderColor = new Color (0, 1, 0, 0.5f);
Gizmos.color = colliderColor;
//draw wheel radius
var wheelCenter = transform.position;
var rollMatrix = Matrix4x4.TRS (Vector3.zero, Quaternion.AngleAxis(_driveShaft.Angle * Mathf.Rad2Deg, right), Vector3.one);
var radiusP0 = -forward * wheelRadius;
var radiusP1 = forward * wheelRadius * 1.2f;
radiusP0 = rollMatrix.MultiplyPoint3x4 (radiusP0);
radiusP1 = rollMatrix.MultiplyPoint3x4 (radiusP1);
Gizmos.DrawLine (wheelCenter + radiusP0, wheelCenter + radiusP1);
*/
//draw wheel circle
//AdvancedGizmo.DrawCircle (wheelCenter, right, wheelRadius, colliderColor, 36);
//draw force point
/*var wheelBottom = wheelCenter - transform.up * wheelRadius;
AdvancedGizmo.DrawCircle (wheelBottom, forward, wheelRadius * kSuspW, colliderColor);
AdvancedGizmo.DrawCircle (wheelBottom, right, wheelRadius * kSuspW, colliderColor);
AdvancedGizmo.DrawCircle (wheelBottom, transform.up, wheelRadius * kSuspW, colliderColor);
*/
//draw friction
/*Gizmos.color = Color.red;
Gizmos.DrawLine (transform.position, transform.position + forward * _friction.x);
//draw wheel velocity
Gizmos.color = colliderColor;
Gizmos.DrawLine (transform.position, transform.position + _velocity);
var p = Camera.current.WorldToScreenPoint (transform.position + Vector3.up);
p.y = Camera.current.pixelHeight - p.y;
Tools.BeginGui ();
var labelRect = new Rect (p.x, p.y, 90, 20);
Tools.DrawRectangle (labelRect, new Color(0,0,0,0.5f));
GUI.Label (new Rect (p.x, p.y, 100, 100), _friction.x.ToString ());
Tools.EndGui ();
}*/
//}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2d2045ac6b2191949ba985c5f8d8cf23
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+15
View File
@@ -0,0 +1,15 @@
using UnityEngine;
using System.Collections;
public class CarWheelDebugger : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: cd0e2d6bdf207664db5eb88eb19512aa
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+19
View File
@@ -0,0 +1,19 @@
using UnityEngine;
using System.Collections;
public class CenterOfMass : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnDrawGizmos(){
Gizmos.DrawWireCube (transform.position, new Vector3 (0.1f, 0.1f, 0.1f));
}
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 08c70305f88768c47ae1f6179c937806
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+26
View File
@@ -0,0 +1,26 @@
using UnityEngine;
using System.Collections;
public class Clutch : MonoBehaviour {
public CarEngine engine;
public Gearbox gearbox;
private float _pressure = 1.0f;
public float Pressure{
get{ return _pressure;}
set{
_pressure = Mathf.Clamp01(value);
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b9a5d0ceff39c2d4da746187c752d66f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
+14
View File
@@ -0,0 +1,14 @@
using UnityEngine;
using System.Collections;
public static class ColorEx {
public static string ToHex(this Color color)
{
return string.Format("#{0}{1}{2}{3}",
(((int)(color.r * 255.0f))&0xff).ToString("X2"),
(((int)(color.g * 255.0f))&0xff).ToString("X2"),
(((int)(color.b * 255.0f))&0xff).ToString("X2"),
(((int)(color.a * 255.0f))&0xff).ToString("X2"));
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ca64549d1cac22a419dcfbc203873c0e
timeCreated: 1461872157
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
using UnityEngine;
using System.Collections;
public class ConstantAngularSpeed : MonoBehaviour
{
public Vector3 angularVelocity;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void FixedUpdate()
{
GetComponent<Rigidbody>().angularVelocity = angularVelocity;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cdaa4477408108745b8d01968739a76a
timeCreated: 1430743113
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
using UnityEngine;
using System.Collections;
public class Curve : MonoBehaviour {
public virtual float Sample(float arg)
{
return 0.0f;
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 917382405abb03e478b65ea3b7c5b2b3
timeCreated: 1454257651
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+6
View File
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 4013a7cdee5e4ce478b06ca99a16009c
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
@@ -0,0 +1,30 @@
using UnityEngine;
using System.Collections;
public class ConstantForce : MonoBehaviour {
public Vector3 force;
public Rigidbody body;
public float maxSpeed = 1000;
public bool localSpace = true;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
if (body != null) {
var vel = body.velocity.magnitude;
if(vel < maxSpeed) {
if(localSpace) {
var f = transform.TransformDirection(force);
body.AddForce(f);
} else {
body.AddForce(force);
}
}
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 3052e159dd821b343b26054f95fee9fd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,23 @@
using UnityEngine;
using System.Collections;
public class ConstantVelocity : MonoBehaviour {
public Rigidbody target;
public Vector3 velocity = Vector3.forward;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void FixedUpdate() {
if (target != null) {
target.velocity = velocity;
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2447c867112e08944a68a1b2a72389f4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: -100
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,35 @@
using UnityEngine;
using System.Collections;
using System.Linq;
public class DebugSpeedometer : MonoBehaviour
{
public WheelPhysics[] wheels;
public Rigidbody car;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnGUI()
{
float speed_ms = 0;
if (wheels != null)
{
speed_ms = Mathf.Abs((float)wheels.Select(v => v.angularVelocity*v.TotalWheelRadius).Sum() / wheels.Length);
}
var speed_kmph = (speed_ms*60.0f*60.0f)/1000.0f;
var car_speed = car.velocity.magnitude*3.6f;
GUI.Label(new Rect(20, 100, 200, 40), "Wheels speed [km/h]: " + speed_kmph);
GUI.Label(new Rect(20, 140, 200, 40), "Real speed [km/h]: " + car_speed);
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f076152b0f182a946abb77db1b200bbb
timeCreated: 1453672668
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
using System.Collections;
public class GetPhysicsDeltaTime : MonoBehaviour {
public Rigidbody source;
private Vector3 lastPos;
// Use this for initialization
void Start () {
lastPos = source.position;
source.velocity = Vector3.forward;
}
// Update is called once per frame
void Update () {
}
// Update is called once per frame
void FixedUpdate() {
var currentPos = source.position;
var delta = currentPos - lastPos;
var distance = delta.magnitude;
lastPos = currentPos;
Debug.Log("Delta time = " + distance+ " Fixed delta: " + Time.fixedDeltaTime);
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 37b12b0ffde576c48976e47fb0d4ec9f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+17
View File
@@ -0,0 +1,17 @@
using UnityEditor;
using UnityEngine;
using System.Collections;
public static class Label3D {
/*
public static void AtWorldPosition(Vector3 position, string text) {
var screenPosition = Camera.main.WorldToScreenPoint(position);
screenPosition.y = Camera.main.pixelHeight - screenPosition.y;
var labelContent = new GUIContent(text);
var size = GUI.skin.label.CalcSize(new GUIContent(text));
var labelRect = new Rect(screenPosition.x, screenPosition.y, size.x, size.y);
Tools.DrawRectangle(labelRect, new Color(0,0,0,0.5f));
GUI.Label(labelRect, labelContent);
}*/
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 43b38c3c19f944d4b8c5fed125847963
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
@@ -0,0 +1,66 @@
using UnityEngine;
using System.Collections;
using System.Linq;
using System;
public class Plot2DVariableFunction : Plot2DFunction
{
public GameObject target;
public string variable;
// Use this for initialization
void Start ()
{
ReadValue();
}
public override float f(float x)
{
return ReadValue();
}
float ReadValue()
{
if (target != null) {
var pathBlocks = variable.Split('.');
var c = target.GetComponent(pathBlocks[0]);
if (c == null)
{
return 0;
}
//find target
int depth = 1;
object o = c;
System.Reflection.FieldInfo field = null ;
while (depth < pathBlocks.Length) {
var t = o.GetType();
field = t.GetField(pathBlocks[depth], System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
if (field == null)
{
return 0;
}
o = field.GetValue(o);
depth++;
}
try
{
float val = Convert.ToSingle(o);
return val;
}
catch
{
Debug.LogFormat("Failed to convert property {0} to float type!", field.Name);
}
}
return 0;
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 477c3138005e6c64da3d6bc84e51dec9
timeCreated: 1454231920
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,117 @@
using UnityEngine;
using System.Collections;
using System;
public class TyreCurvesView : MonoBehaviour
{
public OscilloscopeDisplay display;
public float Fz = 5000;
public bool autoVerticalScale = true;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
private void OnDrawGizmosSelected()
{
if (display == null)
{
return;
}
var tyre = GetComponent<Tyre>();
if (display.plot.channels.Length < 4) {
Array.Resize(ref display.plot.channels, 4);
}
int samplesCount = 400;
Color[] channel_colors = new[] {Color.red, Color.green, Color.blue};
double r = 0.33;
double r0 = r;
for (int i = 0; i < 3; ++i)
{
var channel = display.plot.channels[i];
channel.ResizeBuffers(samplesCount);
channel.SampleBufferPosition = samplesCount - 1;
channel.color = channel_colors[i];
if (autoVerticalScale)
{
channel.cellValue = Fz / display.halfYCellCount;
}
channel.cellTime = 1.0f / display.halfXCellCount;
if (i == 0){
for (int j = 0; j < samplesCount; ++j) {
float k = ((1.0f / (float)(samplesCount - 1)) * j) * 2.0f - 1.0f;
var Vc = new Double3(10, 0, 0);
var forces = Pacejka.CalcPacejka(Vc, (Vc.x + Vc.x * k) / r, r0, r, Fz, 0, tyre.pacejkaParams._coeffs2, false);
channel.SetSample(j, k, (float)forces.x);
}
} else if (i == 1) {
for (int j = 0; j < samplesCount; ++j) {
float k = ((1.0f / (float)(samplesCount - 1)) * j) * 2.0f - 1.0f;
Vector3 angle_zero = new Vector3(10, 0, 0);
Vector3 angle_90 = new Vector3(0, 10, 0);
Vector3 Vc = (Vector3.Lerp(angle_zero, angle_90, Mathf.Abs(k))*Mathf.Sign(k)).normalized * 10;
var forces = Pacejka.CalcPacejka(new Double3(Vc.x, Vc.y, Vc.z), 10.0 / r, r0, r, Fz, 0, tyre.pacejkaParams._coeffs2, false);
channel.SetSample(j, k, (float)forces.y);
}
} else if (i == 2) {
for (int j = 0; j < samplesCount; ++j) {
float k = ((1.0f / (float)(samplesCount - 1)) * j) * 2.0f - 1.0f;
Vector3 angle_zero = new Vector3(10, 0, 0);
Vector3 angle_90 = new Vector3(0, 10, 0);
Vector3 Vc = (Vector3.Lerp(angle_zero, angle_90, Mathf.Abs(k))).normalized * 10;
Vc.y *= Mathf.Sign(k);
var forces = Pacejka.CalcPacejka(new Double3(Vc.x, Vc.y, Vc.z), 10.0 / r, r0, r, Fz, 0, tyre.pacejkaParams._coeffs2, false);
channel.SetSample(j, k, (float)forces.z);
}
}
}
//draw friction circle
var combined_channel = display.plot.channels[3];
combined_channel.ResizeBuffers(samplesCount);
combined_channel.SampleBufferPosition = samplesCount - 1;
combined_channel.color = Color.white;
combined_channel.cellValue = combined_channel.cellTime = 3000 / display.halfYCellCount;
for (int j = 0; j < samplesCount; ++j) {
float k = ((1.0f / (float)(samplesCount - 1)) * j) * 2.0f - 1.0f;
// float k = ((1.0f / (float)(samplesCount - 1)) * j);
/*float angle = Mathf.PI*2.0f*k;
var v = new Vector3(Mathf.Sin(angle), Mathf.Cos(angle), 0) * 1000;
combined_channel.SetSample(j, (float)v.x, (float)v.y);*/
Vector3 angle_zero = new Vector3(1, 0, 0);
Vector3 angle_90 = new Vector3(0, 1, 0);
Vector3 Vc = (Vector3.Lerp(angle_zero, angle_90, Mathf.Abs(k)) ).normalized * 10;
Vc.y *= Mathf.Sign(k);
var forces = Pacejka.CalcPacejka(new Double3(Vc.x, Vc.y, Vc.z), 8.0 / r, r0, r, Fz, 0, tyre.pacejkaParams._coeffs2, true);
combined_channel.SetSample(j, (float)forces.x, (float)forces.y);
// combined_channel.SetSample(j, k * 3000, (float)forces.x);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 68fb46041ea99004b9edd5d7fc9133da
timeCreated: 1453127428
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+13
View File
@@ -0,0 +1,13 @@
using UnityEngine;
using System.Collections;
public static class GameObjectEx {
public static Vector3 GetEulerAnglesLocal(this GameObject obj){
return obj.transform.localEulerAngles;
}
public static Vector3 SetEulerAnglesLocal(this GameObject obj, Vector3 angles){
return obj.transform.localEulerAngles = angles;
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 46281f2baa585724aafa4fc416a1ff24
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
+57
View File
@@ -0,0 +1,57 @@
using UnityEngine;
using System.Collections;
public enum Gears{
Rear = -1,
Neutral = 0,
Gear1 = 1,
Gear2 = 2,
Gear3 = 3,
Gear4 = 4,
Gear5 = 5
}
public class GearboxDefault : Gearbox {
private float[] _gearRatios = new float[]{3.5f, 0.0f, 3.636f, 1.95f, 1.375f, 0.941f, 0.784f};
private int _currentGear = (int)Gears.Neutral;
public override float GetGearRatio (int gear)
{
throw new System.NotImplementedException ();
}
public override int Gear{
get{ return _currentGear;}
set{
if (_currentGear != value) {
_currentGear = value;
Debug.Log("Set gear to: " + (Gears)_currentGear);
}
}
}
public override GearboxControlType ControlType {
get {
return GearboxControlType.Manual;
}
}
public override float MaxOutputTorque {
get {
return 600.0f;
}
}
public override int GearsCount {get {return _gearRatios.Length;}}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e5ee2c816bfcf0b4fa4d39b321073968
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:

Some files were not shown because too many files have changed in this diff Show More