Previously, I published “Script to roll a cube” and the script for rectangular parallelepiped were requested. So I made it.

The script is the following

```using UnityEngine;
using System.Collections;

public class moveRect : MonoBehaviour {

public float rotationPeriod = 0.3f;		// period to move the next position
Vector3 scale;							// the size of rectangle parallelepiped

bool isRotate = false;					// flag for under rotation
float directionX = 0;					// flag for rotation direction
float directionZ = 0;					// flag for rotation direction

float startAngleRad = 0;				// angle from the horizontal plane to the center before rotation
Vector3 startPos;						// position before rotation
float rotationTime = 0;					// past time since rotation start
Quaternion fromRotation;				// quaternion before rotation
Quaternion toRotation;					// quaternion after rotation

// Use this for initialization
void Start () {

// get the size of rectangle parallelepiped
scale = transform.lossyScale;
//Debug.Log ("[x, y, z] = [" + scale.x + ", " + scale.y + ", " + scale.z + "]");

}

// Update is called once per frame
void Update () {

float x = 0;
float y = 0;

// get key input
x = Input.GetAxisRaw ("Horizontal");
if (x == 0) {
y = Input.GetAxisRaw ("Vertical");
}

// rotate rectangle parallelepiped if key was input and rectangle parallelepiped was not rotating
if ((x != 0 || y != 0) && !isRotate) {
directionX = y;																// set rotation direction (x or y is 0)
directionZ = x;																//set rotation direction (x or y is 0)
startPos = transform.position;												// keep the coordinate before rotation
fromRotation = transform.rotation;											// keep the quaternion before rotation
transform.Rotate (directionZ * 90, 0, directionX * 90, Space.World);		// rotate to 90 deg.
toRotation = transform.rotation;											// keep quaternion after rotation
transform.rotation = fromRotation;											// get the rotation of rectangle parallelepiped back to that of before rotation （shallow copy of transform is available?）
rotationTime = 0;															// set the past time of rotation to 0
isRotate = true;															// set flag for during rotation
}
}

void FixedUpdate() {

if (isRotate) {

rotationTime += Time.fixedDeltaTime;									// add past time of rotation
float ratio = Mathf.Lerp(0, 1, rotationTime / rotationPeriod);			// the ration of past time per all time to rotation

// move
float thetaRad = Mathf.Lerp(0, Mathf.PI / 2f, ratio);					// get radian of rotation angle
float distanceX = -directionX * radius * (Mathf.Cos (startAngleRad) - Mathf.Cos (startAngleRad + thetaRad));		// distance of X. "-" is for the moving direction.
transform.position = new Vector3(startPos.x + distanceX, startPos.y + distanceY, startPos.z + distanceZ);			// set the present position

// rotate
transform.rotation = Quaternion.Lerp(fromRotation, toRotation, ratio);		// set the present angle using Quaternion.Lerp (what a convenient function!!)

// initialize all parameter after moving and rotation
if (ratio == 1) {
isRotate = false;
directionX = 0;
directionZ = 0;
rotationTime = 0;
}
}
}

Vector3 dirVec = new Vector3(0, 0, 0);			// vector of moving direction
Vector3 nomVec = Vector3.up;					// (0,1,0)

// change the moving direction to vector
if (directionX != 0) {							// move to X direction
dirVec = Vector3.right;						// (1,0,0)
} else if (directionZ != 0) {					// move to Z direction
dirVec = Vector3.forward;					// (0,0,1)
}

// calculate radius and startAngle with the inner product between the moving direction and the face direction of object.
if (Mathf.Abs (Vector3.Dot (transform.right, dirVec)) > 0.99) {						// moving direction is the same as x of object
if (Mathf.Abs (Vector3.Dot (transform.up, nomVec)) > 0.99) {					// y axis of global is the same as y of object
startAngleRad = Mathf.Atan2(scale.y, scale.x);								// the angle from horizontal plane to the center before rotation
} else if (Mathf.Abs (Vector3.Dot (transform.forward, nomVec)) > 0.99) {		// y axis of global is the same as z of object
}

} else if (Mathf.Abs (Vector3.Dot (transform.up, dirVec)) > 0.99) {					// moving direction is the same as y of object
if (Mathf.Abs (Vector3.Dot (transform.right, nomVec)) > 0.99) {					// y of global is the same as x of object
} else if (Mathf.Abs (Vector3.Dot (transform.forward, nomVec)) > 0.99) {		// y axis of global is the same as z of object
}
} else if (Mathf.Abs (Vector3.Dot (transform.forward, dirVec)) > 0.99) {			// moving direction is the same as z of object
if (Mathf.Abs (Vector3.Dot (transform.right, nomVec)) > 0.99) {					// y of global is the same as x of object
} else if (Mathf.Abs (Vector3.Dot (transform.up, nomVec)) > 0.99) {				// y axis of global is the same as y of object
}
}
}
}```

Make Cube, set the scale of “Transform”, and add the above script to the object. That it!

This script is just an impromptu. I think there is better script.

【Android】Colorful Dice -カラフルでポップなサイコロパズル-

Categories: Memo #### Hamza Younas` · 2018-08-07 at 19:06

How to get movement on button by right, left up and down arrow for mobile controls #### PiroMayo · 2018-08-07 at 22:24

It depends on your design concept; how do you want to control the cube. So it is difficult to answer.
You can find the tutorial about mobile and touch on unity in the following page.
https://unity3d.com/learn/tutorials/s/mobile-touch
If you want to use virtual controller, you can find it in the unity asset store and github.

In my app “Colorful Dice“, I control the cube using the following script.

```if (Input.touchCount == 1 && manager.GetComponent ().isPlaying) {
Touch touch = Input.GetTouch (0);

if (touch.phase == TouchPhase.Moved) {
float x = touch.deltaPosition.x;
float y = touch.deltaPosition.y;

if (Mathf.Abs (x) < reactionThreshold) {　x = 0;　}
if (Mathf.Abs (y) < reactionThreshold) {　y = 0;　}

if (Mathf.Abs(x) > Mathf.Abs(y) && !isRotate) {
if ((x > 0 && transform.position.z + error < moveLimitZmax) || (x < 0 && transform.position.z - error > moveLimitZmin)) {
directionZ = x;
startPos = transform.position;
fromRotation = transform.rotation;
transform.Rotate (NormalizeFloat (directionZ) * 90, 0, NormalizeFloat (directionX) * 90, Space.World);
toRotation = transform.rotation;
transform.rotation = fromRotation;
rotationTime = 0;
isRotate = true;
}
}

if (Mathf.Abs(y) > Mathf.Abs(x) && !isRotate) {
if ((y > 0 && transform.position.x - error > moveLimitXmin) || (y < 0 && transform.position.x + error < moveLimitXmax)) {
directionX = y;
startPos = transform.position;
fromRotation = transform.rotation;
transform.Rotate (NormalizeFloat (directionZ) * 90, 0, NormalizeFloat (directionX) * 90, Space.World);
toRotation = transform.rotation;
transform.rotation = fromRotation;
rotationTime = 0;
isRotate = true;
}
}
}
}
```

This site uses Akismet to reduce spam. Learn how your comment data is processed.