# Rolling cubes one space and one rotation at a time, with a delay

 0 I am about a week in to Unity but reading through all the tutorials, guides and documentation I can as quickly as I can. I have what I'm sure is a simple scenario but I'm having trouble determing the method to tackle it in Unity. What I want to do is have a row of cubes roll 90 degrees and one position downward followed by a delay of 2 seconds (an arbitrary number of seconds), and then repeat. Put another way, I want the cube to roll over on its side in the direction it is rolling. From what I've gathered so far, I thought one way would be to transform the cube at set intervals: private var cubeTimer : float = 0.0; private var currentCube : GameObject; private var cubeTime : float = 2.0; private var cubeSpeed : float = 50.0; function Update () { cubeTimer += Time.deltaTime; spinAmount = Time.deltaTime * cubeSpeed; if (cubeTimer > cubeTime){ transform.position.x = transform.position.x +1; cubeTimer = 0.0; } transform.Rotate(0, 0, -spinAmount); } That's rotating it, but that rotation doesn't match up with the movement in the x-axis properly, so it looks awful. How could I sync the roll to exactly match up with the x-asix movement? Should I be doing this as a RigidBody and AddMotion instead? I tried that, but the roll didn't seem predictable depending on where the block was on the plane. There are animation curves I know, but I wonder how I would sync the rotation and movement on the x-axis. more ▼ asked Nov 25 '09 at 04:20 AM TedB 26 ● 2 ● 3 ● 7 runevision ♦♦ 8.1k ● 29 ● 46 ● 112 add new comment (comments are locked) 10|3000 characters needed characters left ▼ Viewable by all users

2 answers: sort voted first
 0 A simple solution is to do the rotation as an animation where at the end of the animation the cube has moved the +1 distance. Alternatively use Transform.rotateArount to rotate around a point on the edge of the cube you're currently rolling over. If not clear what I mean, let me know, can make an example or so. EDIT: too much fun to pass, here sample code in C# (sorry not too fond of javascript but shouldn't be too hard to convert if you need), Just create new C# class called RollCube and copy/paste code below over it. EDIT2: now have rotation done from Coroutine so we can delay after rolling to a side. using UnityEngine; using System.Collections; public class RollCube : MonoBehaviour { public float cubeSize = 1f; public float cubeSpeed = 50f; public float delay = 2f; private float totalRotation = 0f; // determines if we're past the 90 degrees private float startHeight = 0f; // for correcting height errors // next two vars are for determining the corner // to rotate over private float fwdWeight = 0.5f; private float upWeight = -0.5f; // Use this for initialization void Start () { startHeight = transform.position.y; StartCoroutine(CORollCube()); } IEnumerator CORollCube() { while (true) { // we calc the spinamount but make sure it won't shoot over the 90 degrees float spinAmount = Mathf.Min(Time.deltaTime * cubeSpeed, 90f - totalRotation); // we rotate around one of the edges of the cube (the stationary one of course) transform.RotateAround(transform.position + (fwdWeight * transform.forward + upWeight * transform.up) * cubeSize, Vector3.right, spinAmount); // add to amount of spin in this update the total rotation totalRotation += spinAmount; // check if we have to move to the next edge if (totalRotation >= 90f) { // we move to next corner as pivot point totalRotation -= 90f; float t = fwdWeight; fwdWeight = -upWeight; upWeight = t; // make sure height stays correct Vector3 pos = transform.position; pos.y = startHeight; transform.position = pos; // wait for delay amount of seconds yield return new WaitForSeconds(delay); } else { // ready for this frame yield return 0; } } } } more ▼ answered Nov 25 '09 at 04:36 AM Jaap Kreijkamp 6.4k ● 20 ● 26 ● 70 Thanks for the quick answer and code for rotating and moving the cube forward at the same time. Looks great!I'm having trouble applying it though with a delay after the move. I figured I could pause it after a 90 rotation with a yield WaitForSeconds(2) but that doesn't stop it at all. My goal is to be able to start and stop the cube advancing one position at a time if a player does something, otherwise, keep moving, with a pause between moves. Am I on the right track? Any idea what's up with yield not yielding? Nov 28 '09 at 04:41 AM TedB That update with the coroutine works great. I was trying to do the coroutine in JavaScript but evidently not correctly. I'll leave it as C# for now. Nov 30 '09 at 02:51 AM TedB That came handy to me! Was not trying out for any of these things but obviously there was a rotation and shifting of pivot points! Thanx!!! Jan 25 '12 at 07:58 AM ArunChnadran add new comment (comments are locked) 10|3000 characters needed characters left ▼ Viewable by all users
 0 // Reposting this non-working answer because it was unreadable when posted as a comment to the previous answer var cubeSize : float = 1; var cubeSpeed : float = 80; private var totalRotation : float = 0; // determines if we're past the 90 degrees private var startHeight : float = 0; // for correcting height errors // next two vars are for determining the corner // to rotate over private var fwdWeight : float = 0.5; private var upWeight : float = -0.5; // Use this for initialization function Start () { startHeight = transform.position.y; } // Update is called once per frame function Update () { DoRoll(2); } function DoRoll (delay: float) { var spinAmount : float = Time.deltaTime * cubeSpeed; var t : float; var pos : Vector3; // we rotate around one of the edges of the cube (the stationary one of course) transform.RotateAround(transform.position + (fwdWeight * transform.forward + upWeight * transform.up) * cubeSize, Vector3.right, spinAmount); // add to amount of spin in this update the total rotation totalRotation += spinAmount; // check if we have to move to the next edge if (totalRotation >= 90) { // we move to next corner as pivot point totalRotation -= 90; t = fwdWeight; fwdWeight = -upWeight; upWeight = t; // make sure height stays correct pos = transform.position; pos.y = startHeight; transform.position = pos; print ("At rotation " + totalRotation); yield WaitForSeconds(delay); } } more ▼ answered Nov 28 '09 at 04:48 AM TedB 26 ● 2 ● 3 ● 7 thanx for the conversion too!! Jan 25 '12 at 08:49 AM ArunChnadran add new comment (comments are locked) 10|3000 characters needed characters left ▼ Viewable by all users

### Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

Topics:

x5084
x3791
x2168

asked: Nov 25 '09 at 04:20 AM

Seen: 4150 times

Last Updated: Jan 25 '12 at 08:49 AM