Stabilizer.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. [RequireComponent(typeof(WheelCollider))]
  5. public class Stabilizer : MonoBehaviour { //by Marcos Schultz - www.schultzgames.com
  6. [Range(3,50)]
  7. public int raysNumber = 36;
  8. [Range(45,180)]
  9. public float raysMaxAngle = 135;
  10. public float rayWidth = 0.15f;
  11. WheelCollider _wheelCollider;
  12. float orgRadius;
  13. void Start () {
  14. _wheelCollider = GetComponent<WheelCollider> ();
  15. orgRadius = _wheelCollider.radius;
  16. }
  17. void FixedUpdate () {
  18. float radiusOffset = 0.0f;
  19. for (int x = 0; x <= raysNumber; x++) {
  20. Quaternion wheelAngle = Quaternion.AngleAxis (_wheelCollider.steerAngle, transform.up);
  21. float angleToRay = x * (raysMaxAngle / raysNumber) + ((180 - raysMaxAngle) / 2);
  22. Vector3 rayDirection = wheelAngle * Quaternion.AngleAxis (angleToRay, transform.right) * transform.forward;
  23. //
  24. //get wheel position and rotation
  25. Vector3 worldPos;
  26. Quaternion worldRot;
  27. _wheelCollider.GetWorldPose (out worldPos, out worldRot);
  28. //raycast center
  29. RaycastHit hitCenter;
  30. if(Physics.Raycast(worldPos, rayDirection, out hitCenter, _wheelCollider.radius)){
  31. if (!hitCenter.transform.IsChildOf (transform.root) && !hitCenter.collider.isTrigger) {
  32. Debug.DrawLine (worldPos, hitCenter.point, Color.red);
  33. radiusOffset = Mathf.Max (radiusOffset, _wheelCollider.radius - hitCenter.distance);
  34. }
  35. }
  36. Debug.DrawRay(worldPos, rayDirection*orgRadius, Color.green);
  37. //raycast Right
  38. RaycastHit hitRight;
  39. if(Physics.Raycast(worldPos + (worldRot * Vector3.right) * rayWidth, rayDirection, out hitRight, _wheelCollider.radius)){
  40. if (!hitRight.transform.IsChildOf (transform.root) && !hitRight.collider.isTrigger) {
  41. Debug.DrawLine (worldPos + (worldRot * Vector3.right) * rayWidth, hitRight.point, Color.red);
  42. radiusOffset = Mathf.Max (radiusOffset, _wheelCollider.radius - hitRight.distance);
  43. }
  44. }
  45. Debug.DrawRay(worldPos + (worldRot * Vector3.right) * rayWidth, rayDirection*orgRadius, Color.green);
  46. //raycast Left
  47. RaycastHit hitLeft;
  48. if(Physics.Raycast(worldPos - (worldRot * Vector3.right) * rayWidth, rayDirection, out hitLeft, _wheelCollider.radius)){
  49. if (!hitLeft.transform.IsChildOf (transform.root) && !hitLeft.collider.isTrigger) {
  50. Debug.DrawLine (worldPos - (worldRot * Vector3.right) * rayWidth, hitLeft.point, Color.red);
  51. radiusOffset = Mathf.Max (radiusOffset, _wheelCollider.radius - hitLeft.distance);
  52. }
  53. }
  54. Debug.DrawRay(worldPos - (worldRot * Vector3.right) * rayWidth, rayDirection*orgRadius, Color.green);
  55. //set correct radius
  56. float newRadius = Mathf.Clamp (orgRadius + radiusOffset, orgRadius, orgRadius * 2.0f);
  57. if (Mathf.Abs (_wheelCollider.radius - newRadius) > 0.01f) {
  58. _wheelCollider.radius = Mathf.LerpUnclamped (_wheelCollider.radius, newRadius, 0.02f);
  59. }
  60. }
  61. }
  62. }