ColliderAddSlopeAdjustment.cs 2.8 KB

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