I need a rigibody to move through an object but the object needs to react to the rigidbody

I am building an excavator sim/game and I got to the point where I am using rigidbodies to control the arm and bucket. The ground is a mesh (I cannot use Terrain) and I got it to react when the bucket hits it.

The mesh reacts by lowering the vertices where the bucket hits. Ofcourse I want to be able to dig a deeper hole so the script recalculates the meshcollider to keep track of the new hits. To keep the frame rate up I use a Coroutine for this. To make the game faster I want to recalculate every half second or maybe even every second, the bucket is not moving at a very high speed so the ground doesn’t need to be recalculated every frame, there will be enough mesh to hit to get a good looking hole.

That all works fine, the problem is: when the recalulation is done the bucket bounces off the new collider. How can I make the rigidbody of the bucket ignore the meshcollider but let the mesh and meshcollider react to the bucket?

``````    void OnCollisionStay(Collision collision)
{
if (collision.gameObject == Bucket)
{
foreach (var contact in collision.contacts)
{
Vector3 Direct = contact.normal;
if (Direct.x < 0) { Direct.x = 0 - Direct.x; } //set values positive if negative for comparison
if (Direct.y < 0) { Direct.y = 0 - Direct.y; }
if (Direct.z < 0) { Direct.z = 0 - Direct.z; }

if (Direct.x > Direct.y) { AddDepression(contact.point, 1, -Vector3.up); } //if ground is more than 45deg. vertical just move down
else if (Direct.z > Direct.y) { AddDepression(contact.point, 1, -Vector3.up); }
else { AddDepression(contact.point, collisionRadius, contact.normal); } //else move down in proper direction
}
}
}

{
//recalculating where it hits when plane is not on 0,0,0 coordinates
float ImpactPointX = depressionPoint.x - plane.transform.position.x;
float ImpactPointY = depressionPoint.y - plane.transform.position.y;
float ImpactPointZ = depressionPoint.z - plane.transform.position.z;

var LocalPos = new Vector3(ImpactPointX, ImpactPointY, ImpactPointZ);

//in Start() the vertices of plane are put into a List called modifiedVertices
for (int i = 0; i < modifiedVertices.Count; ++i)
{
//is the vertex whithin a specified distance of the contact.point
var distance = (LocalPos - modifiedVertices*).magnitude;*
``````

if (distance < radius)//yes it is!
{
var newVert = modifiedVertices*; //get coords from existing location*
newVert = newVert + direction * maximumDepression; //move from existing location in the direction of contact.normal * a maxdepression
modifiedVertices.RemoveAt(i); //empty old coords
modifiedVertices.Insert(i, newVert); //write in new coords
}

}
plane.GetComponent().mesh.SetVertices(modifiedVertices); //set new vertix locations

StartCoroutine(“RecalculateMeshCollider”);//calculate new collider, needed to dig further
}

IEnumerator RecalculateMeshCollider() {
Physics.IgnoreCollision(plane.GetComponent(), Bucket.GetComponent());//switch off collisions for smooth movement through ground

plane.GetComponent().sharedMesh = plane.GetComponent().mesh; //set sharedmesh to new mesh
yield return new WaitForSeconds(1); //wait a second
Physics.IgnoreCollision(plane.GetComponent(), Bucket.GetComponent(), false);//switch collisions back on (and launch bucket apparently)
}

If you don’t want the bucket to collide with anything at all, but still react to things, you can set isTrigger to true in the bucket’s collider.
You can then use OnTriggerEnter, OnTriggerStay and OnTriggerExit to detect things the bucket collide with.

If you want the bucket to collide with other things but not the ground, you can use Layer-based collision detection. The bucket and ground should be on layers that doesn’t collide with each other. You can then attach a trigger as a child object which you set to a layer which collides with the ground, and detect whether it is going through the ground with OnTriggerEnter/Stay/Exit.