- Home /
Tipping a cube over
My problem seems to be pretty easy but it looks like it is impossible to slove because you can't set a pivot of a 3D object in unity.
I have a tower in my game that needs to tip over and then stand up again. This has to work even if the object is resized and multiple times in a row. Is there any simple way to do this?
Here is a picture of how it should look like:
Answer by robertbu · May 19, 2014 at 08:00 AM
Here is a bit of sample code. Place it on a block and use the arrow keys:
#pragma strict
private var parent : Transform;
private var dirs = [Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back];
var speed = 90.0;
function Start() {
parent = new GameObject().transform;
}
function Update() {
if (Input.GetKeyDown(KeyCode.LeftArrow)) {
FlopTheBlock(Vector3.left);
}
else if (Input.GetKeyDown(KeyCode.RightArrow)) {
FlopTheBlock(Vector3.right);
}
else if (Input.GetKeyDown(KeyCode.UpArrow)) {
FlopTheBlock(Vector3.forward);
}
else if (Input.GetKeyDown(KeyCode.DownArrow)) {
FlopTheBlock(Vector3.back);
}
}
function FlopTheBlock(direction : Vector3) {
var down = WhatsDown();
var dir = transform.InverseTransformDirection(direction);
var pos = dir * 0.5 + down * 0.5;
pos = transform.TransformPoint(pos);
var axis = Vector3.Cross(Vector3.down, direction);
transform.parent = null;
parent.rotation = Quaternion.identity;
parent.position = pos;
transform.parent = parent;
var qTo = Quaternion.AngleAxis(-90.0, axis);
while (parent.rotation != qTo) {
parent.rotation = Quaternion.RotateTowards(parent.rotation, qTo, speed * Time.deltaTime);
yield;
}
}
function WhatsDown() : Vector3 {
for (var i = 0; i < dirs.Length; i++) {
if (Vector3.Dot(transform.TransformDirection(dirs[i]), Vector3.down) > 0.9)
return dirs[i];
}
}
Note to solve this problem, there are a couple of sub-problems that need to be solved. First the rotation around an axis not through the pivot of the object. This code places an empty game object on an edge and make the visible object a child. So rotating the parent rotates the child around an edge.
To find the right edge, the code first finds which side of the cube is facing down. Then it translates the direction the cube is to be pushed into local coordinates. Combining the two gives a local coordinate of the edge point. Converting to world coordinates handles the scaling.
Thank you so much! This helped me a lot! I almost gave up. It works great.
Don't forget to mark the answer as correct by clicking the check mark
Answer by Sprakle · May 18, 2014 at 04:49 PM
Two things come to mind:
If you want to use the physics engine, apply a force at the top of the object.
If you want consistent deterministic movement, rotate around the base.
Your answer
Follow this Question
Related Questions
How do I make something happen at collider 1 Answer
Internal collisions 1 Answer
Access other game object BoxCollider 1 Answer
Multiple Colliders Trigger problem 2 Answers
Box collider on a default plane 0 Answers