Can you get polygon collider 2d shape from a sprite?
When you create an object with polygon collider 2d from inspector, unity automatically generates polygon collider that approximately fits the sprite. My question is if there is a way to do that when creating an object from a script? While searching for a solution I found that each sprite has a sprite mesh which has vertices. I tried setting those as a path for my collider, but the result is a mess: their order appears to be messed up. My current code:
Sprite spr; // I get that in other part of the code
GameObject go = (GameObject)Instantiate(prefab, gameObject.transform);
go.GetComponent<SpriteRenderer>().sprite = spr;
go.GetComponent<PolygonCollider2D>().SetPath(0, spr.vertices);
Answer by tribski · Sep 26, 2016 at 02:15 AM
There appears to be a somewhat good solution: add new polygon collider ( and remove the old one). When you add new collider with go.AddComponent<PolygonCollider2D>();
it will be generated to fit the mesh.
I don't know if it's best practice or not but it works great! Thanks!
This way is working in editor but not in android device. Have any idea how to fix such problem?
Answer by CaseyHofland · Sep 12, 2020 at 09:09 AM
For anyone finding this, there is a better way than OP's answer (sorry senpai).
// Store these outside the method so it can reuse the Lists (free performance)
private List<Vector2> points = new List<Vector2>();
private List<Vector2> simplifiedPoints = new List<Vector2>();
public void UpdatePolygonCollider2D(float tolerance = 0.05f)
{
polygonCollider2D.pathCount = sprite.GetPhysicsShapeCount();
for(int i = 0; i < polygonCollider2D.pathCount; i++)
{
sprite.GetPhysicsShape(i, points);
LineUtility.Simplify(points, tolerance, simplifiedPoints);
polygonCollider2D.SetPath(i, simplifiedPoints);
}
}
This way you don't have to destroy / add a new PolygonCollider2D each time, plus the points List can be recycled for some free optimization.
Thanks to @empath for pointing me towards LineUtility.Simplify!
Your method is pretty amazing, it's cool seeing such a tight collider around a character model.
That said... there are some extreme performance ramifications for doing so. Even when 2 objects with only polygon colliders on them that are set to not detect one another in the project settings touch are laid on top of one another, my FPS drops by 20. (This seems unintended?)
You mention doing point optimization using DouglasPeukerReduction, is that something easily copyable?
EDIT: I feel like a fool. I swear I already searched and couldn't find anything. I don't know if this is what you used, but for anyone else curious, this seems to do the trick: https://docs.unity3d.com/ScriptReference/LineUtility.Simplify.html
Your answer
Follow this Question
Related Questions
How can i get a transform to move to another transform if it is touching it? 0 Answers
Help with making an object dodge other objects? 0 Answers
Collider2D.Cast doesn't detect some parts of my composite collider 2D 0 Answers
Two colliders that trigger different things in the same object-hierarchy 0 Answers
4 line code not working! 1 Answer