Advertisement
Purianite

Clarity - Controller 2D

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