How can I specify the mesh to my MeshCollider ?
I already add it to my mesh
by user 224464722878005248
How can I specify the mesh to my MeshCollider ?
I already add it to my mesh
by user 224464722878005248
By using addNewComponent, do I need to make another thing to make it works ?
by user 224464722878005248
So, MeshCollider is a component and you need to speicify what Mesh data it will use. (that will be the sharedMesh property)
const colliderObject = new Object3D(); // new object that will host the mesh collider component
this.gameObject.add(colliderObject); // add it as a children to the main object
const renderer = this.gameObject.getComponent(MeshRenderer); // get the mesh renderer from the main object
const collider = new MeshCollider(); // create a new MeshCollider component
// sanitize input
if(renderer && renderer.sharedMesh) {
collider.sharedMesh = renderer?.sharedMesh; // set the mesh of the mesh renderer to the mesh collider
GameObject.addComponent(colliderObject, collider); // add the MeshCollider component to the new gameobject
}
else {
console.error(`no mesh can be found on ${this.gameObject.name}`, this.gameObject);
}
It is called SharedMesh to save performance since as the name hints, it will reuse the same instance on multiple colliders as possible, same applies to materials.
Let me know if anything wouldn’t be clear
Hmmm okay
by user 224464722878005248
I will try, thanks a lot Kipash
by user 224464722878005248
It came to my attention that this would work if the object is from Unity. But if you load an external model it likely uses Three.js objects directly and there is no MeshRenderer. Let me see, if i can clarify what to do in such case.
Yes, there is no MeshRenderer
by user 224464722878005248
I got error and after a log, the renderer is null
by user 224464722878005248
How could I do ?
by user 224464722878005248
I tried to add a MeshRenderer component bu it’s not sufficient
by user 224464722878005248
var mesh: Mesh | null = null;
instance.traverse((x: Object3D) => { // iterate through all children
if(mesh) return; //already found a result
mesh = x instanceof Mesh ? x : null;
});
if(mesh != null) {
mesh = mesh as Mesh;
// create the mesh collider and assign the mesh
const collider = new MeshCollider();
collider.sharedMesh = mesh!;
// create a host object to hold possible offsets
const colliderObject = new Object3D();
GameObject.addComponent(colliderObject, collider); // add the new collider to the new collider object
// add the collider object under the mehs to get correct scale, position and rotation
mesh.add(colliderObject);
// add rigidbody to the main object
const rigidbody = new Rigidbody();
rigidbody.isKinematic = true; // for debuging purposes otherwise it falls endlessly
instance.addComponent(rigidbody);
}
so, in your case the instance
variable is your rightRooth
.
The code is naive in the sense that it tries to find the first Mesh object in the hiearchy, you could run in to problems if a tooth visual is comprised of two Meshes.
This is how it looks like in our ExternalContent sample where the green outline is the MeshCollider visualized by ?showcolliders
That’s weird… I got one warning and one error by tooth
Here the coliders generated :
by user 224464722878005248
The warning :
Your model is using scaled mesh colliders which is not optimal for performance LowerTooth_42
The error :
rapier_wasm3d.js:133 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
at q (rapier_wasm3d.js:133:28)
at _.trimesh (rapier_wasm3d.js:3830:22)
at oI.intoRaw (shape.ts:817:25)
at MI.createCollider (collider_set.ts:65:35)
at sI.createCollider (world.ts:342:31)
at _RapierPhysics.createCollider (engine_physics_rapier.ts:653:32)
at _RapierPhysics.addMeshCollider (engine_physics_rapier.ts:583:30)
at MeshCollider.onEnable (Collider.ts:93:42)
at MeshCollider.__internalEnable (Component.ts:499:14)
at set enabled [as enabled] (Component.ts:554:18)
Still
by user 224464722878005248
by user 224464722878005248
Example of the tooth that I use
by user 224464722878005248