- Home /
Rotating a gameobject using integers
Hi all. So I'm very confused on why this isn't working. I have created some integers which I want to use to rotate a cube in my game. The three integers called 'rotx', 'roty', and 'rotz' are meant to be used to tell the object what the rotation should be. I have tried using the lines of code 'this.transform.eulerAngles = new Vector3(rotx, roty, rotz);' and 'this.transform.rotation = Quaternion.Euler(rotx, roty, rotz);', but neither work the way I want them to. What I want to happen is for example if the value of rotx was 90 and the other two were 0, then the gameobject should rotate to (90, 0, 0). I have even made the integers public, and I can indeed see when in play mode that the integers do equal what they are meant to, but the rotation coordinates of the object don't. What's even weirder is that the y coordinate even goes to -180 sometimes, and 'roty' never ever changes from 0 in my script.
Here's my script incase I've made any error somewhere else in my script but I can't spot any errors. Thanks.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerMovement : MonoBehaviour {
public Camera cameraScript;
private float pos;
public float rotx;
public float roty;
public float rotz;
public float desrotx;
public float desrotz;
public static bool playerMoved;
public static bool canMove;
public static int moves;
public Text movesText;
private void Start()
{
moves = 0;
playerMoved = false;
canMove = true;
pos = 0;
rotx = 0;
roty = 0;
rotz = 0;
desrotx = 0;
desrotz = 0;
}
private void Update()
{
this.transform.rotation = Quaternion.Euler(rotx, roty, rotz);
//this.transform.eulerAngles = new Vector3(rotx, roty, rotz);
if (movesText != null)
{
movesText.text = moves.ToString();
}
}
public void LeftButton()
{
if (GameMaster.endTheLevel == false && canMove == true)
{
moves = moves + 1;
playerMoved = true;
desrotx = rotx - 90;
StartCoroutine(MoveLeft());
StartCoroutine(RotateLeft());
}
}
public void RightButton()
{
if (GameMaster.endTheLevel == false && canMove == true)
{
moves = moves + 1;
playerMoved = true;
desrotx = rotx + 90;
StartCoroutine(MoveRight());
StartCoroutine(RotateRight());
}
}
public void UpButton()
{
if (GameMaster.endTheLevel == false && canMove == true)
{
moves = moves + 1;
playerMoved = true;
desrotz = rotz + 90;
StartCoroutine(MoveUp());
StartCoroutine(RotateUp());
}
}
public void DownButton()
{
if (GameMaster.endTheLevel == false && canMove == true)
{
moves = moves + 1;
playerMoved = true;
desrotz = rotz - 90;
StartCoroutine(MoveDown());
StartCoroutine(RotateDown());
}
}
IEnumerator MoveLeft()
{
Camera.enableArrows = false;
cameraScript.greenArrow.interactable = false;
cameraScript.blueArrow.interactable = false;
cameraScript.yellowArrow.interactable = false;
cameraScript.redArrow.interactable = false;
pos = this.transform.position.z - 0.4f;
while (this.transform.position.z > pos)
{
this.transform.position = this.transform.position + new Vector3(0f, 0f, -0.06f);
yield return new WaitForSeconds(0.005f);
}
this.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, pos);
pos = 0;
yield return new WaitForSeconds(0.05f);
Camera.enableArrows = true;
cameraScript.greenArrow.interactable = true;
cameraScript.blueArrow.interactable = true;
cameraScript.yellowArrow.interactable = true;
cameraScript.redArrow.interactable = true;
}
IEnumerator RotateLeft()
{
while(rotx > desrotx)
{
rotx = rotx - 8;
yield return new WaitForSeconds(0.005f);
}
rotx = desrotx;
if (desrotx <= -360)
{
desrotx = 0;
rotx = 0;
}
}
IEnumerator MoveUp()
{
Camera.enableArrows = false;
cameraScript.greenArrow.interactable = false;
cameraScript.blueArrow.interactable = false;
cameraScript.yellowArrow.interactable = false;
cameraScript.redArrow.interactable = false;
pos = this.transform.position.x - 0.4f;
while (this.transform.position.x > pos)
{
this.transform.position = this.transform.position + new Vector3(-0.06f, 0f, 0f);
yield return new WaitForSeconds(0.005f);
}
this.transform.position = new Vector3(pos, this.transform.position.y, this.transform.position.z);
pos = 0;
yield return new WaitForSeconds(0.05f);
Camera.enableArrows = true;
cameraScript.greenArrow.interactable = true;
cameraScript.blueArrow.interactable = true;
cameraScript.yellowArrow.interactable = true;
cameraScript.redArrow.interactable = true;
}
IEnumerator RotateUp()
{
while (rotz < desrotz)
{
rotz = rotz + 8;
yield return new WaitForSeconds(0.005f);
}
rotz = desrotz;
if (desrotz >= 360)
{
desrotz = 0;
rotz = 0;
}
}
IEnumerator MoveRight()
{
Camera.enableArrows = false;
cameraScript.greenArrow.interactable = false;
cameraScript.blueArrow.interactable = false;
cameraScript.yellowArrow.interactable = false;
cameraScript.redArrow.interactable = false;
pos = this.transform.position.z + 0.4f;
while (this.transform.position.z < pos)
{
this.transform.position = this.transform.position + new Vector3(0f, 0f, 0.06f);
yield return new WaitForSeconds(0.005f);
}
this.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, pos);
pos = 0;
yield return new WaitForSeconds(0.05f);
Camera.enableArrows = true;
cameraScript.greenArrow.interactable = true;
cameraScript.blueArrow.interactable = true;
cameraScript.yellowArrow.interactable = true;
cameraScript.redArrow.interactable = true;
}
IEnumerator RotateRight()
{
while (rotx < desrotx)
{
rotx = rotx + 8;
yield return new WaitForSeconds(0.005f);
}
rotx = desrotx;
if (desrotx >= 360)
{
desrotx = 0;
rotx = 0;
}
}
IEnumerator MoveDown()
{
Camera.enableArrows = false;
cameraScript.greenArrow.interactable = false;
cameraScript.blueArrow.interactable = false;
cameraScript.yellowArrow.interactable = false;
cameraScript.redArrow.interactable = false;
pos = this.transform.position.x + 0.4f;
while (this.transform.position.x < pos)
{
this.transform.position = this.transform.position + new Vector3(0.06f, 0f, 0f);
yield return new WaitForSeconds(0.005f);
}
this.transform.position = new Vector3(pos, this.transform.position.y, this.transform.position.z);
pos = 0;
yield return new WaitForSeconds(0.05f);
Camera.enableArrows = true;
cameraScript.greenArrow.interactable = true;
cameraScript.blueArrow.interactable = true;
cameraScript.yellowArrow.interactable = true;
cameraScript.redArrow.interactable = true;
}
IEnumerator RotateDown()
{
rotz = desrotz + 90;
while (rotz > desrotz)
{
rotz = rotz - 8;
yield return new WaitForSeconds(0.005f);
}
rotz = desrotz;
if (desrotz <= -360)
{
desrotz = 0;
rotz = 0;
}
}
}
Answer by narqs · Jun 29, 2018 at 03:09 PM
Hello @HyperGamer87 the reason you're experiencing this, is due to the fact that your cube is rotating around it's local axis, that plus the fact that you're rotating your local axis, will give you some weird rotations. this can be solved by using the Quaternion.AngleAxis()
I have already created a class from scratch and changed a bunch of things. It's already testet, and should work. Keep in mind that the z+ is forward now.
public class CubeRotation : MonoBehaviour
{
#region Fields
[Header("Camera")]
public Camera cameraScript;
[Header("Movement Properties")]
public float movementSpeed = 0.12f; // Movement speed
public float movementAmount = 0.4f;
public Text movesText;
public Vector3 pos; // changed to a vector3 to determain the move direction
public static int moves;
public static bool canMove;
public static bool playerMoved;
private Vector3 currentPos; // our current position
[Header("Rotation Properties")]
public float rotationSpeed = 0.12f; // Rotation speed
public float angle = 90; // this is how much it should be rotated
// we we'll be using it for rotating
private Vector3 worldAxis = Vector3.zero;
private Quaternion currentRotation; // our current rotation
private float startTime; // start time for lerping movement and rotation
private bool isRotating;
private bool isMoving;
#endregion
#region Start & Update
void Start()
{
moves = 0;
canMove = true;
playerMoved = false;
}
void Update()
{
if (movesText != null)
{
movesText.text = moves.ToString();
}
// These are for lerping, and is the correct way to lerp
// timeSinceStarted is equal to Time.time - our start time, which is set in the buttons functions
float timeSinceStarted = Time.time - startTime;
// percentageComplete is devided by our rotationSpeed, and gives us a number between 0 and 1
// 0 = just started, 1 = finished rotating
float percentageComplete = timeSinceStarted / rotationSpeed;
// This is what fixed the weird rotation
// Here we use Quaternion.AngleAxis to rotatate angle amount around axis.
// We then multiply it by our currentRotation to rotate around the world axis
// Multiplying with Quaternions are very important as they wont have the same end result.
// currentRotation * Quaternion.AngleAxis() = local axis
// Quaternion.AngleAxis() * currentRotation = world axis
// angle just tells us to rotate 90 degrees each time
// you could change it in the inspector
Quaternion newRotation = Quaternion.AngleAxis(this.angle, worldAxis) * currentRotation;
// if our new rotation is not = Vector3.zero and currentRotation is not = Vector3.zero
// then we could rotate
// lerping will throw an error as it can't calculate Quaternions that are zeroed out.
// and will therefore throw an error
if (newRotation.eulerAngles != Vector3.zero || currentRotation.eulerAngles != Vector3.zero)
{
// here we're asigning our lerped rotation to our local Quaternion variable
Quaternion lerping = Quaternion.Lerp(this.currentRotation, newRotation, percentageComplete);
// and here we just assign it to our transform.rotation
transform.rotation = lerping;
// if isRotating is true and the tranform.rotation has finished rotating
// then set isRotating back to false, so that we can rotate again
if (isRotating && transform.rotation == newRotation)
isRotating = false;
}
}
#endregion
#region Buttons
public void ButtonUp()
{
if (GameMaster.endTheLevel == false && !isRotating && !isMoving && canMove)
{
// here we set the start time
startTime = Time.time;
// for asigning movement, forward when moving
// Use the inspector to change the movement amount
// which is how much you want the cube to move, in your case it was 0.4
AssignMovement(Vector3.forward, movementAmount);
// right when rotating, because we rotate around our x axis when going forward
// this asigns the direction we want to rotate Vector3.right = (1,0,0)
worldAxis = Vector3.right;
// We set our current rotation variable to that of the object
currentRotation = this.transform.rotation;
// here we set isRotating to true, to make sure that the cube can't be rotated while rotating.
isRotating = true;
}
}
public void ButtonDown()
{
if (GameMaster.endTheLevel == false && !isRotating && !isMoving && canMove)
{
startTime = Time.time;
AssignMovement(Vector3.back, -movementAmount);
worldAxis = Vector3.left;
currentRotation = this.transform.rotation;
isRotating = true;
}
}
public void ButtonLeft()
{
if (GameMaster.endTheLevel == false && !isRotating && !isMoving && canMove)
{
startTime = Time.time;
AssignMovement(Vector3.left, -movementAmount);
worldAxis = Vector3.forward;
currentRotation = this.transform.rotation;
isRotating = true;
}
}
public void ButtonRight()
{
if (GameMaster.endTheLevel == false && !isRotating && !isMoving && canMove)
{
startTime = Time.time;
AssignMovement(Vector3.right, movementAmount);
worldAxis = Vector3.back;
currentRotation = this.transform.rotation;
isRotating = true;
}
}
#endregion
#region Movement
// here we determain our move direction and new move position
private void AssignMovement(Vector3 moveDir, float moveAmount)
{
// set the currentPos variable to our current position
currentPos = transform.position;
// setting is moving to true
isMoving = true;
// here we determain our move direction
// moveDir.x > 0 = right, moveDir.x < 0 = left
if (moveDir.x > 0 || moveDir.x < 0)
{
// set our pos.x to our moveAmount
pos.x = moveAmount;
}
// same as above, but here we check if we're moving forward or backwards
// moveDir.z > 0 = forward, moveDir.z < 0 = backwards
if (moveDir.z > 0 || moveDir.z < 0)
{
// set our pos.z to our moveAmount
pos.z = moveAmount;
}
// Here we invoke our Coroutine, and pass a Vecor3
// which is our new target position
// pos could be (0,0,0.4f) + currentPos = new position
StartCoroutine(Move(pos + currentPos));
}
// Here we move our cube
private IEnumerator Move(Vector3 newPos)
{
Camera.enableArrows = false;
cameraScript.greenArrow.interactable = false;
cameraScript.blueArrow.interactable = false;
cameraScript.yellowArrow.interactable = false;
cameraScript.redArrow.interactable = false;
// while our current position is no equal to our new position
while (this.transform.position != newPos)
{
// These are for lerping, and is the correct way to lerp
// timeSineStarted is equal to Time.time - our start time, which is set in the buttons functions
float timeSinceStarted = Time.time - startTime;
// percentageComplete is devided by our movementSpeed, and gives us a number between 0 and 1
// 0 = just started, 1 = finished moving
float percentageComplete = timeSinceStarted / movementSpeed;
// Here we lerp the position, to give a smother movement
// it's important that the currentPos and newPos stays the same throughout the lerping
this.transform.position = Vector3.Lerp(currentPos, newPos, percentageComplete);
yield return null;
}
// zero out pos, for the next movement
pos = Vector3.zero;
moves = moves + 1;
playerMoved = true;
// isMoving is set to false
isMoving = false;
Camera.enableArrows = true;
cameraScript.greenArrow.interactable = true;
cameraScript.blueArrow.interactable = true;
cameraScript.yellowArrow.interactable = true;
cameraScript.redArrow.interactable = true;
}
#endregion
}
i have commented most of the things. naming conventions might not be the best :)
That's just great. Thanks so much, it finally works! It's a little annoying that it only goes up to 180 though. $$anonymous$$y cube has a different colour on each of the six sides, meaning that when it gets to 180, the colour that's meant to be on the bottom appears on the top, making the animation look a little weird :/. Despite that it rotates the way I wanted it to now, so thanks for that!
Hello again @HyperGamer87 I guess you could change the if statements to 360, then ins$$anonymous$$d of having 3 floats rotx, roty, rotz, you could have a vector3 called rot.
this way you could assign to it in your IEnumerators like
rot.z = rot.z + 8;
and then assign it in the update function like this
this.transform.localEulerAngles = rot;
and to ensure that your rot does not exceed the 360 degrees, you could clamp it in the IEnumerator like this
while (rot.z < desrotz)
{
rot.z = rot.z + 8;
desrotz = $$anonymous$$athf.Clamp(desrotz, -360, 360);
yield return new WaitForSeconds(0.005f);
}
Sorry for the late reply @narqs and thanks for trying to help again! I've done what you said but it doesn't seem to be working. The cube rotates once and then it doesn't rotate again. I can see in the inspector that desrotx and desrotz only equals 0 or 90 and never anything else, so I guess this will be the reason for the rotation not working.
Forgot to mention that the EulerAngles, as shown in the inspector, will not be showing the same value as the rot variable, they should however represent the same rotation :)
Answer by Ellie97 · Jun 29, 2018 at 11:23 AM
I believe if you change transform.eulerAngles to transform.rotation.eulerAngles that will fix it i.e. this.transform.rotation.eulerAngles = new Vector3(rotx, roty, rotz);
That does not work sadly.
The left side of the argument gives an error stating "Cannot modify the return value of 'Transform.rotation' because it is not a variable".
Thanks for trying anyway!
@HyperGamer87 You can't do:
this.transform.rotation.eulerAngles = new Vector3(rotx, roty, rotz);
It should be something like:
transform.eulerAngles = new Vector3(rotx, roty, rotz);
I believe putting the this
keyword is useless also.
Btw, rotx, roty, and rotz are not 'integers', they are decimals, or more commonly known in C# as 'floats'. An integer is a whole number, a float can be decimal too. Integer variables are declared as int
Hey, thanks for the answer. I know what the difference between an int and float is, I just got mixed up with the data types :D. Removing the 'this' doesn't seem to make any difference though unfortunatly.
You can see with this image what the values of rotx, roty, and rotz are currently at, and these should equal the objects rotation x, y, and z values. They don't equal though. rotx = 180, but the objects x rotation is equal to 0, roty = 0 when the objects y rotation is equal to -180, and then rotz = -270 when the objects z rotation is equal to -90.
This is all so confusing!
Thanks for your answer anway!
Answer by madks13 · Jun 29, 2018 at 02:33 PM
Why not use the Rotate method instead?
Tried the Rotate method but that just makes the cube spin out of control for some reason.