Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by DimonK95 · Mar 23, 2018 at 02:28 PM · 3dmesh colliderpolygon collider 2d

Generate 2D polygon collider from 3D mesh

My game use 2d physic, but 3D graphics. The unity editor automatically generates a collider polygon using the sprite of the desired shape. If for example on a sprite a circle is drawn on a transparent background, then the generated collider polygon will be round. When the 2D scene mode is fixed, if you click on the 3d mesh model - it is outlined in orange (as can be seen in the screenshot), I want to make the polygon a collider polygon of the same shape as if it was a sprite. Tell me, please, how can I do this except to manually sketch the collider polygon? I need to algorithm working on at least simple examples as in the screenshot alt text

снимок-экрана-2018-03-23-в-181557.png (119.4 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
5

Answer by alpineboarder · Mar 12, 2019 at 12:33 AM

I was looking for this exact solution myself (All that dragging around polygon points was driving me insane).

Here's an editor script I wrote that will match any PolygonCollider2D to the MeshFilter on a GameObject.

Just plop it into an Editor folder, highlight the GameObject, and click Update Polygon Colliders up in the Tools menu, or Ctrl/Cmd+T

Seems to work well with ProBuilder and in Prefab Edit Mode. I'm sure this can be greatly improved upon, feel free!

GIANT credit goes to @Bunny83 for their EdgeHelper class! Wouldn't work nearly as well without it. :)

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEditor;
 using System;
 using UnityEditor.SceneManagement;
 using System.Linq;
 
 public static class SetPolygonCollider3D
 {
     [MenuItem("Tools/Update Polygon Colliders %t", false, -1)]
     static void UpdatePolygonColliders()
     {
         Transform transform = Selection.activeTransform;
         if(transform == null)
         {
             Debug.LogWarning("No valid GameObject selected!");
             return;
         }
 
         EditorSceneManager.MarkSceneDirty(transform.gameObject.scene);
 
         MeshFilter[] meshFilters = transform.GetComponentsInChildren<MeshFilter>();
         
         foreach(MeshFilter meshFilter in meshFilters)
         {
             if(meshFilter.GetComponent<PolygonCollider2D>() != null)
             {
                 UpdatePolygonCollider2D(meshFilter);
             }
         }
     }
 
     static void UpdatePolygonCollider2D(MeshFilter meshFilter)
     {
         if(meshFilter.sharedMesh == null)
         {
             Debug.LogWarning(meshFilter.gameObject.name + " has no Mesh set on its MeshFilter component!");
             return;
         }
 
         PolygonCollider2D polygonCollider2D = meshFilter.GetComponent<PolygonCollider2D>();
         polygonCollider2D.pathCount = 1;
 
         List<Vector3> vertices =  new List<Vector3>();
         meshFilter.sharedMesh.GetVertices(vertices);
 
         var boundaryPath = EdgeHelpers.GetEdges(meshFilter.sharedMesh.triangles).FindBoundary().SortEdges();
 
         Vector3[] yourVectors = new Vector3[boundaryPath.Count];
         for(int i = 0; i < boundaryPath.Count; i++)
         {
             yourVectors[i] = vertices[ boundaryPath[i].v1 ];
         }
         List<Vector2> newColliderVertices = new List<Vector2>();
 
         for(int i=0; i < yourVectors.Length; i++)
         {
             newColliderVertices.Add(new Vector2(yourVectors[i].x, yourVectors[i].y));
         }
 
         Vector2[] newPoints = newColliderVertices.Distinct().ToArray();
 
         EditorUtility.SetDirty(polygonCollider2D);
 
         polygonCollider2D.SetPath(0, newPoints);
         Debug.Log(meshFilter.gameObject.name + " PolygonCollider2D updated.");
     }
 }
 
 public static class EdgeHelpers
 {
     public struct Edge
     {
         public int v1;
         public int v2;
         public int triangleIndex;
         public Edge(int aV1, int aV2, int aIndex)
         {
             v1 = aV1;
             v2 = aV2;
             triangleIndex = aIndex;
         }
     }
 
     public static List<Edge> GetEdges(int[] aIndices)
     {
         List<Edge> result = new List<Edge>();
         for (int i = 0; i < aIndices.Length; i += 3)
         {
             int v1 = aIndices[i];
             int v2 = aIndices[i + 1];
             int v3 = aIndices[i + 2];
             result.Add(new Edge(v1, v2, i));
             result.Add(new Edge(v2, v3, i));
             result.Add(new Edge(v3, v1, i));
         }
         return result;
     }
 
     public static List<Edge> FindBoundary(this List<Edge> aEdges)
     {
         List<Edge> result = new List<Edge>(aEdges);
         for (int i = result.Count-1; i > 0; i--)
         {
             for (int n = i - 1; n >= 0; n--)
             {
                 if (result[i].v1 == result[n].v2 && result[i].v2 == result[n].v1)
                 {
                     // shared edge so remove both
                     result.RemoveAt(i);
                     result.RemoveAt(n);
                     i--;
                     break;
                 }
             }
         }
         return result;
     }
     public static List<Edge> SortEdges(this List<Edge> aEdges)
     {
         List<Edge> result = new List<Edge>(aEdges);
         for (int i = 0; i < result.Count-2; i++)
         {
             Edge E = result[i];
             for(int n = i+1; n < result.Count; n++)
             {
                 Edge a = result[n];
                 if (E.v2 == a.v1)
                 {
                     // in this case they are already in order so just continoue with the next one
                     if (n == i+1)
                         break;
                     // if we found a match, swap them with the next one after "i"
                     result[n] = result[i + 1];
                     result[i + 1] = a;
                     break;
                 }
             }
         }
         return result;
     }
 }
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Kiote · Aug 29, 2019 at 07:41 PM 1
Share

Worked Perfectly for me, thank you. Probably saved me about 5 hours of manually aligning polygon colliers.

avatar image Bunny83 Kiote · Aug 30, 2019 at 09:35 AM 0
Share

$$anonymous$$eep in $$anonymous$$d that this only works properly if your 3d meshes either have no depth changes at the silhouette or you're using an orthographic camera, so no perspective. However if an orthographic camera is used, it's kinda wasteful to use 3d meshes in the first place.

avatar image Joelia · Nov 05, 2021 at 04:07 PM 0
Share

I'm working with unity's ProBuilder and I was wondering if the script is possible to create an outline for shapes like this. For easier shapes it works perfectly!! (Btw the view in the screenshots won't be the game view)

@Bunny83 or @alpineboarder

][1]

mesh-with-pro-builder.png (105.5 kB)
mesh-with-pro-builder2.png (208.7 kB)
avatar image woahbust · Nov 20, 2021 at 04:04 PM 0
Share

i have tried to use this and although it does generate a polygon collider, it only seems to do so from the bottom of the mesh, instead of from the angle of the camera, do you know of any way to fix this?

avatar image Joelia woahbust · Nov 21, 2021 at 06:26 PM 0
Share

I don't know if we're dealing with the exact same problem but this is what worked for me:

When using probuilder only try to use the extrude function. For some reason when I try to add loopcuts to my mesh it messes with how the polygon collider gets created. (even though the topology is the exact same with both methods.)

So for now I just don't use loopcuts when I make things with probuilder. (Although I must say it's quite annoying to do it that way xd)

avatar image woahbust Joelia · Mar 16 at 03:09 AM 0
Share

I am not using probuilder, but the issue seems to be that it is using every edge instead of only the outer ones, and it doesn't change the colliders based on rotation, so its always generating them as if they had no rotation, although I get that 2d colliders don't work on rotated objects anyway.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

88 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Make a Good Collider on Blender import? 2 Answers

Cant fix my collider problem on an object, help me up :) 1 Answer

Unity 3D mesh collider collision detection 0 Answers

Mesh collider wont collide smoothly 0 Answers

Faux Gravity help 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges