Search Unity

Polygon collider 2D & 3D terrain

Discussion in 'Physics' started by Hindi, Feb 18, 2015.

  1. Hindi

    Hindi

    Joined:
    Apr 14, 2013
    Posts:
    59
    I'd like to use sprites with polygon collider and a 3D terrain object, which seems to not be possible.
    When I rotate my sprite so that it is parallel to the terrain, the polygon collider says :

    "The collider did not create any collision shapes as they all failed verification. This could be because they were deemed too small or the vertices were too close. Vertices can also besome close under certain rotations or very small scalling"

    After a 90° rotation over X axis, the sprite appears as a line to the collider, hence the warning (and no collision).

    The problem is, I can't turn the 3D terrain either... Is it impossible to have both of them working in the same plan ?
     
  2. justJack

    justJack

    Joined:
    Feb 5, 2015
    Posts:
    22
    2D and 3D will not physically interact - I mean they will not collide with each other.

    About the message,
    try adjusting your polygon collider manually. But like I said, it will not solve your problem (at least you will get rid of that message).
     
  3. Hindi

    Hindi

    Joined:
    Apr 14, 2013
    Posts:
    59
    I don't want them to collide, I'm using the sprites as a grid that only interracts with the mouse. Still, I need to have both of them in the same plan if I want that my 3D object use the terrain object and my mouse to interract with the sprites at the same time.

    When I try to adjust the collider, I can only put the nodes on a line.
     
  4. Hindi

    Hindi

    Joined:
    Apr 14, 2013
    Posts:
    59
    bump
     
  5. ataboo

    ataboo

    Joined:
    Oct 17, 2012
    Posts:
    3
    Old question but I thought I'd share my solution for anyone googling this.

    For my 2.5D project I wanted my 2D Collider/Sprite character to walk on Terrain. I ended up generating a 2D poly collider at run-time by sampling the terrain height-map at my z-plane.

    Code (CSharp):
    1.  
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent (typeof(PolygonCollider2D))]
    6. public class Terrain2DPoly : MonoBehaviour {
    7.     [SerializeField] private Terrain m_Terrain;
    8.     [SerializeField] private float zPlane = 0f;
    9.  
    10.     private PolygonCollider2D m_collider;
    11.  
    12.     void Start()
    13.     {
    14.         m_collider = GetComponent<PolygonCollider2D> ();
    15.         Vector3 terrainPos = m_Terrain.GetPosition ();
    16.  
    17.         transform.position = new Vector3(terrainPos.x, terrainPos.y, zPlane);
    18.            
    19.         m_collider.SetPath (0, IntersectPlane().ToArray());
    20.     }
    21.  
    22.     /// <summary>
    23.     /// Generates a list of Vector2s representing where the zPlane intersects the terrain.
    24.     /// </summary>
    25.     /// <returns>List of points</returns>
    26.     private List<Vector2> IntersectPlane()
    27.     {
    28.         Vector3 terrainPos = m_Terrain.GetPosition ();
    29.         TerrainData terrainData = m_Terrain.terrainData;
    30.         int pointCount = terrainData.heightmapResolution;
    31.         float pointStepSize = terrainData.size.x/pointCount;
    32.         List<Vector2> intersectPoints = new List<Vector2> (pointCount + 2);
    33.         float minY = 0f;
    34.  
    35.         for (int x = 0; x < pointCount; x++) {
    36.             float xPos = x * pointStepSize;
    37.             float y = m_Terrain.SampleHeight(new Vector3(xPos + terrainPos.x, 0, 0));
    38.             minY = Mathf.Min (minY, y);
    39.             intersectPoints.Add(new Vector2(xPos, y));
    40.         }
    41.  
    42.         minY -= 5f;
    43.  
    44.         // Add botton right and bottom left points to insure convex.
    45.         intersectPoints.Add (new Vector2 (pointCount * pointStepSize, minY));
    46.         intersectPoints.Add (new Vector2 (0, minY));
    47.  
    48.         return intersectPoints;
    49.     }
    50. }
    You can run this once and prefab the collider if you don't want it to generate it every time.

    I am no Unity guru so hopefully there are no terrible performance consequences or anything but it seems to work fine.
     
    jktaylo1 and xcmeathead like this.
  6. xcmeathead

    xcmeathead

    Joined:
    Jun 1, 2015
    Posts:
    28
    @ataboo you've just saved me a lot of time! Thanks so much for this brilliant script :D
     
  7. jktaylo1

    jktaylo1

    Joined:
    Apr 18, 2017
    Posts:
    2
    Thanks @ataboo! I was able to use an Object2Terrain script to get my environment mesh into a terrain object and use your code to get out a 2D Polygon Collider! For anyone else trying to use the script, please make sure your terrain is at the origin 0,0,0. I tried to modify the code to account for offset from world origin, but unfortunately am too new to unity to figure it out. I will probably come back to it because it would be nice to place my 2D characters at different places and orientations in the 3D world.
     
  8. Mantra-Games

    Mantra-Games

    Joined:
    Nov 27, 2012
    Posts:
    171

    Hey I need something exactly like this for my Pseudo 3D game using Corgi Engine which uses 2D colliders. I want to add 2D colliders to unity terrain and other 3D mesh so I don't have to manually create them.

    I tried adding this script to the unity terrain but I get the error:
    "The script 'PolygonCollider2D' does not contain a class derived from UnityEngine.MonoBehaviour"

    How is it supposed to be used?

    Thanks so much if you respond :)

    EDIT - Ok got this working but how would I move the collider on the Z? The player needs to be at 0 on the Z, I see that I can move the collider on the X and Y but not the Z :(
     
    Last edited: Jun 23, 2021
  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    I don't know the tool you're referring to but you seem to be under the misunderstanding that the 2D physics system is somehow a 3D physics system. The Transform Z has nothing whatsoever to do with 2D physics. It has XY position and Z rotation (3 degrees of freedom).
     
  10. Mantra-Games

    Mantra-Games

    Joined:
    Nov 27, 2012
    Posts:
    171
    Ok thanks ;)

    So I'm just looking for a way to move the 2D collider thats generated on the Z (red arrow) to -13.3 (blue arrow). In this screenshot it's generated right on the edge of the Z plane.

    EDIT - NM...I got this working by just specifying a -13 on the Z plane in this script and leaving the position of the terrain at 0. :)

    @ataboo Thanks SO MUCH for sharing this, it's saved me a lot of headache creating 2D colliders to match the terrain shape!
     

    Attached Files:

    Last edited: Jun 23, 2021
  11. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    The Gizmo draws it at whatever the Transform Z is just to match any other rendering on that GameObject. That's just a visual representation; the collider doesn't move in Z. I can see you "got it working" but apart from placing your Transform Z at the position you want I'm not sure I follow what the problem was. Either way, glad you got it working.