Advertisement
KodingKid

C# Unity3D Surface Contact (Object)

Apr 6th, 2021
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.24 KB | None | 0 0
  1. void Update () {
  2.     GetComponent<Renderer>().material.SetColor(
  3.             "_Color", OnGround ? Color.black : Color.white
  4.         );
  5.     }
  6. int stepsSinceLastGrounded;
  7. void UpdateState () {
  8.         stepsSinceLastGrounded += 1;
  9.         velocity = body.velocity;
  10.         if (OnGround) {
  11.             stepsSinceLastGrounded = 0;
  12.             jumpPhase = 0;
  13.             if (groundContactCount > 1) {
  14.                 contactNormal.Normalize();
  15.             }
  16.         }
  17.         else {
  18.             contactNormal = Vector3.up;
  19.         }
  20.     }
  21. bool SnapToGround () {
  22.         return false;
  23.     }
  24. void UpdateState () {
  25.         stepsSinceLastGrounded += 1;
  26.         velocity = body.velocity;
  27.         if (OnGround || SnapToGround()) {
  28.         }
  29.     }
  30.     bool SnapToGround () {
  31.         if (stepsSinceLastGrounded > 1) {
  32.             return false;
  33.         }
  34.         return false;
  35.     }
  36. if (stepsSinceLastGrounded > 1) {
  37.             return false;
  38.         }
  39.         if (!Physics.Raycast(body.position, Vector3.down)) {
  40.             return false;
  41.         }
  42.         return false;
  43.     if (!Physics.Raycast(body.position, Vector3.down, out RaycastHit hit)) {
  44.             return false;
  45.         }
  46. }
  47.         if (hit.normal.y < minGroundDotProduct) {
  48.             return false;
  49.         }
  50. if (hit.normal.y < minGroundDotProduct) {
  51.             return false;
  52.         }
  53.  
  54.         groundContactCount = 1;
  55.         contactNormal = hit.normal;
  56.         float speed = velocity.magnitude;
  57.         float dot = Vector3.Dot(velocity, hit.normal);
  58.         velocity = (velocity - hit.normal * dot).normalized * speed;
  59.         return true;
  60. if (dot > 0f) {
  61.             velocity = (velocity - hit.normal * dot).normalized * speed;
  62.         }
  63. [SerializeField, Range(1f, 1000f)]
  64.     float maxSnapSpeed = 1000f;
  65. bool SnapToGround () {
  66.         if (stepsSinceLastGrounded > 1) {
  67.             return false;
  68.         }
  69.         float speed = velocity.magnitude;
  70.         if (speed > maxSnapSpeed) {
  71.             return false;
  72.         }
  73.         if (!Physics.Raycast(body.position, Vector3.down, out RaycastHit hit)) {
  74.             return false;
  75.         }
  76.         if (hit.normal.y < minGroundDotProduct) {
  77.             return false;
  78.         }
  79.     groundContactCount = 1;
  80.         contactNormal = hit.normal;
  81.     float dot = Vector3.Dot(velocity, hit.normal);
  82.         if (dot > 0f) {
  83.             velocity = (velocity - hit.normal * dot).normalized * speed;
  84.         }
  85.         return true;
  86.     }
  87. [SerializeField, Min(0f)]
  88.     float probeDistance = 1f;
  89.         if (!Physics.Raycast(
  90.             body.position, Vector3.down, out RaycastHit hit,
  91.             probeDistance, probeMask
  92.         )) {
  93.             return false;
  94.         }
  95.         [SerializeField]
  96.     LayerMask probeMask = -1, stairsMask = -1;
  97. [SerializeField, Range(0, 90)]
  98.     float maxGroundAngle = 25f, maxStairsAngle = 50f;
  99. float minGroundDotProduct, minStairsDotProduct;
  100. void OnValidate () {
  101.         minGroundDotProduct = Mathf.Cos(maxGroundAngle * Mathf.Deg2Rad);
  102.         minStairsDotProduct = Mathf.Cos(maxStairsAngle * Mathf.Deg2Rad);
  103.     }
  104. float GetMinDot (int layer) {
  105.         return stairsMask != layer ?
  106.             minGroundDotProduct : minStairsDotProduct;
  107.     }
  108. return (stairsMask & (1 << layer)) == 0 ?
  109.     void EvaluateCollision (Collision collision) {
  110.         float minDot = GetMinDot(collision.gameObject.layer);
  111.         for (int i = 0; i < collision.contactCount; i++) {
  112.             Vector3 normal = collision.GetContact(i).normal;
  113.             if (normal.y >= minDot) {
  114.                 groundContactCount += 1;
  115.                 contactNormal += normal;
  116.             }
  117.         }
  118.     }
  119. if (hit.normal.y < GetMinDot(hit.collider.gameObject.layer)) {
  120.             return false;
  121.         }
  122. Vector3 contactNormal, steepNormal;
  123.     int groundContactCount, steepContactCount;
  124.     bool OnGround => groundContactCount > 0;
  125.     bool OnSteep => steepContactCount > 0;
  126.     void ClearState () {
  127.         groundContactCount = steepContactCount = 0;
  128.         contactNormal = steepNormal = Vector3.zero;
  129.     }
  130.     if (normal.y >= minDot) {
  131.                 groundContactCount += 1;
  132.                 contactNormal += normal;
  133.             }
  134.             else if (normal.y > -0.01f) {
  135.                 steepContactCount += 1;
  136.                 steepNormal += normal;
  137.             }
  138. bool CheckSteepContacts () {
  139.         if (steepContactCount > 1) {
  140.             steepNormal.Normalize();
  141.             if (steepNormal.y >= minGroundDotProduct) {
  142.                 groundContactCount = 1;
  143.                 contactNormal = steepNormal;
  144.                 return true;
  145.             }
  146.         }
  147.         return false;
  148.     }
  149. if (OnGround || SnapToGround() || CheckSteepContacts()) {
  150.             stepsSinceLastGrounded = 0;
  151.             jumpPhase = 0;
  152.             if (groundContactCount > 1) {
  153.                 contactNormal.Normalize();
  154.             }
  155.         }
  156. void Jump () {
  157.         Vector3 jumpDirection;
  158.     stepsSinceLastJump = 0;
  159.         jumpPhase += 1;
  160.         float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight);
  161.         float alignedSpeed = Vector3.Dot(velocity, jumpDirection);
  162.         if (alignedSpeed > 0f) {
  163.             jumpSpeed = Mathf.Max(jumpSpeed - alignedSpeed, 0f);
  164.         }
  165.         velocity += jumpDirection * jumpSpeed;
  166.         }
  167.     }
  168. Vector3 jumpDirection;
  169.         if (OnGround) {
  170.             jumpDirection = contactNormal;
  171.         }
  172.         else if (OnSteep) {
  173.             jumpDirection = steepNormal;
  174.         }
  175.         else if (jumpPhase < maxAirJumps) {
  176.             jumpDirection = contactNormal;
  177.         }
  178.         else {
  179.             return;
  180.         }
  181. stepsSinceLastGrounded = 0;
  182.             if (stepsSinceLastJump > 1) {
  183.                 jumpPhase = 0;
  184.             }
  185. else if (maxAirJumps > 0 && jumpPhase <= maxAirJumps) {
  186.             if (jumpPhase == 0) {
  187.                 jumpPhase = 1;
  188.             }
  189.             jumpDirection = contactNormal;
  190.         }
  191. else if (OnSteep) {
  192.             jumpDirection = steepNormal;
  193.             jumpPhase = 0;
  194.         }
  195. jumpDirection = (jumpDirection + Vector3.up).normalized;
  196.         float alignedSpeed = Vector3.Dot(velocity, jumpDirection);
  197. //This is a very old script I made a year ago in Unity3D and never used so apologies if it doesn't work, I just learnt it from an old YouTube tutorial so it may be broken! (same as: https://pastebin.com/80qY21pB)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement