- Home /
Rolling cubes one space and one rotation at a time, with a delay
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.
Answer by Jaap Kreijkamp · Nov 25, 2009 at 04:36 AM
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;
}
}
}
}
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. $$anonymous$$y 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?
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.
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!!!
Answer by TedB · Nov 28, 2009 at 04:48 AM
// 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);
}
}
Your answer
Follow this Question
Related Questions
Animating (simple rotation) armature by script 1 Answer
Problem with animation: they always start at the same rotation!! 1 Answer
Animate a cube rotation with script only 3 Answers
Using Quaternions and C# script to animate a mesh 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers