- Home /

# 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.

**Answer** by aldonaletto
·
Apr 15, 2012 at 08:15 PM

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;
```

}

Thanks for the scrip you rlly helped me out. but i have one more question im useing the mouse orbit script and like to change the forward direction to the direction the camera is aiming.

i hope its possible

I think you could get the direction camera->cube and fake a *move* vector that would make the cube move in the camera forward direction. But there's a problem: the cube will never stop moving, because there will always exist a forward direction. To solve this, define a button or key - the "walk" button.

I assumed key W is the walk button, and modified Update to work this way - just replace the original Update with this one:

function Update(){ if (Input.GetKey("w")){ // if W is pressed... // get the dir camera->cube: var dir = transform.position - Camera.main.transform.position; // ignore the less significant horizontal direction: if (Mathf.Abs(dir.z) >= Mathf.Abs(dir.x)){ dir.x = 0; } else { dir.z = 0; } Flop(Vector2(dir.x, dir.z)); } } ...

I'v tried to make it move it backwards if this is poossible by changing the dir.x and dir.z but i couldn't work it out.

I alsoe want to make it move left and right but i might figure that out if i know how to move backwards

It should go in the direction the camera is looking at - to move backwards, you should rotate the camera with the mouse to point the backward direction (the same applies to left and right).

If you want to control the cube with the keyboard, just use the original code of this answer - its Update function reads "Horizontal" and "Vertical" axes to control cube movement.

I've posted an answer to an even older question here. I've just took a look at my code and it's very simple to make it work with different sizes as long as the cube is aligned with the world because the easiest way to determine it's size is using renderer.bounds.size ;)

Btw: mine does even work with a quader with the size 1 x 2 x 3 ;)

Here's the modified and even simplified version of my script:

```
private var rotator : Transform;
var speed = 1.0;
var rotating = false;
function RotateCube(refPoint : Vector3, rotationAxis : Vector3)
{
var size = renderer.bounds.extents;
refPoint = Vector3.Scale(refPoint - Vector3.up,size);
rotator.localRotation = Quaternion.identity;
rotator.position = transform.position + refPoint;
transform.parent = rotator;
var angle : float = 0;
while(angle < 90.0)
{
angle += Time.deltaTime*90.0*speed;
rotator.rotation = Quaternion.AngleAxis(Mathf.Min(angle,90.0),rotationAxis);
yield;
}
audio.PlayOneShot(audio.clip);
transform.parent = null;
rotating = false;
}
function Start()
{
rotator = (new GameObject("Rotator")).transform;
}
function Update ()
{
if (!rotating)
{
if (Input.GetKey(KeyCode.D))
{
rotating = true;
RotateCube(Vector3.right,-Vector3.forward);
}
else if (Input.GetKey(KeyCode.A))
{
rotating = true;
RotateCube(-Vector3.right,Vector3.forward);
}
else if (Input.GetKey(KeyCode.W))
{
rotating = true;
RotateCube(Vector3.forward,Vector3.right);
}
else if (Input.GetKey(KeyCode.S))
{
rotating = true;
RotateCube(-Vector3.forward,-Vector3.right);
}
}
}
```

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Odd 2D Torque behavior 0 Answers

Detect the up axis when rolling a cube? 2 Answers

AddTorque application is too slow 1 Answer

moving a cube 2 Answers