How do you make an omnidirectional 2D character controller?

I have not been able to find online examples of an omnidirectional 2d character controller, and can’t seem to find one that we can use as an example before developing our own. It is our first time creating a custom character controller and would really love some help with developing this one. In case you don’t actually get what we mean by an omnidirectional controller, have a look at the game Realm of the Mad god. Probably the best example out there. Thx in advance~

Most 2D character controllers have some code that adds a horizontal amount and a vertical amount to your character’s position. If you have looked through a few 2D character controllers, you have most likely already encountered some code that does this.

For example a 2D character controller might have code that does the equivalent of this:

player.position += Vector3.right * Input.GetAxis("Horizontal") * movementSpeed;
player.position += Vector3.up * Input.GetAxis("Vertical") * movementSpeed;

If you want to add movement in all directions, all you need to do is supply some different up and right vectors:

Vector3 playerForward = /* Get the angle that the player is facing */
Vector3 playerRight = Vector3.Cross(Vector3.forward, playerForward);
player.position += playerRight * Input.GetAxis("Horizontal") * movementSpeed;
player.position += playerForward * Input.GetAxis("Vertical") * movementSpeed;

In particular, to reproduce the movement in RotMG, all you have to add to a generic character controller is two keys that control the angle of the player (i.e. camera rotation). Then you can just put that rotation into playerForward.

If anyone comes across this answer it is correct if you are using translate to move your character. However I was using rigidbodies.

In order to fix this issue with rigidbodies you must use:

took me a while to figure it out, hope this helps someone.

I stumbled upon this question when trying to solve this issue for myself. However I use rigidbodies to move my character not translation. The above answer solves it for translation I beleive but if you land on this answer and use rigidbodies the answer is:


Rigidbody.AddRelativeForce(Vector2.down * speed);

in lieu of:

Rigidbody.AddForce(Vector2.down * speed);

that adds the force in the local axis not the global.

documentation is here:

hope this helps someone.