0
\$\begingroup\$

I have two kinematic rigidbody cubes from the standard 3D objects, I have also enabled contact pairs mode to "all contact pairs", how do I make it so that no matter what angle they collide in they perserve the same angle but just get out of each others space making it look like they're in contact e.g. collided?

Here is my attempt at doing that:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

 public class Physics : MonoBehaviour
{
  private Collider collider1;
  private bool grounded = false; //used to determine if the collider hit something so it doesnt keep going down

// Start is called before the first frame update
void Start()
{
    collider1 = GetComponent <Collider>();
}

// Update is called once per frame
void Update()
{
    if (!grounded) //if the collider hit something, stop going down
    {
        collider1.transform.Translate(0f,-.1f,0f,Space.World);
        
    } 
}

private void OnCollisionEnter(Collision collision)
{        
    grounded = true; //the collider hit something
    if(collider1.transform.position.y != collider1.bounds.extents.y) //if this is true, it means it is at the floor so dont move it
    {
        transform.position = new Vector3(collider1.transform.position.x, collision.collider.bounds.size.y + collider1.bounds.extents.y, collider1.transform.position.z); //attempts to put the collider on top of whatever it get

    }        

 }

}

This works if the cubes are right on top of each other with no angle: enter image description here

It also works if one of the cubes collides at a angle to the other cube, when they collide the bottom cube perverse its angle of collision and and the top cube just gets out of the space of the other collider making it look like they have collided: enter image description here What doesn't seem to work is if both cubes collide with each other at a angle, although they preserve their angle of collision, and also get out of each others space, they do not remain in contact with each other which if they did would make it look like they have collided.

enter image description here Instead there is a gap between them, how do I get rid of the gap e.g. make it so that no matter what angle the objects are at they get out of each others space, preserve the angle, and remain in contact with each other to give the illusion that they have collided?

\$\endgroup\$
2
  • \$\begingroup\$ Wouldn't rigibodies have this behaviour by default? \$\endgroup\$ – Weckar E. Nov 23 '20 at 8:52
  • \$\begingroup\$ Remember that bounds are axis-aligned. Did you consider using a BoxCast to sense how far a box of a given shape and rotation can slide before touching a surface? \$\endgroup\$ – DMGregory Nov 26 '20 at 12:00
0
\$\begingroup\$

Simply set the inverse inertia tensor to all zeros. The simple explanation here is that the inertia tensor of an object describes how that object resists rotation when acted upon by outside forces. A zero inverse inertia tensor implies that the object has infinite inertia in all directions, and thus resists all rotation produced by physics.

https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/UnityPhysicsSamples/Assets/Demos/2.%20Setup/2b.%20Motion%20Properties/Scripts/SetInertiaInverseBehaviour.cs

Another option is to use angular constraints.

https://docs.unity3d.com/Manual/class-RotationConstraint.html

\$\endgroup\$
0
\$\begingroup\$

As I mentioned in a comment, you can use a BoxCast to scan possible positions for a box along a line, and stop it at the moment it touches another object. Something like this:

Vector3 GetStackedPosition(Vector3 lowest, float maxHeight, Vector3 halfExtents, Quaternion orientation) {

    Vector3 start = lowest;
    start.y += maxHeight;

    if (!Physics.BoxCast(start, halfExtents, Vector3.down, out RaycastHit hit, orientation, maxHeight))
        return lowest;

    Vector3 result = start;
    result.y -= hit.distance + 2f * Physics.defaultContactOffset;

    return result;
}

If you're spawning all these cubes on the same frame, then be sure to call Physics.SyncTransforms after placing each one, so that the physics engine knows where its collider ends up and can use it as a potential obstacle for the next cast.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.