How to make a character turn on key in Unity remake of Frogger

Hey all, novice C# coder here. I am trying to make it so that the player can turn when a key is pressed, towards their facing direction. I already have it so the player can move, now I just want the character to turn in the direction they are moving. Here is the code for movement I have so far:

if(Input.GetKeyDown (KeyCode.LeftArrow)||Input.GetKeyDown (KeyCode.A))
{
gameObject.transform.position += Vector3.left;
}
else if(Input.GetKeyDown (KeyCode.RightArrow)||Input.GetKeyDown (KeyCode.D))
{
gameObject.transform.position += Vector3.left * -1;
}
else if(Input.GetKeyDown(KeyCode.UpArrow)||Input.GetKeyDown (KeyCode.W))
{
gameObject.transform.position += Vector3.forward;
}
else if(Input.GetKeyDown(KeyCode.DownArrow)||Input.GetKeyDown (KeyCode.S))
{
gameObject.transform.position += Vector3.forward * -1;
}

I appreciate any feedback you guys can give. Thanks!

Well, to turn, just insert code that sets transform.rotation, e.g. transform.localEulerAngles = new Vector3(0, 90, 0).

(Obviously you will need to specify a different value for that rotation for each of the four directions.)

Also note that you never need to say “gameObject.transform” like that… just “transform” will do. Finally, when you paste code, please use the “Insert” button (between the picture icon and the floppy disk icon) to get it formatted correctly. See here for more info.

Welcome to the community, and good luck with your game!

  1. This really should be in the code section of the forums.

  2. When posting code make sure to put it into brackets:

like this!

(Quote me so you can see what I wrote to make that)

  1. There’s ton’s of documentation out there on this already and you need to work on looking it up.

  2. I would transform rotate towards a rotation vector3 in world space when pressing the button.

Edit: So something like:

void Update() {
if (Input.GetButtonDown("Left")){
  transform.eulerAngles = new Vector3(0, 270, 0);
}
if (Input.GetButtonDown("Right")){
  transform.eulerAngles = new Vector3(0, 90, 0);
}
if (Input.GetButtonDown("Up")){
  transform.eulerAngles = new Vector3(0, 0, 0);
}
if (Input.GetButtonDown("Down")){
  transform.eulerAngles = new Vector3(0, 180, 0);
}
}

Also, you’re going to want to cache the object’s transform so that Unity isn’t going back and forth to the location in memory every frame. What I’ve given you SHOULD work, but it’s not the “right” way.

To cache a transform declare it with your variables then assign it in the start or awake function:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {

private Transform myTransform;

void Start(){
myTransform = transform;
}
void Update() {
  //Now use
myTransform.eulerAngles = new Vector3(0, 0, 0);
//Instead of
transform.eulerAngles = new Vector3(0, 0, 0);
}
}

Hope that makes sense.

Edit #2: Here’s a great link on how to optimize things if you’re wanting more help on the matter:
http://docs.unity3d.com/412/Documentation/ScriptReference/index.Performance_Optimization.html

And remember, when working with eulerAngles: you can set them, but never read from eulerAngles (unless you know what you are doing)

but you could avoid using eulerAngles for something like this and use something like

transform.forward = -Vector3.left; //for instant. turn right etc.

Really? Does that actually work? I always assumed that .forward, .left, etc. were essentially read-only. To make assigning to them work, Unity would have to make some hefty assumptions about which axis you want to rotate around. There’s certainly nothing in the docs about it that I can see… but maybe it’s an undocumented feature?

Good thread. Moving it to a more appropriate forum.
Gigi

Well, Unity is an enhanced, tamed version of HAL. In 2001, a young man (let’s call him David …) found the remainings of HAL in an abandoned shed somewhere in Denmark. After 3 years of …experimentation he renamed it to Unity3D - a friendly, lovely piece of software - mostly. it makes no assumptions - at least not in this case:

transform.forward = -Vector3.left; //for instant. turn right etc.

This does Not rotate something around…slowly. This line immediately (this frame!) re-orientates your transform, so that an imaginary point one unit in front of it in local space (space of this transform) is = Vector3(imagine position in world space) 1(x), 0(y), 0(z)

  • Vector3.right is the same as -Vector3.left (sorry for being complicated)

you could use something like transform.forward = Vector3.Lerp(transform.forward, Vector3.right, Time.deltaTime * howFastValueInsertSomeFloatHere);

But this would Not rotate the transform in a constant (or lerp-ish) speed, but it would move the imaginary point (see above) to it’s new position - aand okay… resulting in some kind of rotation for the transform. but be aware

and sorry for being complicated again. super tired…

for beginners reading this:
I recommend spending a few hours, learning and understanding the basics of Vectors, what they are, what they do and to get a better understanding of world and local space etc.
:slight_smile:

Yeah, but there are an infinite number of orientations that do that. Point your forward vector in that direction. Now rotate around your forward vector. Orientation is 4-dimensional; this only specifies three dimensions, leaving one unspecified. So how is that one set?

I frankly didn’t believe that they would actually do this, so I tried it. You’re right; it works. I don’t know how they pick the free rotation, and I still claim it’s a skanky undocumented feature, but yes, it does work. :slight_smile: Thanks for teaching me something new today!

BTW @Zenthus , it’s also polite to follow up on threads you start and let people know if/when you get a solution.

1 Like

I see, what you mean is What about all the other axes, when just Y-rot. points forward?? what about ‘roll’ etc.

I THINK all other axes get reset?
When using LookAt you can define some worldUp variable, so this would solve the problem you mentioned yea? perhaps here some standart-up vector is used?

http://docs.unity3d.com/ScriptReference/Transform.LookAt.html

Right, I always use LookAt when I want to make an object look at something, because it’s explicit about the fourth axis (via the up vector).

Presumably Unity is just choosing some fourth axis when you just assign to transform.forward (or .right or .up, which also work). I think I know the conversation that must have happened at Unity, because I’ve been in a similar situation many times when I was working at REAL Software… “Well, users really shouldn’t be doing this, but if they do, we ought to make it do something sensible. So, let’s just pick a reasonable behavior and quietly code it up, but not document it or draw attention to it.”

It’s still cool though, and especially in 2D (where there isn’t this extra rotation ambiguity) it could be a really handy way to point a sprite!