Unity Cube Rolling

Unity Cube Rolling


Unity Cube Rolling

 Hello everyone, I'm here again with a new Unity lesson. In today's video, I will try to explain to you how you can roll a cube in Unity, and how you can rotate an object by changing the positions of the pivot points inside the object..

Cube Rolling Step 1 - Preparing the Scene

First, let's prepare our scene. I am preparing a floor with 9 cubes of the same size, and designating a cube of the same size as the character. I assign 2D square images I found on the internet to the floor cubes and my character so that it is clear which is which.

Unity Cube Rolling Scene

Every cube I put in my scene has a size of 1Br for Unity.

Additionally, I should mention that for now, I haven't assigned any properties to either my floor cube or my character cube except for the 2D images. (Like Rigidbody) 

If you want to assign a physical property, if you do not freeze rotation and position on your character cube's rigidbody, you may encounter problems.

Cube Rolling Step 2 - Understanding the Logic of Rotating the Cube

Now, if we try to rotate our cube without understanding how to roll it, because our foundation is not solid, we will encounter problems and will constantly be trying to fix errors, so first let's understand what kind of approach we should take.

In 3D objects, there is a point called the pivot point, which is usually located exactly in the center of the object. Objects rotate based on these pivot points when performing rotation operations.

Let me show you with a short video what happens when this pivot point is in the center during rotation.



As you can see, since the pivot point is centered, the middle part is always taken as a reference for rotation. By moving the pivot points to the corners, we will enable our cube to move in the desired direction.

To better understand what happens when this pivot point is moved to a corner, let me add a new cube and try to explain this concept to you in the simplest way.

I created a new cube, placed it in the direction I want my character cube to rotate, then parented my character cube to the new, smaller cube. When I rotated the small cube, my character cube also performed the rotation movement from the pivot point.



As you can see, our cube rotates exactly in the direction we want and moves. In fact, instead of doing this movement, i.e., setting the pivot point, with an extra cube, we will do it for our character cube in the code and make it much simpler.

Cube Rolling Step 3 - Writing the Code

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

public class kupYuvarla : MonoBehaviour
{
    #region Variables
    public float donmeHizi; // The variable we use to calculate in how many steps it will rotate.
    bool donmeKontrol = false; // The variable we created to prevent the cube from being rotated again while it is rotating.
    #endregion

    #region Unity Functions
    void Update()
    {
        KupDondurTusKontrol(); // Here we call our function to rotate the cube.
    }
    #endregion

    #region Functions for Rotating the Cube
    void KupDondurTusKontrol() // Our function that checks which keys will be pressed for the cube to rotate.
    {
        if (donmeKontrol) // We check whether our cube is rotating.
        {
            return; // If the cube is rotating, prevent the following code from running.
        }
        else // If the cube is not rotating, run the following code
        {
            Vector3 _kupKonum = transform.position; // We get the current position of the cube
            if (Input.GetKeyDown(KeyCode.W)) // Specify what happens when the W key is pressed
            {
                donmeKontrol = true; // Set the cube's rotation status
                StartCoroutine(KupDondur(_kupKonum + new Vector3(0, -0.5f, 0.5f), Vector3.right)); // Change the pivot point according to cube position, command to rotate to the right.
            }else if (Input.GetKeyDown(KeyCode.S)) // Specify what happens when the S key is pressed
            {
                donmeKontrol = true; // Set the cube's rotation status
                StartCoroutine(KupDondur(_kupKonum + new Vector3(0, -0.5f, -0.5f), Vector3.left));  // Change the pivot point according to cube position, command to rotate to the left.
            }
            else if (Input.GetKeyDown(KeyCode.A))
            {
                donmeKontrol = true; // Set the cube's rotation status
                StartCoroutine(KupDondur(_kupKonum + new Vector3(-0.5f, -0.5f, 0), Vector3.forward));  // Change the pivot point according to cube position, command to rotate upwards.
            }
            else if (Input.GetKeyDown(KeyCode.D))
            {
                donmeKontrol = true; // Set the cube's rotation status
                StartCoroutine(KupDondur(_kupKonum + new Vector3(0.5f, -0.5f, 0), Vector3.back));  // Change the pivot point according to cube position, command to rotate backwards.
            }
        }



    }

    IEnumerator KupDondur(Vector3 pivotNoktasi, Vector3 _vector) // We use IEnumerator to move the cube so the rotation is smoother, not instantaneous.
    {
        // Take the rotation angle as 90, divide it by rotation speed, and use for loop to match it.
        for (int i = 0; i < (90 / donmeHizi); i++)
        {
            this.transform.RotateAround(pivotNoktasi, _vector, donmeHizi); // Here we perform the rotation for the cube.
            yield return new WaitForSeconds(0.001f); // Set how long to wait at each rotation position.
        }
        // Sometimes the cube may be placed at a position like 0.99999; here we arrange the position to the closest integer for accuracy.
        Vector3 _yeniKonum = new Vector3(TamSayiyaDonustur((double)transform.position.x), TamSayiyaDonustur((double)transform.position.y), TamSayiyaDonustur((double)transform.position.z));
        this.transform.position = _yeniKonum; // Set the cube's position to the newly arranged location.
        donmeKontrol = false; // Restore the rotation status
        yield return null; // Continue immediately without delay.

    }
    #endregion

    #region Other Functions
    // Function to round the cube position to the closest integer
    int TamSayiyaDonustur(double sayi){
        return Mathf.RoundToInt((float)sayi); // Use RoundToInt for values like 0.999; for example, 0.999 = 1 or 1.98989 = 2.
    }
    #endregion
}

The only thing I need to explain here is that normally our character moves right and left based on the z axis and vertically with x, but here it's entered in the opposite way; if you don't, your character can take up-down directions..

Note: After writing the script, don't forget to assign it to the cube you want to rotate and enter the rotation speed value, and in my opinion, select a rotation speed that divides 90 evenly, otherwise you might encounter minor issues.

The comments above explain exactly what each part of the code does, so I won't repeat explanations here, but if you get stuck anywhere related to the code, you can write it as a comment below.

Cube Rolling Step 4 - Let's Look at the Result