Taken from the “sculpt vertices” of the Unity’s “Procedural Examples”:
function Update () {
// When no button is pressed we update the mesh collider
if (!Input.GetMouseButton (0))
{
// Apply collision mesh when we let go of button
ApplyMeshCollider();
return;
}
// Did we hit the surface?
var hit : RaycastHit;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, hit))
{
var filter : MeshFilter = hit.collider.GetComponent(MeshFilter);
if (filter)
{
// Don't update mesh collider every frame since physX
// does some heavy processing to optimize the collision mesh.
// So this is not fast enough for real time updating every frame
if (filter != unappliedMesh)
{
ApplyMeshCollider();
unappliedMesh = filter;
}
// Deform mesh
var relativePoint = filter.transform.InverseTransformPoint(hit.point);
DeformMesh(filter.mesh, relativePoint, pull * Time.deltaTime, radius);
}
}
}
function ApplyMeshCollider () {
if (unappliedMesh && unappliedMesh.GetComponent(MeshCollider)) {
unappliedMesh.GetComponent(MeshCollider).mesh = unappliedMesh.mesh;
}
unappliedMesh = null;
}
Could someone explain me the functionality of this piece of code? Especially the part of the mesh collider update. What exactly does and when? Which commands and under which sequence they function in order to hold it from not updating every frame?
I have examined the code thoroughly, but due to my minor programming level, I cannot understand some parts. Also by trying the example in run-time, I couldn’t figure out the collider’s behavior.
Thank you in advance Unity Community.
// When no button is pressed we update the mesh collider
if (!Input.GetMouseButton (0))
{
// Apply collision mesh when we let go of button
ApplyMeshCollider();
return;
}
Here the mesh collider is updated when the user is not pressing the left mouse button, however the mesh collider is only likely to be updated once as the function ApplyMeshCollider will only update the collider if the unappliedMesh is not null and it is set to null at the end of the function everytime.
So what this essentially means is when the user lets go of the left mouse button the collider is updated at most one time, and the return statement means the rest of the code is not reached.
When the user does press the left mouse button this section of the code is called:
// Did we hit the surface?
var hit : RaycastHit;
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, hit))
{
var filter : MeshFilter = hit.collider.GetComponent(MeshFilter);
if (filter)
{
// Don't update mesh collider every frame since physX
// does some heavy processing to optimize the collision mesh.
// So this is not fast enough for real time updating every frame
if (filter != unappliedMesh)
{
ApplyMeshCollider();
unappliedMesh = filter;
}
// Deform mesh
var relativePoint = filter.transform.InverseTransformPoint(hit.point);
DeformMesh(filter.mesh, relativePoint, pull * Time.deltaTime, radius);
}
}
This bit of code is doing the following; create a ray cast from the point of the mouse cursor (best way to imagine it is sending out a laser from your cursor which can hit objects in the scene), then check if the ray cast has hit anything in the scene, if it has hit something then try to get the mesh filter of that object, if the object does have a mesh filter then check if the two meshes are the same mesh (So if the deformed mesh you want to apply is the same as the current mesh then dont update the collider), if the two meshes are different then give the collider the new mesh and set the unapplied mesh to null.
I hope that clears a few things up for you.
EDIT:
Ok so I managed to get the mesh collider to update properly, it probably isn’t the base way to do it but hopefully you can build on it from there:
var CanUpdate = false;
function ApplyMeshCollider () {
if (unappliedMesh && unappliedMesh.GetComponent(MeshCollider)) {
if(CanUpdate)
{
unappliedMesh.GetComponent(MeshCollider).sharedMesh = null;
}
unappliedMesh.GetComponent(MeshCollider).sharedMesh = unappliedMesh.sharedMesh;
}
//unappliedMesh = null;
CanUpdate = !CanUpdate;
}
So try placing the variable at the top of the script with the rest and replacing the ApplyMeshCollider function with my one and see if that gives a better result.