Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Mesh collider isn't working

Discussion in 'Scripting' started by mate_veres, Mar 4, 2020.

  1. mate_veres

    mate_veres

    Joined:
    Oct 19, 2019
    Posts:
    72
    Good Evening!

    I stumbled upon a problem when I was experimenting with mesh colliders.

    I am currently making a 2D game where I generate the ground by making a mesh of predefined points with the help of a triangulation method. I attached a mesh collider to it and I set the MeshCollider.sharedMesh in the start method after the triangulation process ended. But my player with raycasting ground detection falls through it.
    I continued experimenting and I found out that my player falls through everything with mesh collider.

    Here is my collision detection script of the player:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(BoxCollider2D))]
    5. public class Controller2D : MonoBehaviour
    6. {
    7.    
    8.     public LayerMask collisionMask;
    9.  
    10.     const float skinWidth = .015f;
    11.     public int horizontalRayCount = 4;
    12.     public int verticalRayCount = 4;
    13.  
    14.     float horizontalRaySpacing;
    15.     float verticalRaySpacing;
    16.  
    17.     BoxCollider2D collider;
    18.     RaycastOrigins raycastOrigins;
    19.     public CollisionInfo collisions;
    20.  
    21.     void Start()
    22.     {
    23.         collider = GetComponent<BoxCollider2D>();
    24.         CalculateRaySpacing();
    25.     }
    26.  
    27.    
    28.     public void Move(Vector3 velocity)
    29.     {
    30.         UpdateRaycastOrigins();
    31.         collisions.Reset();
    32.  
    33.         if (velocity.x != 0)
    34.         {
    35.             HorizontalCollisions(ref velocity);
    36.         }
    37.         if (velocity.y != 0)
    38.         {
    39.             VerticalCollisions(ref velocity);
    40.         }
    41.  
    42.         transform.Translate(velocity);
    43.     }
    44.  
    45.     void HorizontalCollisions(ref Vector3 velocity)
    46.     {
    47.         float directionX = Mathf.Sign(velocity.x);
    48.         float rayLength = Mathf.Abs(velocity.x) + skinWidth;
    49.  
    50.         for (int i = 0; i < horizontalRayCount; i++)
    51.         {
    52.             Vector2 rayOrigin = (directionX == -1) ? raycastOrigins.bottomLeft : raycastOrigins.bottomRight;
    53.             rayOrigin += Vector2.up * (horizontalRaySpacing * i);
    54.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, collisionMask);
    55.  
    56.             Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength, Color.red);
    57.  
    58.             if (hit)
    59.             {
    60.                 velocity.x = (hit.distance - skinWidth) * directionX;
    61.                 rayLength = hit.distance;
    62.  
    63.                 collisions.left = (directionX == -1);
    64.                 collisions.right = (directionX == 1);
    65.             }
    66.            
    67.         }
    68.     }
    69.  
    70.     void VerticalCollisions(ref Vector3 velocity)
    71.     {
    72.         float directionY = Mathf.Sign(velocity.y);
    73.         float rayLength = Mathf.Abs(velocity.y) + skinWidth;
    74.  
    75.         for (int i = 0; i < verticalRayCount; i++)
    76.         {
    77.             Vector2 rayOrigin = (directionY == -1) ? raycastOrigins.bottomLeft : raycastOrigins.topLeft;
    78.             rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);
    79.             RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
    80.  
    81.             Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength, Color.red);
    82.  
    83.             if (hit)
    84.             {
    85.                 velocity.y = (hit.distance - skinWidth) * directionY;
    86.                 rayLength = hit.distance;
    87.  
    88.                 collisions.above = (directionY == 1);
    89.                 collisions.below = (directionY == -1);
    90.             }
    91.         }
    92.     }
    93.  
    94.     void UpdateRaycastOrigins()
    95.     {
    96.         Bounds bounds = collider.bounds;
    97.         bounds.Expand(skinWidth * -2);
    98.  
    99.         raycastOrigins.bottomLeft = new Vector2(bounds.min.x, bounds.min.y);
    100.         raycastOrigins.bottomRight = new Vector2(bounds.max.x, bounds.min.y);
    101.         raycastOrigins.topLeft = new Vector2(bounds.min.x, bounds.max.y);
    102.         raycastOrigins.topRight = new Vector2(bounds.max.x, bounds.max.y);
    103.     }
    104.  
    105.     void CalculateRaySpacing()
    106.     {
    107.         Bounds bounds = collider.bounds;
    108.         bounds.Expand(skinWidth * -2);
    109.  
    110.         horizontalRayCount = Mathf.Clamp(horizontalRayCount, 2, int.MaxValue);
    111.         verticalRayCount = Mathf.Clamp(verticalRayCount, 2, int.MaxValue);
    112.  
    113.         horizontalRaySpacing = bounds.size.y / (horizontalRayCount - 1);
    114.         verticalRaySpacing = bounds.size.x / (verticalRayCount - 1);
    115.     }
    116.  
    117.     struct RaycastOrigins
    118.     {
    119.         public Vector2 topLeft, topRight;
    120.         public Vector2 bottomLeft, bottomRight;
    121.     }
    122.  
    123.     public struct CollisionInfo
    124.     {
    125.         public bool above, below;
    126.         public bool left, right;
    127.  
    128.         public void Reset()
    129.         {
    130.             above = below = false;
    131.             left = right = false;
    132.         }
    133.     }
    134. }
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    how do you set your LayerMask (i.e. collisionMask in your code)?
     
  3. mate_veres

    mate_veres

    Joined:
    Oct 19, 2019
    Posts:
    72
    Thank you for your answer.

    I set it in manually in the inspector, but I checked it twice and it's aligned with the mesh's object.
     
  4. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    what I meant is are you absolutely sure you're setting the appropriate value?
    I can't tell if you're experienced with bitmasks in general, but that's the most common source of this type of error.
     
  5. mate_veres

    mate_veres

    Joined:
    Oct 19, 2019
    Posts:
    72
    I did some testing and it seems like raycast just doesn't work with any mesh filter object in my project. Here is a video: https://easyupload.io/uhtacb

    As you can see the rays collide with every other object except the quad with mesh filter. Also, I haven't use layermask for this experiment.
     
  6. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,380
    In Unity, 2D and 3D physics are separate systems, so something like a mesh collider (which is 3D) is not going to work with Raycast2D. You either need to use the regular 3D Raycast or change your mesh collider to a polygon collider 2d instead.

    https://docs.unity3d.com/Manual/class-PolygonCollider2D.html

    2D physics objects and functions should all have the character "2D" in the name.
     
    hms0589 likes this.
  7. mate_veres

    mate_veres

    Joined:
    Oct 19, 2019
    Posts:
    72
    Thank you for your answer!

    I have solved the problem with polygon colliders.