Advertisement
Guest User

Untitled

a guest
Apr 21st, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.83 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class Controller2D : RaycastController {
  5.  
  6.     public float maxSlopeAngle = 80;
  7.  
  8.     public CollisionInfo collisions;
  9.     [HideInInspector]
  10.     public Vector2 playerInput;
  11.  
  12.     public override void Start() {
  13.         base.Start ();
  14.         collisions.faceDir = 1;
  15.  
  16.     }
  17.  
  18.     public void Move(Vector2 moveAmount, bool standingOnPlatform) {
  19.         Move (moveAmount, Vector2.zero, standingOnPlatform);
  20.     }
  21.  
  22.     public void Move(Vector2 moveAmount, Vector2 input, bool standingOnPlatform = false) {
  23.         UpdateRaycastOrigins ();
  24.  
  25.         collisions.Reset ();
  26.         collisions.moveAmountOld = moveAmount;
  27.         playerInput = input;
  28.  
  29.         if (moveAmount.y < 0) {
  30.             DescendSlope(ref moveAmount);
  31.         }
  32.  
  33.         if (moveAmount.x != 0) {
  34.             collisions.faceDir = (int)Mathf.Sign(moveAmount.x);
  35.         }
  36.  
  37.         HorizontalCollisions (ref moveAmount);
  38.         if (moveAmount.y != 0) {
  39.             VerticalCollisions (ref moveAmount);
  40.         }
  41.  
  42.         transform.Translate (moveAmount);
  43.  
  44.         if (standingOnPlatform) {
  45.             collisions.below = true;
  46.         }
  47.     }
  48.  
  49.     void HorizontalCollisions(ref Vector2 moveAmount) {
  50.         float directionX = collisions.faceDir;
  51.         float rayLength = Mathf.Abs (moveAmount.x) + skinWidth;
  52.  
  53.         if (Mathf.Abs(moveAmount.x) < skinWidth) {
  54.             rayLength = 2*skinWidth;
  55.         }
  56.  
  57.         for (int i = 0; i < horizontalRayCount; i ++) {
  58.             Vector2 rayOrigin = (directionX == -1)?raycastOrigins.bottomLeft:raycastOrigins.bottomRight;
  59.             rayOrigin += Vector2.up * (horizontalRaySpacing * i);
  60.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, collisionMask);
  61.  
  62.             Debug.DrawRay(rayOrigin, Vector2.right * directionX,Color.red);
  63.  
  64.             if (hit) {
  65.  
  66.                 if (hit.distance == 0) {
  67.                     continue;
  68.                 }
  69.  
  70.                 float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
  71.  
  72.                 if (i == 0 && slopeAngle <= maxSlopeAngle) {
  73.                     if (collisions.descendingSlope) {
  74.                         collisions.descendingSlope = false;
  75.                         moveAmount = collisions.moveAmountOld;
  76.                     }
  77.                     float distanceToSlopeStart = 0;
  78.                     if (slopeAngle != collisions.slopeAngleOld) {
  79.                         distanceToSlopeStart = hit.distance-skinWidth;
  80.                         moveAmount.x -= distanceToSlopeStart * directionX;
  81.                     }
  82.                     ClimbSlope(ref moveAmount, slopeAngle, hit.normal);
  83.                     moveAmount.x += distanceToSlopeStart * directionX;
  84.                 }
  85.  
  86.                 if (!collisions.climbingSlope || slopeAngle > maxSlopeAngle) {
  87.                     moveAmount.x = (hit.distance - skinWidth) * directionX;
  88.                     rayLength = hit.distance;
  89.  
  90.                     if (collisions.climbingSlope) {
  91.                         moveAmount.y = Mathf.Tan(collisions.slopeAngle * Mathf.Deg2Rad) * Mathf.Abs(moveAmount.x);
  92.                     }
  93.  
  94.                     collisions.left = directionX == -1;
  95.                     collisions.right = directionX == 1;
  96.                 }
  97.             }
  98.         }
  99.     }
  100.  
  101.     void VerticalCollisions(ref Vector2 moveAmount) {
  102.         float directionY = Mathf.Sign (moveAmount.y);
  103.         float rayLength = Mathf.Abs (moveAmount.y) + skinWidth;
  104.  
  105.         for (int i = 0; i < verticalRayCount; i ++) {
  106.  
  107.             Vector2 rayOrigin = (directionY == -1)?raycastOrigins.bottomLeft:raycastOrigins.topLeft;
  108.             rayOrigin += Vector2.right * (verticalRaySpacing * i + moveAmount.x);
  109.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
  110.  
  111.             Debug.DrawRay(rayOrigin, Vector2.up * directionY,Color.red);
  112.  
  113.             if (hit) {
  114.                 if (hit.collider.tag == "Through") {
  115.                     if (directionY == 1 || hit.distance == 0) {
  116.                         continue;
  117.                     }
  118.                     if (collisions.fallingThroughPlatform) {
  119.                         continue;
  120.                     }
  121.                     if (playerInput.y == -1) {
  122.                         collisions.fallingThroughPlatform = true;
  123.                         Invoke("ResetFallingThroughPlatform",.5f);
  124.                         continue;
  125.                     }
  126.                 }
  127.  
  128.                 moveAmount.y = (hit.distance - skinWidth) * directionY;
  129.                 rayLength = hit.distance;
  130.  
  131.                 if (collisions.climbingSlope) {
  132.                     moveAmount.x = moveAmount.y / Mathf.Tan(collisions.slopeAngle * Mathf.Deg2Rad) * Mathf.Sign(moveAmount.x);
  133.                 }
  134.  
  135.                 collisions.below = directionY == -1;
  136.                 collisions.above = directionY == 1;
  137.             }
  138.         }
  139.  
  140.         if (collisions.climbingSlope) {
  141.             float directionX = Mathf.Sign(moveAmount.x);
  142.             rayLength = Mathf.Abs(moveAmount.x) + skinWidth;
  143.             Vector2 rayOrigin = ((directionX == -1)?raycastOrigins.bottomLeft:raycastOrigins.bottomRight) + Vector2.up * moveAmount.y;
  144.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin,Vector2.right * directionX,rayLength,collisionMask);
  145.  
  146.             if (hit) {
  147.                 float slopeAngle = Vector2.Angle(hit.normal,Vector2.up);
  148.                 if (slopeAngle != collisions.slopeAngle) {
  149.                     moveAmount.x = (hit.distance - skinWidth) * directionX;
  150.                     collisions.slopeAngle = slopeAngle;
  151.                     collisions.slopeNormal = hit.normal;
  152.                 }
  153.             }
  154.         }
  155.     }
  156.  
  157.     void ClimbSlope(ref Vector2 moveAmount, float slopeAngle, Vector2 slopeNormal) {
  158.         float moveDistance = Mathf.Abs (moveAmount.x);
  159.         float climbmoveAmountY = Mathf.Sin (slopeAngle * Mathf.Deg2Rad) * moveDistance;
  160.  
  161.         if (moveAmount.y <= climbmoveAmountY) {
  162.             moveAmount.y = climbmoveAmountY;
  163.             moveAmount.x = Mathf.Cos (slopeAngle * Mathf.Deg2Rad) * moveDistance * Mathf.Sign (moveAmount.x);
  164.             collisions.below = true;
  165.             collisions.climbingSlope = true;
  166.             collisions.slopeAngle = slopeAngle;
  167.             collisions.slopeNormal = slopeNormal;
  168.         }
  169.     }
  170.  
  171.     void DescendSlope(ref Vector2 moveAmount) {
  172.  
  173.         RaycastHit2D maxSlopeHitLeft = Physics2D.Raycast (raycastOrigins.bottomLeft, Vector2.down, Mathf.Abs (moveAmount.y) + skinWidth, collisionMask);
  174.         RaycastHit2D maxSlopeHitRight = Physics2D.Raycast (raycastOrigins.bottomRight, Vector2.down, Mathf.Abs (moveAmount.y) + skinWidth, collisionMask);
  175.         if (maxSlopeHitLeft ^ maxSlopeHitRight) {
  176.             SlideDownMaxSlope (maxSlopeHitLeft, ref moveAmount);
  177.             SlideDownMaxSlope (maxSlopeHitRight, ref moveAmount);
  178.         }
  179.  
  180.         if (!collisions.slidingDownMaxSlope) {
  181.             float directionX = Mathf.Sign (moveAmount.x);
  182.             Vector2 rayOrigin = (directionX == -1) ? raycastOrigins.bottomRight : raycastOrigins.bottomLeft;
  183.             RaycastHit2D hit = Physics2D.Raycast (rayOrigin, -Vector2.up, Mathf.Infinity, collisionMask);
  184.  
  185.             if (hit) {
  186.                 float slopeAngle = Vector2.Angle (hit.normal, Vector2.up);
  187.                 if (slopeAngle != 0 && slopeAngle <= maxSlopeAngle) {
  188.                     if (Mathf.Sign (hit.normal.x) == directionX) {
  189.                         if (hit.distance - skinWidth <= Mathf.Tan (slopeAngle * Mathf.Deg2Rad) * Mathf.Abs (moveAmount.x)) {
  190.                             float moveDistance = Mathf.Abs (moveAmount.x);
  191.                             float descendmoveAmountY = Mathf.Sin (slopeAngle * Mathf.Deg2Rad) * moveDistance;
  192.                             moveAmount.x = Mathf.Cos (slopeAngle * Mathf.Deg2Rad) * moveDistance * Mathf.Sign (moveAmount.x);
  193.                             moveAmount.y -= descendmoveAmountY;
  194.  
  195.                             collisions.slopeAngle = slopeAngle;
  196.                             collisions.descendingSlope = true;
  197.                             collisions.below = true;
  198.                             collisions.slopeNormal = hit.normal;
  199.                         }
  200.                     }
  201.                 }
  202.             }
  203.         }
  204.     }
  205.  
  206.     void SlideDownMaxSlope(RaycastHit2D hit, ref Vector2 moveAmount) {
  207.  
  208.         if (hit) {
  209.             float slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
  210.             if (slopeAngle > maxSlopeAngle) {
  211.                 moveAmount.x = Mathf.Sign(hit.normal.x) * (Mathf.Abs (moveAmount.y) - hit.distance) / Mathf.Tan (slopeAngle * Mathf.Deg2Rad);
  212.  
  213.                 collisions.slopeAngle = slopeAngle;
  214.                 collisions.slidingDownMaxSlope = true;
  215.                 collisions.slopeNormal = hit.normal;
  216.             }
  217.         }
  218.  
  219.     }
  220.  
  221.     void ResetFallingThroughPlatform() {
  222.         collisions.fallingThroughPlatform = false;
  223.     }
  224.  
  225.     public struct CollisionInfo {
  226.         public bool above, below;
  227.         public bool left, right;
  228.  
  229.         public bool climbingSlope;
  230.         public bool descendingSlope;
  231.         public bool slidingDownMaxSlope;
  232.  
  233.         public float slopeAngle, slopeAngleOld;
  234.         public Vector2 slopeNormal;
  235.         public Vector2 moveAmountOld;
  236.         public int faceDir;
  237.         public bool fallingThroughPlatform;
  238.  
  239.         public void Reset() {
  240.             above = below = false;
  241.             left = right = false;
  242.             climbingSlope = false;
  243.             descendingSlope = false;
  244.             slidingDownMaxSlope = false;
  245.             slopeNormal = Vector2.zero;
  246.  
  247.             slopeAngleOld = slopeAngle;
  248.             slopeAngle = 0;
  249.         }
  250.     }
  251.  
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement