Search Unity

Collision in 2.5d scroller game

Discussion in 'Scripting' started by kaimelis, Oct 10, 2016.

  1. kaimelis

    kaimelis

    Joined:
    Apr 28, 2016
    Posts:
    18
    Hi there. My collision is not working with 3d objects. maybe you can help me.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent (typeof (BoxCollider))]
    5. public class ControllerSQ : MonoBehaviour {
    6.  
    7.     public LayerMask CollisionMask;
    8.  
    9.     const float SkinWidth = .015f;
    10.     public int HorizontalRayCount = 4;
    11.     public int VerticalRayCount = 4;
    12.  
    13.     private float _horizontalRaySpacing;
    14.     private float _verticalRaySpacing;
    15.  
    16.     private BoxCollider _collider;
    17.     private RaycastOrigins _raycastOrigins;
    18.  
    19.     void Start()
    20.     {
    21.         _collider = GetComponent<BoxCollider> ();
    22.         CalculateRaySpacing ();
    23.     }
    24.  
    25.     public void Move(Vector3 velocity)
    26.     {
    27.         UpdateRaycastOrigins ();
    28.  
    29.         if (velocity.x != 0) {
    30.             HorizontalCollisions (ref velocity);
    31.         }
    32.         if (velocity.y != 0) {
    33.             VerticalCollisions (ref velocity);
    34.         }
    35.  
    36.         transform.Translate (velocity);
    37.     }
    38.  
    39.     void HorizontalCollisions(ref Vector3 velocity)
    40.     {
    41.         float directionX = Mathf.Sign (velocity.x);
    42.         float rayLength = Mathf.Abs (velocity.x) + SkinWidth;
    43.      
    44.         for (int i = 0; i < HorizontalRayCount; i ++) {
    45.             Vector2 rayOrigin = (directionX == -1)?_raycastOrigins.bottomLeft:_raycastOrigins.bottomRight;
    46.             rayOrigin += Vector2.up * (_horizontalRaySpacing * i);
    47.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, CollisionMask);
    48.  
    49.             Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength,Color.red);
    50.  
    51.             if (hit) {
    52.                 velocity.x = (hit.distance - SkinWidth) * directionX;
    53.                 rayLength = hit.distance;
    54.             }
    55.         }
    56.     }
    57.  
    58.     void VerticalCollisions(ref Vector3 velocity)
    59.     {
    60.         float directionY = Mathf.Sign (velocity.y);
    61.         float rayLength = Mathf.Abs (velocity.y) + SkinWidth;
    62.  
    63.         for (int i = 0; i < VerticalRayCount; i ++) {
    64.             Vector2 rayOrigin = (directionY == -1)?_raycastOrigins.bottomLeft:_raycastOrigins.topLeft;
    65.             rayOrigin += Vector2.right * (_verticalRaySpacing * i + velocity.x);
    66.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, CollisionMask);
    67.  
    68.             Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength,Color.red);
    69.  
    70.             if (hit) {
    71.                 velocity.y = (hit.distance - SkinWidth) * directionY;
    72.                 rayLength = hit.distance;
    73.             }
    74.         }
    75.     }
    76.  
    77.     void UpdateRaycastOrigins()
    78.     {
    79.         Bounds bounds = _collider.bounds;
    80.         bounds.Expand (SkinWidth * -2);
    81.  
    82.         _raycastOrigins.bottomLeft = new Vector2 (bounds.min.x, bounds.min.y);
    83.         _raycastOrigins.bottomRight = new Vector2 (bounds.max.x, bounds.min.y);
    84.         _raycastOrigins.topLeft = new Vector2 (bounds.min.x, bounds.max.y);
    85.         _raycastOrigins.topRight = new Vector2 (bounds.max.x, bounds.max.y);
    86.     }
    87.  
    88.  
    89.     void CalculateRaySpacing()
    90.     {
    91.         Bounds bounds = _collider.bounds;
    92.         bounds.Expand (SkinWidth * -2);
    93.  
    94.         HorizontalRayCount = Mathf.Clamp (HorizontalRayCount, 2, int.MaxValue);
    95.         VerticalRayCount = Mathf.Clamp (VerticalRayCount, 2, int.MaxValue);
    96.  
    97.         _horizontalRaySpacing = bounds.size.y / (HorizontalRayCount - 1);
    98.         _verticalRaySpacing = bounds.size.x / (VerticalRayCount - 1);
    99.     }
    100.  
    101.     struct RaycastOrigins
    102.     {
    103.         public Vector2 topLeft, topRight;
    104.         public Vector2 bottomLeft, bottomRight;
    105.     }
    106.  
    107. }
    108.  
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent (typeof (ControllerSQ))]
    5. public class Player : MonoBehaviour {
    6.  
    7.     float moveSpeed = 6;
    8.     float gravity = -20;
    9.     Vector3 velocity;
    10.  
    11.     ControllerSQ controller;
    12.  
    13.     void Start() {
    14.         controller = GetComponent<ControllerSQ> ();
    15.     }
    16.  
    17.     void Update() {
    18.  
    19.         Vector2 input = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical"));
    20.  
    21.         velocity.x = input.x * moveSpeed;
    22.         velocity.y += gravity * Time.deltaTime;
    23.         controller.Move (velocity * Time.deltaTime);
    24.     }
    25. }
    26.  
     
    Last edited: Oct 10, 2016
  2. kaimelis

    kaimelis

    Joined:
    Apr 28, 2016
    Posts:
    18
    Done it. Easy solution just to check also z coordinates. I was too tired to think.
     
  3. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    Out of curiosity - is there a specific reason why you're reimplementing collision checks, gravity etc. with collider objects (or actually - at all)?

    In that scenario you might want to use a mesh, to save on all the Physics calls that Unity will do anyway when you create a collider.
     
  4. kaimelis

    kaimelis

    Joined:
    Apr 28, 2016
    Posts:
    18
    I am making squirrel movement. so i need it to move perpendicular to ground. So I thought that would be a good idea check collision allways. Because I need to check when im on the ground, which angle i am moving. But maybe I will try mesh also. Good idea. thanks