2D Top Down Character Control

Hi guys, I’ve recently started using Unity, and I’m very new to C#, so I decided to make a test game of sorts in order to get used to the more common methods before I start making games. For that purpose I set the framework to 2D defaults and am just using a cube resting on a plane for the player. I’m having trouble getting the cube to rotate in order to face the mouse pointer. Here’s my controller script

	void Update ()
		// Get smoothed input

		float MoveHorizontal = Input.GetAxis ("Horizontal") * moveSpeed;
		float MoveVertical = Input.GetAxis ("Vertical") * moveSpeed;

		// Apply movement

		transform.Translate (Vector2.right * MoveHorizontal * Time.deltaTime);
		transform.Translate (Vector2.up * MoveVertical * Time.deltaTime);

		Vector2 mousePos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
		transform.LookAt (mousePos);

However, after doing some research I’ve realized that LookAt cannot be limited to using only x and y. I tried transform.rotate, but that doesn’t take Input.mousePosition as an argument.

I did some more digging and found several similar questions here, but people are making some more complicated things like having some type of action attached to the mouse. I’ve tried some of the example codes, and funny enough the one that I understood the least, work the most. Even so it didn’t really work properly, and I couldn’t figure out what the problem was. Also I don’t really want to use something that I don’t understand. Just as an example, here’s the code I found around here:

//		Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10);
//		Vector3 lookPos = Camera.main.ScreenToWorldPoint(mousePos);
//		lookPos = lookPos - transform.position;
//		float angle = Mathf.Atan2(lookPos.y, lookPos.x) * Mathf.Rad2Deg;
//		transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

Like I said it kind of worked, but the controls were reversed and even inverting them from the Input manager didn’t help. I also tried changing a few signs but that didn’t work either. I’ve also tried Quaternion.Slerp but that only takes from and to parameters.

Sorry for asking such a simple question but I really done quite a bit of searching, and either I missed something or I really suck at programming and can’t take a hint from another answer. I only want the cube to rotate on around it’s z axis in order to face the mouse. Nothing more, I’ve found people needing to cast rays and to clamp movement to 90 degrees only, I don’t need anything like that.

Also, while on the controller subject, is it better to use transform.Translate or use rigidbody.velocity for movement? Would that work on a cube or even a character, I mean it wouldn’t just push the model around making it tumble like a misshaped piece of wood? Or rigidbody.AddForce (that only worked on a sphere though)? Also, since its a 2D game, is it pointless to have a cube? Can I just go with a quad? And if I can how would the 2D collider work if I place the quad at -1z and enemy shoots a bullet at -2z? If it wouldn’t register does that mean that I’m limited to 1 type of collision per axis unit, or is this where c# layers come in play?

I’m very sorry if I’m overloading with stupid simple questions, but everywhere I look has answers that either I can’t understand or include a load of other things that I don’t have the questions for atm. Any explanation on any of these matters is highly appreciated. Thanks in advance.


First thing first, welcome to Unity ^^

Have you started your project by checking the box 2D project? It simplifies many things when working only in 2D. And yes it’s useless to have a cube in pure 2D, but many 2D-games nowadays use 3D models (super smash bros as a well known example), so that’s your choice, also depending if the player would see a difference.

If you checked the 2D box and use a sprite (jpg, png, …) instead of a cube, I think you wouldn’t have trouble to rotate it only on z. But just because I’m not sure: have you tried to freeze rotation of the cube on x and y axes (in the rigidbody component)?

About coding the controller, I just know it’s a bad idea to use translate or rotate as they don’t handle collisions properly.

About the z axis, the simplest stay to launch some tests :stuck_out_tongue_winking_eye:

Good luck!

The code outline in the comments will work if you left the setup as default. Default means the camera has a rotation (0,0,0) and therefore facing positive ‘z’. If you are using a perspective rather than an orthographic camera, you need to be careful about the use of ‘10’ in the first line. It will be the distance in front of the plane of the camera to the plane of your 2D action. The 10 is not necessary for an orthographic camera. Also this code expects the ‘forward’ of the sprite to be to his right. If you are using the ‘up’ as forward, then this code will have to be changed. If you have a default setup with the character facing right and you are still having trouble, post the script you are using with this code and we can take a look.

The 3D Physics and 2D Physics don’t mix. You can use both in the same program for different things, but a 2D object won’t collide with an object with a 3D collider. All the 2D physics use Vector2s, so the ‘Z’ component is discarded/ignored.

Movement though Transform vs. CharacterController vs. Rigidbody are all different with their strengths and weaknesses, so which to use will depend on your app and goals. There is no universal “better.” I encourage you to do a simple test app or work a tutorial with each.