How to make a Cube Roll in JS in direction of camera?

Hello,

i’m very new to javascript and im trying to make a cube roll. I tried some stuff with animations but really like to do it in JS. The cube is rolling but its really going out of control. Eventually i want to make it roll in the direction my camera is aiming.

I’ve been checking out some other qeustions but didn’t rlly help me out.

private var rollSpeed : float = 8;

function Update () {
if (Input.GetMouseButton(2)) Screen.lockCursor = true;

if (Input.GetKey("right"))
{
rigidbody.AddTorque(Vector3.back * rollSpeed);
}

if (Input.GetKey("left"))
{
rigidbody.AddTorque(Vector3.forward * rollSpeed);
}

if (Input.GetKey("up"))
{
rigidbody.AddTorque(Vector3.right * rollSpeed);
}

if (Input.GetKey("down"))
{
rigidbody.AddTorque(Vector3.left * rollSpeed);
}

}

Hope someone can tell me what to add or change.

I answered a question some time ago that did about the same thing: a cube that flipped in the direction defined by the arrow keys. The idea was to emulate the behaviour of the game Edge.

If you just want to reproduce the flipping walk style, the script below can do the job. Just create a cube and attach this script to it. If you want the flop sound, add an AudioSource and assign an appropriate sound to it (footstep4 from the FPS Tutorial is fine).

When some movement key is pressed, the routine Flop defines around which point and axis the block will rotate, then does a 90 degrees rotation during the time defined by speed. To avoid accumulated errors, the routine AlignBlock is called prior moving. This routine forces orientation alignment to the axes by rounding the eulerAngles to multiples of 90 degrees. It also forces the position alignment to multiples of the block size (defined by size) thus the block will always walk in a grid with size spacing.

If the block has no rigidbody, it will be a really nice guy, flopping precisely over the grid positions - but will not be constrained by collisions nor be affected by gravity. If you add a rigidbody, it will collide and fall, but the flopping action will become somewhat weird (it sometimes stops for a while before ending the 90 degrees rotation). Anyway, the AlignBlock routine will always bring it back to the right position before moving.

NOTE: if a rigidbody is added, AlignBlock ignores Y to not interfere with gravity.

var speed: float = 2.5; // flops per second
var size: float = 1; // block size

var flopping = false;

function Update(){

	var move = Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
	if (move.magnitude > 0.2) Flop(move);
}

function Flop(movDir: Vector2){

	var pivot: Vector3;
	var dir: Vector3;
	
	if (flopping) return; // ignore other commands while flopping
	flopping = true; // signals it's flopping
	if (movDir.y > 0){ // move forward?
		dir = Vector3.forward; // will flop forward
		pivot = Vector3(0,-1,1); // defines point around which rotate
	}
	else
	if (movDir.y < 0){
		dir = -Vector3.forward;
		pivot = Vector3(0,-1,-1);
	}
	else
	if (movDir.x < 0){
		dir = -Vector3.right;
		pivot = Vector3(-1,-1,0);
	}
	else
	if (movDir.x > 0){
		dir = Vector3.right;
		pivot = Vector3(1,-1,0);
	}
	AlignBlock(); // aligns block to grid before flopping
	// calculates the point around which the block will flop
	pivot = transform.position + (pivot * size / 2);
	var org = transform.position - pivot;
	var dest = (transform.position + dir * size) - pivot;
	var rot0 = transform.rotation;
	var rot1 = Quaternion.FromToRotation(org, dest) * rot0; 
	var a: float = 0;
	while (a < 1){
		var dt = Time.deltaTime * speed;
		a += dt;
		transform.position = Vector3.Slerp(org, dest, a) + pivot;
		transform.rotation = Quaternion.Lerp(rot0, rot1, a);
		yield;
	}
	if (audio) audio.Play(); // makes the flop sound 
	flopping = false;
}

private function AlignBlock(){

	var angles = transform.eulerAngles;
	// forces euler angles to be multiple of 90
	angles.x = 90 * Mathf.RoundToInt(angles.x / 90);
	angles.y = 90 * Mathf.RoundToInt(angles.y / 90);
	angles.z = 90 * Mathf.RoundToInt(angles.z / 90);
	transform.eulerAngles = angles;
	var pos = transform.position;
	// forces x and z to be in a grid 
	pos.x = size * Mathf.RoundToInt(pos.x / size);
	pos.z = size * Mathf.RoundToInt(pos.z / size);
	if (!rigidbody) pos.y = size * Mathf.RoundToInt(pos.y / size);
	transform.position = pos;
}