Rolling Cube with Rigidbody?

Hi All,

New to Unity3D, a few hours in, so bear with me. I'm trying to create a cube that rolls along its edge based on key input. I've been able to get this working by referencing the code found in the thread, http://answers.unity3d.com/questions/742/rolling-cubes-one-space-and-one-rotation-at-a-time-with-a-delay. The problem I'm having is I'd like this cube to react to physics. Gravity, collisions, etc. For example if the cube is only rotated part way it should fall back into position, lying flat on the plane beneath it. If I attach a Rigidbody to the cube the rolling code does not function as I would like. The cube tries to roll a little then fails, then moves backwards unexpectedly. I'm using RotateAround to roll the cube. I tried experimenting with AddTorque but have been unsuccessful.

I did find that if I check the Is Kinematic option for the rigidbody the cube rolls along successfully and even collides with other objects. However, it is then unaffected by gravity. I feel like there is probably some proper way to do this that I'm unaware of due to lack of experience.

Any help would be appreciated.

Thanks

The script from the other answer won't help you much or you have to change a lot. The simplest solution is to give the Cube a `rigidbody` and add a script like this:

function FixedUpdate () {
    rigidbody.AddTorque(25, 0, 0);
}

of course, when the cube tipps over, it will still rotate but just around the same axis, that's now pointing up/downwards.

You might want to try transform.Rotate, which rotates the cube. The following script is an example:

function FixedUpdate () {
    if (Input.GetButtonDown ("Fire1")) {
        transform.Rotate (5, 0, 0);
    }

By the way, you might want to check out this tutorial for beginning Unity scripting. Good luck!

Ugh, loosing my mind here. I can't seem to get the cube to lock into place, moving only one grid space per 90 degree rotation. I'm able to get it to work when it travels in the x direction, rotating in the z. But not when it travels in the z and rotates in the x. Here's the code I use for moving the cube along the x axis...

function MoveX(direction: int)
{

    // get a reference to the x rotation so we can lock it back into place after the torque
    var rotationX: float = Mathf.Round(transform.eulerAngles.x);

    // add torque
    var torque: float =  Time.deltaTime * rotationSpeed * direction;
    rigidbody.AddTorque(0, 0, torque);

    // reset the rotation of the other axes
    transform.eulerAngles.x = rotationX;
    transform.eulerAngles.y = 0;

    // get the angle and transform it so it so it can be used to calculate positioning
    var angle: float = Mathf.Round(transform.eulerAngles.z);
    if(transform.position.x > xOffset) angle -= 360;

    // never really want it to be 360. Should be 0 instead.
    if(Mathf.Abs(angle) == 360) angle = 0;

    // determine if the cube is actively moving
    movingX = !((Mathf.Abs(angle) == 0 || Mathf.Abs(angle) == 90 || Mathf.Abs(angle) == 180 || Mathf.Abs(angle) == 270) && direction == 0);

    // determine the position based on the angle
    var x: float = -(angle / 360 * 4) + xOffset;

    // help
    Debug.Log("x          " + angle + "         " + x + "            " + transform.position.x);

    // lock the position
    transform.position.x = x;

    // determine if the cube has completed a total of 4 turns. 340 is used instead of 360 because
    // if the cube is traveling too fast it will skip right over 360 and go back to zero. Not sure 
    // about this logic, seems like there must be a better way to do this.
    if(Mathf.Abs(angle) >= 340)
    {
        transform.position.x = Mathf.Round(transform.position.x);
        xOffset = transform.position.x;
        transform.eulerAngles.z = 0;
    }

}

This code is called from FixedUpdate. The direction is determined by key input and is either -1, 0, or 1. I have a function just like this for moving in the Z as well but the value returned from eulerAngles.x is completely different. In the first rotation the x rotation goes from 0 to 90 as expected. However, the second rotation, in the same direction goes from 90 to 0 instead of 90 to 180. I have no idea why this would be. This happens even when I comment out everything accept the AddTorque and log eulerAngles.x.

Originally I was determining the angle using the rotation Quaternion and a call to ToAngleAxis. This worked great if the cube only ever rotated along one axis (either one). But, when I rotated it along one axis and then the other the it was like the rotational values for the different axes got out of sync or something.

Any suggestions would be greatly appreciated. I feel like I'm probably doing this the hard way but don't know how else I might accomplish what I'm trying to do.

Thanks

hey you should check out my qeustion How To Make A Cube Roll hope its usefull.

Here’s a short Youtube video that covers exactly how to roll a cube on its edges: How to Move a Cube by Rolling it | Unity Tutorial - YouTube


rolling cube