Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct here to familiarize yourself with the rules and how to post constructively.

  2. Unity 2022.1 is now available as the latest Tech release.
    Dismiss Notice
  3. Improve your project's performance with our new guide on profiling in Unity.
    Dismiss Notice

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
     
unityunity