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
}
}
}
public void AddDepression(Vector3 depressionPoint, float radius, Vector3 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[i]).magnitude;
if (distance < radius)//yes it is!
{
var newVert = modifiedVertices[i]; //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<MeshFilter>().mesh.SetVertices(modifiedVertices); //set new vertix locations
StartCoroutine("RecalculateMeshCollider");//calculate new collider, needed to dig further
}
IEnumerator RecalculateMeshCollider() {
Physics.IgnoreCollision(plane.GetComponent<Collider>(), Bucket.GetComponent<Collider>());//switch off collisions for smooth movement through ground
plane.GetComponent<MeshCollider>().sharedMesh = plane.GetComponent<MeshFilter>().mesh; //set sharedmesh to new mesh
yield return new WaitForSeconds(1); //wait a second
Physics.IgnoreCollision(plane.GetComponent<Collider>(), Bucket.GetComponent<Collider>(), false);//switch collisions back on (and launch bucket apparently)
}
Answer by GamePaint · Aug 10, 2018 at 11:17 PM
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.
Your answer
Follow this Question
Related Questions
Position and collider seem to incorrectly shift when moving object 0 Answers
hi guys am having a problem with my player 0 Answers
Rigidbody is colliding terrain on isKinematic = false. call although meshes don't touch 0 Answers
how to prevent a kinematic rigidbody from going through static colliders 0 Answers