- Home /
Create a custom Collider?
Is it possible to make your own custom Collider object in Unity?
I know there is the MeshCollider object, but I'm talking about creating a shape that is defined by an equation. For example, if you wanted to make your own sphere collider (I know there is one built in, this is just an example.), you could check for collisions by seeing if any object is within a certain distance (radius) of the collider.
I know you can create a script class that inherits from Collider, like so:
using UnityEngine; public class CustomCollider : Collider {
}
However, I'm not sure what methods to "override" to check for collisions or whatnot. Perhaps this is not possible at all.
I was able to successfully implement what I'm talking about in Bullet and I talk about it on my blog, if you're interested: http://recreationstudios.blogspot.com/2010/04/spherical-terrain-physics.html
Answer by skovacs1 · Dec 06, 2010 at 11:54 PM
Hmmm. Kind of an odd question. Perhaps it might be enlightening to have a better understanding what it is exactly you want from Unity's physics engine.
Unity's Physics engine has different collider types which implement known intersection algorithms for simple primitives Sphere, Box, Capsule and Plane. Mesh colliders are be more expensive as they would have to perform in the worst case per-triangle intersections. I believe that most if not all of this is done through PhysX, but that really doesn't matter since we cannot really change how these colliders and their collisions are implemented under the hood.
I'm sorry I don't have a better answer, but because of this closed implementation, I do not believe that you can easily override the base collider if at all. I am afraid you will likely have to make do with the MeshCollider. If you are trying to do something as you describe in the linked blog post (tessellate based on proximity to the camera or something according to some noise?) you would indeed likely have to modify the mesh where you are changing it, using the renderer's mesh interface. You wouldn't have to replace the entire mesh exactly, but you would have to find, change/add the appropriate vertices, triangles, uvs and normals and because of the automated recalculations when this happens, you had best store the arrays in temporary memory, change them and then re-assign them, meaning that for all that it matters, you really are replacing the mesh.
The problem stems from the fact that I only use one shared mesh (and one shared material) in order have the best batching. The geometry is completely displaced on the GPU. On the CPU side, the geometry just makes up a cube, but on the GPU it makes up spherical terrain. I cannot use the meshes as they are in Unity for collision because they are not even close to the final render. I also cannot displacement them on the CPU because that would be far too costly.
I've already begun work on a system that is similar to my blog post, and it seems very promising so far. I need to do some more experimentation with it, and then I'll probably post it here.
Please do. I'd like to know how you got GPU displacement to affect CPU physics. Did you roll your own physics solution that does some sort of lookup to your displacement or something?
Answer by GlitchEnzo2 · Dec 08, 2010 at 08:39 AM
I've implemented a system that seems to be working fairly well. It's very similar to the method I implemented in Bullet that I described in my blog. The one major difference is that the triangle processing in Bullet is double sided (collision is in both directions) whereas the MeshCollider in Unity is only single sided (collision is only in 1 direction). That required me to reverse some of my triangles, but that wasn't hard.
Here is my solution: I set up a trigger volume (a sphere) surrounding my spherical terrain, and then I overrode the trigger Enter, Stay, and Exit methods. The Enter and Stay methods are the same. They calculate the 8 corners of the bounding box and then project them down to the terrain. If any of the corners collide with the terrain, then a MeshCollider is created/updated using the 3 closest sides projected to the terrain (only 6 triangles are in each MeshCollider). So, all of the collision response is still handled by Unity/PhysX.
It is optimized slightly by storing the MeshCollider objects in a Dictionary that is keyed off of the original GameObject. That way, only the mesh needs to be updated, instead of destroying and recreating a new GameObject every frame. The Exit method is used to remove the entries from the Dictionary.
I want to add a further optimization where stationary GameObjects (ones just sitting on the terrain) don't have their meshes updated. This will require another Dictionary storing the previous positions, but that should be fairly simple.
As I said it works fairly well. I haven't seen any objects fall through the terrain, and it has no noticeable slow down with 6 objects colliding with the terrain at the same time. I'll plan on doing a test with a lot more objects to see what sort of performance hit there is.
I would post the code here, but it's kind of lengthy (over 150 lines). If anybody is interested in certain parts, I can post those.
you could post it to the unity community wiki with a small description :)
I'm working on a game that involves driving all around a perfect sphere. Problem is that my sphere is nowhere near perfect. I think you might have the expertise I need in working things out if you had a moment to look it over, please and thank you. Hopefully you still have some of the script you mention in this post, as I would love to learn from it. :) I started a post here
If you want your collider to be a perfect sphere why not use the SphereCollider? $$anonymous$$y solution is useful only if you want spherical terrain (a bumpy, non-perfect sphere).
ye. the sphere collider feels right, but the ground still isn't actually spherical. so you end up driving over empty air between edges.
Oh, so the mesh you use for rendering the sphere has gaps? That's a different problem entirely. I'm guessing your sphere is actually a displaced cube made of 6 different sides? Those gaps are usually caused by floating point precision issues.
Answer by spalmer · Mar 31, 2015 at 03:09 PM
I hate the builtin spheres so much I'm making perfect raytraced replacements. I already have the rendering working for an ellipsoid, now I want a custom collider that handles the ellipsoid properly, but Unity's builtin SphereCollider can't handle NU scale. I've got an idea how to use script to create and manage a unique custom SphereCollider for each potentially penetrating object, update a SphereCollider each frame to correspond to some approximate representation of the closest point on surface to each object as a sphere. What you guys are saying makes me think it might be possible. But if managing the different layers/masks gets to be a problem I can just use a finely tesselated MeshCollider I suppose... nasty. Yeah I realize this all has to run deep inside PhysX's pipeline, but hoped there was some way of implementing some kind of callback.
Answer by 1o482013581451 · Apr 30, 2015 at 11:32 AM
Yes it is. All you have to do is go to "add component", "physics", and "mesh collider". It will create a collider in the exact shape of the mesh.
this is biggest lie, it cant handle nonconvex meshes at all
Your answer
Follow this Question
Related Questions
Trying to use colliders on trees to interact with player 1 Answer
How do i prevent an imported Mesh from falling through Terrain? 3 Answers
collision with terrain problem? 3 Answers
How to get OnCollisionEnter working with Terrain. JavaScript 2 Answers
Unity 4 - Sphere Falls through Terrain 2 Answers