0% found this document useful (0 votes)
71 views27 pages

Wheel Collider

Uploaded by

badobe2789
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views27 pages

Wheel Collider

Uploaded by

badobe2789
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

...alisticCarControllerV3\Scripts\RCC_WheelCollider.

cs 1
1 //----------------------------------------------
2 // Realistic Car Controller
3 //
4 // Copyright © 2014 - 2023 BoneCracker Games
5 // https://www.bonecrackergames.com
6 // Buğra Özdoğanlar
7 //
8 //----------------------------------------------
9
10
11 using UnityEngine;
12 using System.Linq;
13 using System.Collections;
14 using System.Collections.Generic;
15
16 /// <summary>
17 /// Based on Unity's WheelCollider. Modifies forward and sideways
curves, settings in order to get stable and realistic physics
depends on selected behavior in RCC Settings.
18 /// </summary>
19 [RequireComponent(typeof(WheelCollider))]
20 [AddComponentMenu("BoneCracker Games/Realistic Car Controller/Main/RCC
Wheel Collider")]
21 public class RCC_WheelCollider : RCC_Core {
22
23 #region OBSOLETE VARIABLES
24
25 [System.Obsolete("Use CarController instead of carController")]
26 public RCC_CarControllerV3 carController {
27
28 get {
29
30 return CarController;
31
32 }
33
34 }
35
36 [System.Obsolete("Use WheelCollider instead of wheelCollider")]
37 public WheelCollider wheelCollider {
38
39 get {
40
41 return WheelCollider;
42
43 }
44
45 }
46
47 [System.Obsolete("Use Rigid instead of rigid")]
48 public Rigidbody rigid {
49
50 get {
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 2
51
52 return Rigid;
53
54 }
55
56 }
57
58 #endregion
59
60 // Car controller.
61 public RCC_CarControllerV3 CarController {
62 get {
63 if (_carController == null)
64 _carController =
GetComponentInParent<RCC_CarControllerV3>();
65 return _carController;
66 }
67 }
68 private RCC_CarControllerV3 _carController;
69
70 // WheelCollider.
71 public WheelCollider WheelCollider {
72 get {
73 if (_wheelCollider == null)
74 _wheelCollider = GetComponent<WheelCollider>();
75 return _wheelCollider;
76 }
77 }
78 private WheelCollider _wheelCollider;
79
80 // Rigidbody of the vehicle.
81 private Rigidbody Rigid {
82 get {
83 if (_rigid == null)
84 _rigid = CarController.Rigid;
85 return _rigid;
86 }
87 }
88 private Rigidbody _rigid;
89
90 public Transform wheelModel; // Wheel model for animating
and aligning.
91
92 public WheelHit wheelHit; // Wheelhit data.
93 public bool isGrounded = false; // Is wheel grounded or not?
94 public int groundIndex = 0; // Current ground index of
wheelhit.
95
96 public bool alignWheel = true; // Align the wheelmodel with
wheelcollider position and rotation.
97 public bool drawSkid = true; // Draw skidmarks.
98
99 // Locating correct position and rotation for the wheel.
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 3
100 [HideInInspector] public Vector3 wheelPosition = Vector3.zero;
101 [HideInInspector] public Quaternion wheelRotation =
Quaternion.identity;
102
103 [Space()]
104 public bool canPower = false; // Can this wheel apply
power?
105 [Range(-1f, 1f)] public float powerMultiplier = 1f;
106 public bool canSteer = false; // Can this wheel apply
steer?
107 [Range(-1f, 1f)] public float steeringMultiplier = 1f;
108 public bool canBrake = false; // Can this wheel apply
brake?
109 [Range(0f, 1f)] public float brakingMultiplier = 1f;
110 public bool canHandbrake = false; // Can this wheel apply
handbrake?
111 [Range(0f, 1f)] public float handbrakeMultiplier = 1f;
112
113 [Space()]
114 public float wheelWidth = .275f; // Width of the wheel.
115 public float wheelOffset = 0f; // Offset by X axis.
116
117 private float wheelRPM2Speed = 0f; // Wheel RPM to Speed in
km/h unit.
118
119 [Space()]
120 [Range(-5f, 5f)] public float camber = 0f; // Camber angle.
121 [Range(-5f, 5f)] public float caster = 0f; // Caster angle.
122 [Range(-5f, 5f)] public float toe = 0f; // Toe angle.
123 [Space()]
124
125 // Skidmarks
126 private int lastSkidmark = -1;
127
128 // Slips
129 [HideInInspector] public float wheelSlipAmountForward =
0f; // Forward slip.
130 [HideInInspector] public float wheelSlipAmountSideways = 0f; //
Sideways slip.
131 [HideInInspector] public float totalSlip =
0f; // Total amount of forward and
sideways slips.
132
133 // WheelFriction Curves and Stiffness.
134 private WheelFrictionCurve forwardFrictionCurve; //
Forward friction curve.
135 private WheelFrictionCurve sidewaysFrictionCurve; // Sideways
friction curve.
136
137 // Original WheelFriction Curves and Stiffness.
138 private WheelFrictionCurve forwardFrictionCurve_Org; //
Forward friction curve original.
139 private WheelFrictionCurve sidewaysFrictionCurve_Org; //
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 4
Sideways friction curve original.
140
141 // Audio
142 private AudioSource audioSource; // Audiosource for tire
skid SFX.
143 private AudioClip audioClip; // Audioclip for
tire skid SFX.
144 private float audioVolume = 1f; // Maximum volume for
tire skid SFX.
145
146 // List for all particle systems.
147 [HideInInspector] public List<ParticleSystem> allWheelParticles =
new List<ParticleSystem>();
148 private ParticleSystem.EmissionModule emission;
149
150 // Tractions used for smooth drifting.
151 [HideInInspector] public float tractionHelpedSidewaysStiffness =
1f;
152 private readonly float minForwardStiffness = .9f;
153 private readonly float maxForwardStiffness = 1f;
154 private readonly float minSidewaysStiffness = .5f;
155 private readonly float maxSidewaysStiffness = 1f;
156
157 // Getting bump force.
158 [HideInInspector] public float bumpForce, oldForce, RotationValue
= 0f;
159
160 private bool deflated = false; // Deflated or not?
161
162 [Space()]
163 public float deflateRadiusMultiplier = .8f; // Deflated
radius multiplier. Radius of the wheelcollider will be multiplied
by this value on deflate.
164 public float deflatedStiffnessMultiplier = .5f; // Deflated
stiffness of the wheelcollider.
165 private float defRadius = -1f; // Original radius of the
wheelcollider.
166
167 // Getting audioclips from the RCC Settings.
168 public AudioClip DeflateAudio {
169
170 get {
171
172 return RCC_Settings.Instance.wheelDeflateClip;
173
174 }
175
176 }
177 public AudioClip InflateAudio {
178
179 get {
180
181 return RCC_Settings.Instance.wheelInflateClip;
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 5
182
183 }
184
185 }
186
187 private AudioSource flatSource;
188 public AudioClip FlatAudio {
189
190 get {
191
192 return RCC_Settings.Instance.wheelFlatClip;
193
194 }
195
196 }
197
198 private ParticleSystem _wheelDeflateParticles;
199 public ParticleSystem WheelDeflateParticles {
200
201 get {
202
203 return
RCC_Settings.Instance.wheelDeflateParticles.GetComponent<
ParticleSystem>();
204
205 }
206
207 }
208
209 private void Start() {
210
211 // Increasing wheelcollider mass for avoiding unstable
behavior.
212 if (RCC_Settings.Instance.useFixedWheelColliders)
213 WheelCollider.mass = Rigid.mass / 15f;
214
215 CreatePivotOfTheWheel();
216 UpdateWheelFrictions();
217 OverrideWheelSettings();
218 CreateAudio();
219 CreateParticles();
220
221 }
222
223 /// <summary>
224 /// Creating pivot point of the wheel.
225 /// </summary>
226 private void CreatePivotOfTheWheel() {
227
228 // Creating pivot position of the wheel at correct position
and rotation.
229 GameObject newPivot = new GameObject("Pivot_" +
wheelModel.transform.name);
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 6
230 newPivot.transform.position = RCC_GetBounds.GetBoundsCenter
(wheelModel.transform);
231 newPivot.transform.rotation = transform.rotation;
232 newPivot.transform.SetParent(wheelModel.transform.parent,
true);
233
234 // Assigning temporary created wheel to actual wheel.
235 wheelModel.SetParent(newPivot.transform, true);
236 wheelModel = newPivot.transform;
237
238 }
239
240 /// <summary>
241 /// Creating pacticles.
242 /// </summary>
243 private void CreateParticles() {
244
245 if (RCC_Settings.Instance.dontUseAnyParticleEffects)
246 return;
247
248 for (int i = 0; i <
RCC_GroundMaterials.Instance.frictions.Length; i++) {
249
250 GameObject ps = Instantiate
(RCC_GroundMaterials.Instance.frictions
[i].groundParticles, transform.position,
transform.rotation);
251 emission = ps.GetComponent<ParticleSystem>().emission;
252 emission.enabled = false;
253 ps.transform.SetParent(transform, false);
254 ps.transform.localPosition = Vector3.zero;
255 ps.transform.localRotation = Quaternion.identity;
256 allWheelParticles.Add(ps.GetComponent<ParticleSystem>());
257
258 }
259
260 }
261
262 /// <summary>
263 /// Creating audiosource.
264 /// </summary>
265 private void CreateAudio() {
266
267 // Creating audiosource for skid SFX.
268 audioSource = NewAudioSource(RCC_Settings.Instance.audioMixer,
CarController.gameObject, "Skid Sound AudioSource", 5f,
50f, 0f, audioClip, true, true, false);
269 audioSource.transform.position = transform.position;
270
271 }
272
273 /// <summary>
274 /// Overriding wheel settings.
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 7
275 /// </summary>
276 private void OverrideWheelSettings() {
277
278 // Override wheels automatically if enabled.
279 if (!CarController.overrideAllWheels) {
280
281 // Overriding canPower, canSteer, canBrake, canHandbrake.
282 if (this == CarController.FrontLeftWheelCollider || this
== CarController.FrontRightWheelCollider) {
283
284 canSteer = true;
285 canBrake = true;
286 brakingMultiplier = 1f;
287
288 }
289
290 // Overriding canPower, canSteer, canBrake, canHandbrake.
291 if (this == CarController.RearLeftWheelCollider || this ==
CarController.RearRightWheelCollider) {
292
293 canHandbrake = true;
294 canBrake = true;
295 brakingMultiplier = .75f;
296
297 }
298
299 }
300
301 }
302
303 private void OnEnable() {
304
305 // Listening an event when main behavior changed.
306 RCC_SceneManager.OnBehaviorChanged += UpdateWheelFrictions;
307
308 // If wheel model is assigned but not enabled, enable it.
309 if (wheelModel && !wheelModel.gameObject.activeSelf)
310 wheelModel.gameObject.SetActive(true);
311
312 // Resetting values on enable.
313 wheelSlipAmountForward = 0f;
314 wheelSlipAmountSideways = 0f;
315 totalSlip = 0f;
316 bumpForce = 0f;
317 oldForce = 0f;
318
319 if (audioSource) {
320
321 audioSource.volume = 0f;
322 audioSource.Stop();
323
324 }
325
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 8
326 WheelCollider.motorTorque = 0f;
327 WheelCollider.brakeTorque = 0f;
328 WheelCollider.steerAngle = 0f;
329
330 }
331
332 /// <summary>
333 /// Checks the selected behavior in RCC Settings and applies
changes.
334 /// </summary>
335 private void UpdateWheelFrictions() {
336
337 // Getting forward and sideways frictions of the
wheelcollider.
338 forwardFrictionCurve = WheelCollider.forwardFriction;
339 sidewaysFrictionCurve = WheelCollider.sidewaysFriction;
340
341 // Getting behavior if selected.
342 RCC_Settings.BehaviorType behavior =
RCC_Settings.Instance.selectedBehaviorType;
343
344 // If there is a selected behavior, override friction curves.
345 if (!CarController.overrideBehavior && behavior != null) {
346
347 forwardFrictionCurve = SetFrictionCurves
(forwardFrictionCurve, behavior.forwardExtremumSlip,
behavior.forwardExtremumValue,
behavior.forwardAsymptoteSlip,
behavior.forwardAsymptoteValue);
348 sidewaysFrictionCurve = SetFrictionCurves
(sidewaysFrictionCurve, behavior.sidewaysExtremumSlip,
behavior.sidewaysExtremumValue,
behavior.sidewaysAsymptoteSlip,
behavior.sidewaysAsymptoteValue);
349
350 }
351
352 // Assigning new frictons.
353 WheelCollider.forwardFriction = forwardFrictionCurve;
354 WheelCollider.sidewaysFriction = sidewaysFrictionCurve;
355
356 // Override original frictions.
357 forwardFrictionCurve_Org = WheelCollider.forwardFriction;
358 sidewaysFrictionCurve_Org = WheelCollider.sidewaysFriction;
359
360 }
361
362 private void Update() {
363
364 // Return if RCC is disabled.
365 if (!CarController.enabled)
366 return;
367
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 9
368 // Setting position and rotation of the wheel model.
369 if (alignWheel)
370 WheelAlign();
371
372 }
373
374 private void FixedUpdate() {
375
376 // Return if RCC is disabled.
377 if (!CarController.enabled)
378 return;
379
380 float circumFerence = 2.0f * 3.14f * WheelCollider.radius; //
Finding circumFerence 2 Pi R.
381 wheelRPM2Speed = (circumFerence * WheelCollider.rpm) * 60f; //
Finding MPH and converting to KMH.
382 wheelRPM2Speed = Mathf.Clamp(wheelRPM2Speed / 1000f, 0f,
Mathf.Infinity);
383
384 // Setting power state of the wheels depending on drivetrain
mode. Only overrides them if overrideWheels is enabled for
the vehicle.
385 if (!CarController.overrideAllWheels) {
386
387 switch (CarController.wheelTypeChoise) {
388
389 case RCC_CarControllerV3.WheelType.AWD:
390 canPower = true;
391 break;
392
393 case RCC_CarControllerV3.WheelType.BIASED:
394 canPower = true;
395 break;
396
397 case RCC_CarControllerV3.WheelType.FWD:
398
399 if (this == CarController.FrontLeftWheelCollider
|| this == CarController.FrontRightWheelCollider)
400 canPower = true;
401 else
402 canPower = false;
403
404 break;
405
406 case RCC_CarControllerV3.WheelType.RWD:
407
408 if (this == CarController.RearLeftWheelCollider ||
this == CarController.RearRightWheelCollider)
409 canPower = true;
410 else
411 canPower = false;
412
413 break;
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 10
414
415 }
416
417 }
418
419 GroundMaterial();
420 Frictions();
421 TotalSlip();
422 SkidMarks();
423 Particles();
424 Audio();
425 CheckDeflate();
426 ESP();
427
428 }
429
430 /// <summary>
431 /// ESP System. All wheels have individual brakes. In case of
loosing control of the vehicle, corresponding wheel will brake
for gaining the control again.
432 /// </summary>
433 private void ESP() {
434
435 if (CarController.ESP && CarController.brakeInput < .5f) {
436
437 if (CarController.handbrakeInput < .5f) {
438
439 if (CarController.underSteering) {
440
441 if (this == CarController.FrontLeftWheelCollider)
442 ApplyBrakeTorque((CarController.brakeTorque *
CarController.ESPStrength) * Mathf.Clamp(-
CarController.rearSlip, 0f, Mathf.Infinity));
443
444 if (this == CarController.FrontRightWheelCollider)
445 ApplyBrakeTorque((CarController.brakeTorque *
CarController.ESPStrength) * Mathf.Clamp
(CarController.rearSlip, 0f, Mathf.Infinity));
446
447 }
448
449 if (CarController.overSteering) {
450
451 if (this == CarController.RearLeftWheelCollider)
452 ApplyBrakeTorque((CarController.brakeTorque *
CarController.ESPStrength) * Mathf.Clamp(-
CarController.frontSlip, 0f, Mathf.Infinity));
453
454 if (this == CarController.RearRightWheelCollider)
455 ApplyBrakeTorque((CarController.brakeTorque *
CarController.ESPStrength) * Mathf.Clamp
(CarController.frontSlip, 0f, Mathf.Infinity));
456
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 11
457 }
458
459 }
460
461 }
462
463 }
464
465 /// <summary>
466 /// Aligning wheel model position and rotation.
467 /// </summary>
468 private void WheelAlign() {
469
470 // Return if no wheel model selected.
471 if (!wheelModel) {
472
473 Debug.LogWarning(transform.name + " wheel of the " +
CarController.transform.name + " is missing wheel
model.");
474 return;
475
476 }
477
478 // Getting position and rotation of the wheelcollider and
assigning wheelPosition and wheelRotation.
479 WheelCollider.GetWorldPose(out wheelPosition, out
wheelRotation);
480
481 //Increase the rotation value.
482 RotationValue += WheelCollider.rpm * (360f / 60f) *
Time.deltaTime;
483
484 // Assigning position and rotation to the wheel model.
485 wheelModel.SetPositionAndRotation(wheelPosition,
transform.rotation * Quaternion.Euler(RotationValue,
WheelCollider.steerAngle, 0f));
486
487 // Adjusting camber angle by Z axis.
488 if (transform.localPosition.x < 0f)
489 wheelModel.transform.RotateAround
(wheelModel.transform.position, transform.forward, -
camber);
490 else
491 wheelModel.transform.RotateAround
(wheelModel.transform.position, transform.forward,
camber);
492
493 // Adjusting caster angle by X axis.
494 if (transform.localPosition.x < 0f)
495 wheelModel.transform.RotateAround
(wheelModel.transform.position, transform.right, -
caster);
496 else
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 12
497 wheelModel.transform.RotateAround
(wheelModel.transform.position, transform.right, caster);
498
499 }
500
501 /// <summary>
502 /// Drawing skidmarks if wheel is skidding.
503 /// </summary>
504 private void SkidMarks() {
505
506 // Return if not drawing skidmarks.
507 if (!drawSkid)
508 return;
509
510 // If scene has skidmarks manager...
511 if (!RCC_Settings.Instance.dontUseSkidmarks) {
512
513 // If slips are bigger than target value, draw the
skidmarks.
514 if (totalSlip > RCC_GroundMaterials.Instance.frictions
[groundIndex].slip) {
515
516 Vector3 skidPoint = wheelHit.point + 1f *
Time.deltaTime * (Rigid.velocity);
517
518 if (Rigid.velocity.magnitude > 1f && isGrounded &&
wheelHit.normal != Vector3.zero && wheelHit.point !=
Vector3.zero && skidPoint != Vector3.zero &&
Mathf.Abs(skidPoint.x) > 1f && Mathf.Abs(skidPoint.z)
> 1f)
519 lastSkidmark =
RCC_SkidmarksManager.Instance.AddSkidMark(skidPoint,
wheelHit.normal, totalSlip, wheelWidth, lastSkidmark,
groundIndex);
520 else
521 lastSkidmark = -1;
522
523 } else {
524
525 lastSkidmark = -1;
526
527 }
528
529 }
530
531 }
532
533 /// <summary>
534 /// Sets forward and sideways frictions.
535 /// </summary>
536 private void Frictions() {
537
538 // Handbrake input clamped 0f - 1f.
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 13
539 float hbInput = CarController.handbrakeInput;
540
541 if (canHandbrake && hbInput > .75f)
542 hbInput = .75f;
543 else
544 hbInput = 1f;
545
546 // Setting wheel stiffness to ground physic material
stiffness.
547 forwardFrictionCurve.stiffness =
RCC_GroundMaterials.Instance.frictions
[groundIndex].forwardStiffness;
548 sidewaysFrictionCurve.stiffness =
(RCC_GroundMaterials.Instance.frictions
[groundIndex].sidewaysStiffness * hbInput *
tractionHelpedSidewaysStiffness);
549
550 // If deflated, apply deflated stiffness.
551 if (deflated) {
552
553 forwardFrictionCurve.stiffness *=
deflatedStiffnessMultiplier;
554 sidewaysFrictionCurve.stiffness *=
deflatedStiffnessMultiplier;
555
556 }
557
558 // If drift mode is selected, apply specific frictions.
559 if (!CarController.overrideBehavior &&
RCC_Settings.Instance.selectedBehaviorType != null &&
RCC_Settings.Instance.selectedBehaviorType.applyExternalWhee
lFrictions)
560 Drift();
561
562 // Setting new friction curves to wheels.
563 WheelCollider.forwardFriction = forwardFrictionCurve;
564 WheelCollider.sidewaysFriction = sidewaysFrictionCurve;
565
566 // Also damp too.
567 WheelCollider.wheelDampingRate =
RCC_GroundMaterials.Instance.frictions[groundIndex].damp;
568
569 }
570
571 /// <summary>
572 /// Total amount of wheel slip.
573 /// </summary>
574 private void TotalSlip() {
575
576 // Forward, sideways, and total slips.
577 if (isGrounded && wheelHit.point != Vector3.zero) {
578
579 wheelSlipAmountForward = wheelHit.forwardSlip;
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 14
580 wheelSlipAmountSideways = wheelHit.sidewaysSlip;
581
582 } else {
583
584 wheelSlipAmountForward = 0f;
585 wheelSlipAmountSideways = 0f;
586
587 }
588
589 totalSlip = Mathf.Lerp(totalSlip, ((Mathf.Abs
(wheelSlipAmountSideways) + Mathf.Abs
(wheelSlipAmountForward)) / 2f), Time.fixedDeltaTime * 10f);
590
591 }
592
593 /// <summary>
594 /// Particles.
595 /// </summary>
596 private void Particles() {
597
598 if (RCC_Settings.Instance.dontUseAnyParticleEffects)
599 return;
600
601 // If wheel slip is bigger than ground physic material slip,
enable particles. Otherwise, disable particles.
602 for (int i = 0; i < allWheelParticles.Count; i++) {
603
604 if (totalSlip > RCC_GroundMaterials.Instance.frictions
[groundIndex].slip) {
605
606 if (i != groundIndex) {
607
608 ParticleSystem.EmissionModule em;
609
610 em = allWheelParticles[i].emission;
611 em.enabled = false;
612
613 } else {
614
615 ParticleSystem.EmissionModule em;
616
617 em = allWheelParticles[i].emission;
618 em.enabled = true;
619
620 }
621
622 } else {
623
624 ParticleSystem.EmissionModule em;
625
626 em = allWheelParticles[i].emission;
627 em.enabled = false;
628
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 15
629 }
630
631 if (isGrounded && wheelHit.point != Vector3.zero)
632 allWheelParticles[i].transform.position =
wheelHit.point + (.05f * transform.up);
633
634 }
635
636 }
637
638 /// <summary>
639 /// Drift.
640 /// </summary>
641 private void Drift() {
642
643 Vector3 relativeVelocity = transform.InverseTransformDirection
(Rigid.velocity);
644 float sqrVel = (relativeVelocity.x * relativeVelocity.x) /
50f;
645
646 if (wheelHit.forwardSlip > 0)
647 sqrVel += (Mathf.Abs(wheelHit.forwardSlip));
648
649 if (CarController.wheelTypeChoise ==
RCC_CarControllerV3.WheelType.RWD) {
650
651 // Forward
652 if (WheelCollider ==
CarController.FrontLeftWheelCollider.WheelCollider ||
WheelCollider ==
CarController.FrontRightWheelCollider.WheelCollider) {
653
654 forwardFrictionCurve.extremumValue = Mathf.Clamp
(forwardFrictionCurve_Org.extremumValue - sqrVel,
minForwardStiffness / 1f, maxForwardStiffness);
655 forwardFrictionCurve.asymptoteValue = Mathf.Clamp
(forwardFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minForwardStiffness / 1f,
maxForwardStiffness); ;
656
657 } else {
658
659 forwardFrictionCurve.extremumValue = Mathf.Clamp
(forwardFrictionCurve_Org.extremumValue - sqrVel,
minForwardStiffness, maxForwardStiffness);
660 forwardFrictionCurve.asymptoteValue = Mathf.Clamp
(forwardFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minForwardStiffness, maxForwardStiffness);
661
662 }
663
664 // Sideways
665 if (WheelCollider ==
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 16
CarController.FrontLeftWheelCollider.WheelCollider ||
WheelCollider ==
CarController.FrontRightWheelCollider.WheelCollider) {
666
667 sidewaysFrictionCurve.extremumValue = Mathf.Clamp
(sidewaysFrictionCurve_Org.extremumValue - sqrVel,
minSidewaysStiffness, maxSidewaysStiffness);
668 sidewaysFrictionCurve.asymptoteValue = Mathf.Clamp
(sidewaysFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minSidewaysStiffness, maxSidewaysStiffness);
669
670 } else {
671
672 sidewaysFrictionCurve.extremumValue = Mathf.Clamp
(sidewaysFrictionCurve_Org.extremumValue - sqrVel,
minSidewaysStiffness, maxSidewaysStiffness);
673 sidewaysFrictionCurve.asymptoteValue = Mathf.Clamp
(sidewaysFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minSidewaysStiffness, maxSidewaysStiffness);
674
675 }
676
677 } else {
678
679 if (WheelCollider ==
CarController.FrontLeftWheelCollider.WheelCollider ||
WheelCollider ==
CarController.FrontRightWheelCollider.WheelCollider) {
680
681 // Forward
682 forwardFrictionCurve.extremumValue = Mathf.Clamp
(forwardFrictionCurve_Org.extremumValue - sqrVel,
minForwardStiffness / 1f, maxForwardStiffness);
683 forwardFrictionCurve.asymptoteValue = Mathf.Clamp
(forwardFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minForwardStiffness / 1f, maxForwardStiffness);
684
685 } else {
686
687 forwardFrictionCurve.extremumValue = Mathf.Clamp
(forwardFrictionCurve_Org.extremumValue - sqrVel,
minForwardStiffness, maxForwardStiffness);
688 forwardFrictionCurve.asymptoteValue = Mathf.Clamp
(forwardFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minForwardStiffness, maxForwardStiffness);
689
690 }
691
692 // Sideways
693 sidewaysFrictionCurve.extremumValue = Mathf.Clamp
(sidewaysFrictionCurve_Org.extremumValue - sqrVel,
minSidewaysStiffness, maxSidewaysStiffness);
694 sidewaysFrictionCurve.asymptoteValue = Mathf.Clamp
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 17
(sidewaysFrictionCurve_Org.asymptoteValue - (sqrVel /
1f), minSidewaysStiffness, maxSidewaysStiffness);
695
696 }
697
698 }
699
700 /// <summary>
701 /// Audio.
702 /// </summary>
703 private void Audio() {
704
705 // Set audioclip to ground physic material sound.
706 audioClip = RCC_GroundMaterials.Instance.frictions
[groundIndex].groundSound;
707 audioVolume = RCC_GroundMaterials.Instance.frictions
[groundIndex].volume;
708
709 // If total slip is high enough...
710 if (totalSlip > RCC_GroundMaterials.Instance.frictions
[groundIndex].slip) {
711
712 // Assigning corresponding audio clip.
713 if (audioSource.clip != audioClip)
714 audioSource.clip = audioClip;
715
716 // Playing it.
717 if (!audioSource.isPlaying)
718 audioSource.Play();
719
720 // If vehicle is moving, set volume and pitch. Otherwise
set them to 0.
721 if (Rigid.velocity.magnitude > 1f) {
722
723 audioSource.volume = Mathf.Lerp(0f, audioVolume,
totalSlip);
724 audioSource.pitch = Mathf.Lerp(1f, .8f,
audioSource.volume);
725
726 } else {
727
728 audioSource.volume = 0f;
729
730 }
731
732 } else {
733
734 audioSource.volume = 0f;
735
736 // If volume is minimal and audio is still playing, stop.
737 if (audioSource.volume <= .05f && audioSource.isPlaying)
738 audioSource.Stop();
739
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 18
740 }
741
742 // Calculating bump force.
743 bumpForce = wheelHit.force - oldForce;
744
745 // If bump force is high enough, play bump SFX.
746 if ((bumpForce) >= 5000f) {
747
748 // Creating and playing audiosource for bump SFX.
749 AudioSource bumpSound = NewAudioSource
(RCC_Settings.Instance.audioMixer,
CarController.gameObject, "Bump Sound AudioSource", 5f,
50f, (bumpForce - 5000f) / 3000f,
RCC_Settings.Instance.bumpClip, false, true, true);
750 bumpSound.pitch = Random.Range(.9f, 1.1f);
751
752 }
753
754 oldForce = wheelHit.force;
755
756 }
757
758 /// <summary>
759 /// Returns true if one of the wheel is slipping.
760 /// </summary>
761 /// <returns><c>true</c>, if skidding was ised, <c>false</c>
otherwise.</returns>
762 public bool IsSkidding() {
763
764 for (int i = 0; i < CarController.AllWheelColliders.Length; i+
+) {
765
766 if (CarController.AllWheelColliders[i].totalSlip >
RCC_GroundMaterials.Instance.frictions[groundIndex].slip)
767 return true;
768
769 }
770
771 return false;
772
773 }
774
775 /// <summary>
776 /// Applies the motor torque.
777 /// </summary>
778 /// <param name="torque">Torque.</param>
779 public void ApplyMotorTorque(float torque) {
780
781 // If TCS is enabled, checks forward slip. If wheel is losing
traction, don't apply torque.
782 if (CarController.TCS) {
783
784 if (Mathf.Abs(WheelCollider.rpm) >= 1) {
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 19
785
786 if (Mathf.Abs(wheelSlipAmountForward) >
RCC_GroundMaterials.Instance.frictions
[groundIndex].slip) {
787
788 CarController.TCSAct = true;
789
790 torque -= Mathf.Clamp(torque * (Mathf.Abs
(wheelSlipAmountForward)) *
CarController.TCSStrength, -Mathf.Infinity,
Mathf.Infinity);
791
792 if (WheelCollider.rpm > 1) {
793
794 torque -= Mathf.Clamp(torque * (Mathf.Abs
(wheelSlipAmountForward)) *
CarController.TCSStrength, 0f, Mathf.Infinity);
795 torque = Mathf.Clamp(torque, 0f,
Mathf.Infinity);
796
797 } else {
798
799 torque += Mathf.Clamp(-torque * (Mathf.Abs
(wheelSlipAmountForward)) *
CarController.TCSStrength, 0f, Mathf.Infinity);
800 torque = Mathf.Clamp(torque, -Mathf.Infinity,
0f);
801
802 }
803
804 } else {
805
806 CarController.TCSAct = false;
807
808 }
809
810 } else {
811
812 CarController.TCSAct = false;
813
814 }
815
816 }
817
818 if (CheckOvertorque())
819 torque = 0;
820
821 if (Mathf.Abs(torque) > 1f)
822 WheelCollider.motorTorque = torque;
823 else
824 WheelCollider.motorTorque = 0f;
825
826 }
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 20
827
828 /// <summary>
829 /// Applies the steering.
830 /// </summary>
831 /// <param name="steerInput">Steer input.</param>
832 /// <param name="angle">Angle.</param>
833 public void ApplySteering(float steerInput, float angle) {
834
835 // Ackerman steering formula.
836 if (steerInput > 0f) {
837
838 if (transform.localPosition.x < 0)
839 WheelCollider.steerAngle = (Mathf.Deg2Rad * angle *
2.55f) * (Mathf.Rad2Deg * Mathf.Atan(2.55f / (6 +
(1.5f / 2))) * steerInput);
840 else
841 WheelCollider.steerAngle = (Mathf.Deg2Rad * angle *
2.55f) * (Mathf.Rad2Deg * Mathf.Atan(2.55f / (6 -
(1.5f / 2))) * steerInput);
842
843 } else if (steerInput < 0f) {
844
845 if (transform.localPosition.x < 0)
846 WheelCollider.steerAngle = (Mathf.Deg2Rad * angle *
2.55f) * (Mathf.Rad2Deg * Mathf.Atan(2.55f / (6 -
(1.5f / 2))) * steerInput);
847 else
848 WheelCollider.steerAngle = (Mathf.Deg2Rad * angle *
2.55f) * (Mathf.Rad2Deg * Mathf.Atan(2.55f / (6 +
(1.5f / 2))) * steerInput);
849
850 } else {
851
852 WheelCollider.steerAngle = 0f;
853
854 }
855
856 if (transform.localPosition.x < 0)
857 WheelCollider.steerAngle += toe;
858 else
859 WheelCollider.steerAngle -= toe;
860
861 }
862
863 /// <summary>
864 /// Applies the brake torque.
865 /// </summary>
866 /// <param name="torque">Torque.</param>
867 public void ApplyBrakeTorque(float torque) {
868
869 // If ABS is enabled, checks forward slip. If wheel is losing
traction, don't apply torque.
870 if (CarController.ABS && CarController.handbrakeInput <= .1f)
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 21
{
871
872 if ((Mathf.Abs(wheelHit.forwardSlip) * Mathf.Clamp01
(torque)) >= CarController.ABSThreshold) {
873
874 CarController.ABSAct = true;
875 torque = 0;
876
877 } else {
878
879 CarController.ABSAct = false;
880
881 }
882
883 }
884
885 if (Mathf.Abs(torque) > 1f)
886 WheelCollider.brakeTorque = torque;
887 else
888 WheelCollider.brakeTorque = 0f;
889
890 }
891
892 /// <summary>
893 /// Converts to splat map coordinate.
894 /// </summary>
895 /// <returns>The to splat map coordinate.</returns>
896 /// <param name="playerPos">Player position.</param>
897 private Vector3 ConvertToSplatMapCoordinate(Terrain terrain,
Vector3 playerPos) {
898
899 Vector3 vecRet = new Vector3();
900 Vector3 terPosition = terrain.transform.position;
901 vecRet.x = ((playerPos.x - terPosition.x) /
terrain.terrainData.size.x) *
terrain.terrainData.alphamapWidth;
902 vecRet.z = ((playerPos.z - terPosition.z) /
terrain.terrainData.size.z) *
terrain.terrainData.alphamapHeight;
903 return vecRet;
904
905 }
906
907 /// <summary>
908 /// Gets the index of the ground material.
909 /// </summary>
910 /// <returns>The ground material index.</returns>
911 private void GroundMaterial() {
912
913 isGrounded = WheelCollider.GetGroundHit(out wheelHit);
914
915 if (!isGrounded || wheelHit.point == Vector3.zero ||
wheelHit.collider == null) {
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 22
916
917 groundIndex = 0;
918 return;
919
920 }
921
922 for (int i = 0; i <
RCC_GroundMaterials.Instance.frictions.Length; i++) {
923
924 if (wheelHit.collider.sharedMaterial ==
RCC_GroundMaterials.Instance.frictions[i].groundMaterial)
{
925
926 groundIndex = i;
927 return;
928
929 }
930
931 }
932
933 // If ground pyhsic material is not one of the ground material
in Configurable Ground Materials, check if we are on
terrain collider...
934 if (!RCC_SceneManager.Instance.terrainsInitialized) {
935
936 groundIndex = 0;
937 return;
938
939 }
940
941 for (int i = 0; i <
RCC_GroundMaterials.Instance.terrainFrictions.Length; i++) {
942
943 if (wheelHit.collider.sharedMaterial ==
RCC_GroundMaterials.Instance.terrainFrictions
[i].groundMaterial) {
944
945 RCC_SceneManager.Terrains currentTerrain = null;
946
947 for (int l = 0; l <
RCC_SceneManager.Instance.terrains.Length; l++) {
948
949 if (RCC_SceneManager.Instance.terrains
[l].terrainCollider ==
RCC_GroundMaterials.Instance.terrainFrictions
[i].groundMaterial) {
950
951 currentTerrain =
RCC_SceneManager.Instance.terrains[l];
952 break;
953
954 }
955
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 23
956 }
957
958 if (currentTerrain != null) {
959
960 Vector3 playerPos = transform.position;
961 Vector3 TerrainCord = ConvertToSplatMapCoordinate
(currentTerrain.terrain, playerPos);
962 float comp = 0f;
963
964 for (int k = 0; k < currentTerrain.mNumTextures; k
++) {
965
966 if (comp < currentTerrain.mSplatmapData[(int)
TerrainCord.z, (int)TerrainCord.x, k])
967 groundIndex = k;
968
969 }
970
971 groundIndex =
RCC_GroundMaterials.Instance.terrainFrictions
[i].splatmapIndexes[groundIndex].index;
972 return;
973
974 }
975
976 }
977
978 }
979
980 groundIndex = 0;
981
982 }
983
984 /// <summary>
985 /// Checking deflated wheel.
986 /// </summary>
987 private void CheckDeflate() {
988
989 if (deflated) {
990
991 if (!flatSource)
992 flatSource = NewAudioSource(gameObject,
FlatAudio.name, 1f, 15f, .5f, FlatAudio, true, false,
false);
993
994 flatSource.volume = Mathf.Clamp01(Mathf.Abs
(WheelCollider.rpm * .001f));
995 flatSource.volume *= isGrounded ? 1f : 0f;
996
997 if (!flatSource.isPlaying)
998 flatSource.Play();
999
1000 } else {
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 24
1001
1002 if (flatSource && flatSource.isPlaying)
1003 flatSource.Stop();
1004
1005 }
1006
1007 if (_wheelDeflateParticles != null) {
1008
1009 ParticleSystem.EmissionModule em =
_wheelDeflateParticles.emission;
1010
1011 if (deflated) {
1012
1013 if (WheelCollider.rpm > 100f && isGrounded)
1014 em.enabled = true;
1015 else
1016 em.enabled = false;
1017
1018 } else {
1019
1020 em.enabled = false;
1021
1022 }
1023
1024 }
1025
1026 if (!isGrounded || wheelHit.point == Vector3.zero ||
wheelHit.collider == null)
1027 return;
1028
1029 for (int i = 0; i <
RCC_GroundMaterials.Instance.frictions.Length; i++) {
1030
1031 if (wheelHit.collider.sharedMaterial ==
RCC_GroundMaterials.Instance.frictions[i].groundMaterial)
{
1032
1033 if (RCC_GroundMaterials.Instance.frictions[i].deflate)
1034 Deflate();
1035
1036 }
1037
1038 }
1039
1040 }
1041
1042 /// <summary>
1043 /// Checks if overtorque applying.
1044 /// </summary>
1045 /// <returns><c>true</c>, if torque was overed, <c>false</c>
otherwise.</returns>
1046 private bool CheckOvertorque() {
1047
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 25
1048 if (CarController.speed > CarController.maxspeed || !
CarController.engineRunning)
1049 return true;
1050
1051 if (CarController.speed > CarController.gears
[CarController.currentGear].maxSpeed &&
CarController.engineRPM >= (CarController.maxEngineRPM
* .985f))
1052 return true;
1053
1054 return false;
1055
1056 }
1057
1058 /// <summary>
1059 /// Sets a new friction to WheelCollider.
1060 /// </summary>
1061 /// <returns>The friction curves.</returns>
1062 /// <param name="curve">Curve.</param>
1063 /// <param name="extremumSlip">Extremum slip.</param>
1064 /// <param name="extremumValue">Extremum value.</param>
1065 /// <param name="asymptoteSlip">Asymptote slip.</param>
1066 /// <param name="asymptoteValue">Asymptote value.</param>
1067 public WheelFrictionCurve SetFrictionCurves(WheelFrictionCurve
curve, float extremumSlip, float extremumValue, float
asymptoteSlip, float asymptoteValue) {
1068
1069 WheelFrictionCurve newCurve = curve;
1070
1071 newCurve.extremumSlip = extremumSlip;
1072 newCurve.extremumValue = extremumValue;
1073 newCurve.asymptoteSlip = asymptoteSlip;
1074 newCurve.asymptoteValue = asymptoteValue;
1075
1076 return newCurve;
1077
1078 }
1079
1080 /// <summary>
1081 /// Deflates the wheel.
1082 /// </summary>
1083 public void Deflate() {
1084
1085 if (deflated)
1086 return;
1087
1088 deflated = true;
1089
1090 if (defRadius == -1)
1091 defRadius = WheelCollider.radius;
1092
1093 WheelCollider.radius = defRadius * deflateRadiusMultiplier;
1094
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 26
1095 if (DeflateAudio)
1096 NewAudioSource(gameObject, DeflateAudio.name, 5f, 50f, 1f,
DeflateAudio, false, true, true);
1097
1098 if (_wheelDeflateParticles == null && WheelDeflateParticles) {
1099
1100 GameObject ps = Instantiate
(WheelDeflateParticles.gameObject, transform.position,
transform.rotation);
1101 _wheelDeflateParticles = ps.GetComponent<ParticleSystem>
();
1102 _wheelDeflateParticles.transform.SetParent(transform,
false);
1103 _wheelDeflateParticles.transform.localPosition = new
Vector3(0f, -.2f, 0f);
1104 _wheelDeflateParticles.transform.localRotation =
Quaternion.identity;
1105
1106 }
1107
1108 CarController.Rigid.AddForceAtPosition(transform.right *
Random.Range(-1f, 1f) * 30f, transform.position,
ForceMode.Acceleration);
1109
1110 }
1111
1112 /// <summary>
1113 /// Inflates the wheel.
1114 /// </summary>
1115 public void Inflate() {
1116
1117 if (!deflated)
1118 return;
1119
1120 deflated = false;
1121
1122 if (defRadius != -1)
1123 WheelCollider.radius = defRadius;
1124
1125 if (InflateAudio)
1126 NewAudioSource(gameObject, InflateAudio.name, 5f, 50f, 1f,
InflateAudio, false, true, true);
1127
1128 }
1129
1130 private void OnDisable() {
1131
1132 RCC_SceneManager.OnBehaviorChanged -= UpdateWheelFrictions;
1133
1134 if (wheelModel)
1135 wheelModel.gameObject.SetActive(false);
1136
1137 // Resetting values on disable.
...alisticCarControllerV3\Scripts\RCC_WheelCollider.cs 27
1138 wheelSlipAmountForward = 0f;
1139 wheelSlipAmountSideways = 0f;
1140 totalSlip = 0f;
1141 bumpForce = 0f;
1142 oldForce = 0f;
1143
1144 if (audioSource) {
1145
1146 audioSource.volume = 0f;
1147 audioSource.Stop();
1148
1149 }
1150
1151 WheelCollider.motorTorque = 0f;
1152 WheelCollider.brakeTorque = 0f;
1153 WheelCollider.steerAngle = 0f;
1154
1155 }
1156
1157 /// <summary>
1158 /// Raises the draw gizmos event.
1159 /// </summary>
1160 private void OnDrawGizmos() {
1161
1162 #if UNITY_EDITOR
1163 if (Application.isPlaying) {
1164
1165 WheelCollider.GetGroundHit(out WheelHit hit);
1166
1167 // Drawing gizmos for wheel forces and slips.
1168 float extension = (-
WheelCollider.transform.InverseTransformPoint
(hit.point).y - (WheelCollider.radius *
transform.lossyScale.y)) /
WheelCollider.suspensionDistance;
1169 Debug.DrawLine(hit.point, hit.point + transform.up *
(hit.force / Rigid.mass), extension <= 0.0 ?
Color.magenta : Color.white);
1170 Debug.DrawLine(hit.point, hit.point - transform.forward *
hit.forwardSlip * 2f, Color.green);
1171 Debug.DrawLine(hit.point, hit.point - transform.right *
hit.sidewaysSlip * 2f, Color.red);
1172
1173 }
1174 #endif
1175
1176 }
1177
1178 }

You might also like