ColliderAddSlopeAdjustment.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class ColliderAddSlopeAdjustment : MonoBehaviour
  5. {
  6. [Header("Steering Direction Config")]
  7. [Tooltip("A Transform that has an Axis that always shows into steering direction. It is assumed, that this transform is always on the floor!")]
  8. public Transform steerTransform;
  9. public Axis steerTransformForward = Axis.Z;
  10. public bool backwardIsForward = false;
  11. public int collisionLayer = 11;
  12. private const float RAYCAST_DIST = 0.2f;
  13. private float rayLength = 10f; //TODO: calculate -> front wheel
  14. // Start is called before the first frame update
  15. void Start()
  16. {
  17. }
  18. void FixedUpdate()
  19. {
  20. bool hit = AdjustSlope(); //Check above ground -> ascending
  21. if(!hit) AdjustSlope(underground: true); //Check underground -> descending
  22. }
  23. private bool AdjustSlope(bool underground = false)
  24. {
  25. var hitDistLower = CastRay(underground: underground);
  26. var hitDistUpper = CastRay(dist: RAYCAST_DIST, underground:underground);
  27. if (hitDistLower != null && hitDistUpper != null)
  28. {
  29. var slope = CalculateHitSlope(hitDistLower.Value, hitDistUpper.Value);
  30. //Debug.Log($"Hit - Slope = {(underground ? -slope : slope )}");
  31. return true;
  32. }
  33. return false;
  34. }
  35. //TODO: does only work for going up! We also need rays underground
  36. private float CalculateHitSlope(float hitDistLower, float hitDistUpper)
  37. {
  38. return Mathf.Atan(RAYCAST_DIST / Mathf.Abs(hitDistUpper - hitDistLower)) * Mathf.Rad2Deg;
  39. }
  40. private float? CastRay(float dist = 0f, bool underground = false)
  41. {
  42. var layerMask = 1 << collisionLayer;
  43. RaycastHit hit;
  44. var forward = CalculateForward();
  45. var position = steerTransform.position + Vector3.up * (dist - (underground ? 1 : 0)); // TODO: probably needs to be transformed to local axes
  46. // Does the ray intersect any objects excluding the player layer
  47. if (Physics.Raycast(position,forward , out hit, rayLength, layerMask))
  48. {
  49. Debug.DrawRay(position, forward * hit.distance, Color.yellow);
  50. if (hit.collider.isTrigger)
  51. {
  52. return null;
  53. }
  54. return hit.distance;
  55. //Debug.Log("Did Hit: ");
  56. }
  57. else
  58. {
  59. Debug.DrawRay(position, forward * rayLength, Color.white);
  60. //Debug.Log("Did not Hit");
  61. }
  62. return null;
  63. }
  64. private Vector3 CalculateForward()
  65. {
  66. Vector3 forward;
  67. switch (steerTransformForward)
  68. {
  69. case Axis.X:
  70. forward = steerTransform.right;
  71. break;
  72. case Axis.Y:
  73. forward = steerTransform.up;
  74. break;
  75. default:
  76. forward = steerTransform.forward;
  77. break;
  78. }
  79. return backwardIsForward ? -forward : forward;
  80. }
  81. }