# Turn X° in Y sec. Tile Walking.

I spent more than 5 solid hours trying to find a solution to this one and browsing Unity Script Reference. Please help me or i will go crazy.

I need a object to turn left or right when i press A or D, it have to turn turnAmount of degrees and the turning speed should be turnSpeed degrees/second.

that is how far i’ve got myself. (yeah yeah im just a beginner)

``````var turnSpeed = 1;
var turnAmount = 45;

private var turnInProgress = 0;

function Update() {
if (Input.GetButtonDown ("Horizontal")) {
turnInProgress = 1;
}
if (turnInProgress == 1) {
for (var turnDegree = 1; turnDegree <= turnAmount; turnDegree++) {
transform.Rotate(Vector3 (0,1,0) * Time.deltaTime);
if (turnDegree == turnAmount) {
turnInProgress = 0;
}
}
}
}
``````

I think this should theoretically work for you, but I’m not getting a proper value out of the LerpAngle method, so the timing isn’t easy to deal with. I’m going to go download Unity 2.5 now, to see if this is a bug that has been fixed. It’s very possible that I’m just missing something in my own code, however.

Let me know if this is the kind of thing you’re looking for.

``````var turnDuration = 1.0;
var turnAmount = 45.0;

private var triggerTime = 0.0;
private var turnIncrement = 0;

function Update ()
{
if (Input.GetButtonDown("Horizontal"))
{
triggerTime = Time.time;
turnIncrement += Mathf.Sign(Input.GetAxis ("Horizontal"));
}

var turnProgress = (Time.time - triggerTime) / turnDuration;
var angle = Mathf.LerpAngle(transform.localEulerAngles.y, (turnIncrement * turnAmount), turnProgress);
transform.eulerAngles = Vector3(0, angle, 0);
}
``````

Thank you. this worked great. Now i just need to understand what all this functions do.

i noticed that angle the object turns is not 45 but something like 45.000001 no big deal, it’s not even noticable.

Sorry, what I said above ended up being my fault, not Unity’s fault. I had moved transform.localEulerAngles.y out of a separate function, and back into Update, to make it easier for you, but I forgot to make sure it wasn’t updated every frame.

This code is a lot more predictable, and I put comments in to help you learn it:

``````var turnDuration = 1;	//length of time for turn to occur
var turnAmount = 45;	//rotation, in degrees, for one turn

private var turnInProgress = false;
private var triggerTime;	//the moment in time that the turn is triggered
private var triggerDegree;	//the rotation about the Y axis of the object when the turn is triggered
private var targetDegree;	//the rotation about the Y axis of the object upon completion of the turn

function Update ()
{
if (Input.GetButtonDown("Horizontal"))
{
if (turnInProgress == false)
{
turnInProgress = true;
triggerTime = Time.time;
triggerDegree = transform.localEulerAngles.y;

//the multiplication is used for direction of rotation
targetDegree = triggerDegree + turnAmount * Mathf.Sign(Input.GetAxis("Horizontal"));
}
}

if (turnInProgress)
{
//turnProgress gives a 0 to 1 value over the duration of the turn,
//which is needed for the last argument of Mathf.LerpAngle
var turnProgress = (Time.time - triggerTime) / turnDuration;

//lightly modified from the LerpAngle scripting reference entry
var angle = Mathf.LerpAngle(triggerDegree, targetDegree, turnProgress);
transform.localEulerAngles = Vector3(0, angle, 0);

if (turnProgress >= 1) turnInProgress = false;
}
}
``````

This kind of code seems appropriate for rotation of mechanical objects, like turrets, while the previous code, if cleaned up, would be geared more towards organic motion. Let me know what you’re going for, if you want any more help.

Thank you for the code and especially for the comments.

I am doing a program that supposed to help me make dungeons and fight battles in D&D. (pen-and-paper roleplay game) I make a dungeon, place characters adn then i can have all this stored digitally istead of having real minityres on the table (3d is more custom too).

This particular script is supposed to be character controller script, because of the whole dungeon made of tiles character should rotate only certain amount per button press and move certain amount forward.

I can see you already got some help, but I wrote this code before I saw the other replies, so I might as well post it now.

``````var turnSpeed = 1;
var turnAmount = 45;
private var turnDegree;
private var turnTarget;

function Start() {
turnDegree = transform.eulerAngles.y;
turnTarget = turnDegree;
}

function Update() {
if (Input.GetAxis ("Horizontal") < -0.1  turnDegree <= turnTarget) {
turnTarget -= turnAmount;
}
if (Input.GetAxis ("Horizontal") >  0.1  turnDegree >= turnTarget) {
turnTarget += turnAmount;
}
var remaining = Mathf.Abs(turnTarget - turnDegree);
if (turnTarget > turnDegree) turnDegree += Mathf.Min(turnSpeed, remaining);
if (turnTarget < turnDegree) turnDegree -= Mathf.Min(turnSpeed, remaining);
transform.eulerAngles = new Vector3(0, turnDegree, 0);
}
``````

Rune

The whole point of this was to LEARN how to do it and not to get the script…thanks both of you.

RuneVision: i think i understand your script but can you explain to me why does the object turns slowly istead of just changing the angle? i don’t get it.