Trying to understand 2D Top Down Movement (RPG-like)

Hey all.

So this may seem like yet another movement question, but I’d like to think it’s fair enough, because despite my efforts, I haven’t quite found what I need.

I have seen MANY movement scripts around, both here and elsewhere like on Unify. There are a few problems, though, related to them – namely that many of these were done before 2D was implemented (and yes, I know that shouldn’t technically matter for the coding but still… ), and even though many were done after as well, I seem to run into similar issues.

A brief explanation of what I want:
I want to be able to move my character along the X and Y axis, as is common (given Unity’s Z axis) in old school RPGs like the older FFs and well, pretty much every turn-based RPG from more than 15 years ago. (Pokemon is another good example if you’re still unsure of what I mean)

I optionally want the option to be able to move in a grid like manner, but not through just teleporting from one spot to another, rather actually physically moving to it (again, like Pokemon), but if that presents issues, then I can live with diagonal and non-grid movement.

Finally, I want to actually collide with objects and stop to a stand still. No jittering or phasing through the colliders (that may seem obvious, but I will elaborate why I’m saying that).

What I keep running into:
Most movement scripts I find for this type are mostly based around side-view scrollers and employ jumping. I also see rotation used because of top-down shooters and the like, but when I dissect the code I still don’t get something usable because…

It’s usually two things that end up happening. One: I don’t have grid movement scripts that are working as intended to actually toy with and see what’s happening – so even though it’s an optional thing for me, I’m a little eh about not having much to look at so I can learn (incredibly visual learner when it involves code), and Two: When they do move, they completely ignore colliders. I have a theory that there is a higher level technique to employ that helps check for that, but I’ve yet to see it.

Finally, colliders in general have been super weird for me. Many of the scripts I test out have me sticking to the colliders or still phasing through them. I NEVER get stopped by the collider. I either jitter, or I go through it eventually.

What I do:
Now, I am fairly new, but I think I’m correct in saying that in order to get your standard collision, you use a Rigidbody2D (correct for gravity), and a boxCollider2D on your character, and a simple collider of whatever sort on your wall or statue or what have you.

I mean, correct me if I’m wrong but that never works for me.

I don’t check >Is Kinematic, and I am sure that they’re on the same plane, so they definitely interact (as evidenced also by the jittering and stuff).

TL;DR:
I just want a good movement script for 2D, but all the stuff I find has errors involving sticking to colliders, going through them, or using too many different aspects for me to easily learn from the scripts so I can make my own. I would like some tips to maybe point out what is going on, and where I can start learning these (apparently) finer skills. Or just point out how silly I am if I’m just being an accidental idiot, haha.

Further TL;DR:
Help me, the movement scripts are mean and borked for me :frowning:

  1. It sounds like the reason you’ve been having trouble with collides is that you are setting the transform.position rather than adding forces to the object. Basically unity has a whole physicals simulation it would like to run that ensures objects don’t get inside each other and when you tell an object to instantly move (by setting position) that physics system can glitch out in many ways.
  2. I can see a few ways to achieve what you’re looking for. One is to use ray-casts to figure out if the player will bump in to something before it is allowed to move. A ray-cast is a built in unity thing that allows you (in a script) to send out a line (like a laser) from your player in a direction and it can tell you all the objects it goings though and how far away they are. This option allows you to mostly continue doing what you have been doing, but it replaces the built in unity physic simulation. Your walls will still have box collides and so will your player, but now you will set your player to Is Kinematic (don’t get pushed by other physics objects). Then based on what your code discovers with the ray-casts you can chose to allow the player’s transform.position to be set to a new value (on the grid) or not. The down side of this approach is that ray-casts can get a little complex.
  3. Another option is to store the whole world in a 2D list (matrix) of some kind. This is a list of lists of values. It could be visualized like this
    [[“wall”,“wall”,“wall”],
    [“empty”, “empty”, “player”],
    [“wall”, “wall”, “empty”]]
    Stored in each slot is the name of what’s inside it. When you draw the game to the screen you pick the image for each tile based on the name in the matrix cell. When the player wants to move to the right you just have to look at the cell to the right of where the player currently is and if it’s empty swap those two values. When an object is moved from one tile to another you can play an animation that makes it look like it’s going from one cell to the next (but really it’s an instant jump). This system is maybe easier to wrap your head around, but has some downside. Things like jumping, or smooth motion across many tiles can get tricky. Everything in the world will need to be in this matrix (more or less).

Sorry I don’t have a perfect simple solution for you, that tends not to be how game development works.
Have you seen this? It might be your best bet.

That’s some awesome information!

Yeah, I’m just sort of getting frustrated pulling long nights trying to find resources that are already complete so I can start understanding what they’ve done and practice those parts but it’s always so much that conflicts or isn’t quite what I’m looking for. This is a lot more in the way of clarification though, thank you.

And yeah, I’ve seen and done the Roguelike Tutorial, but it provided some less than applicable stuff (not bad stuff though, I learned a lot!) and some of the gaps were proving hard for me to understand how to fill.

For 1: I’m inclined to agree somewhat, but at the same time, I’m also having this issue even with stuff that is not just porting in, rather it has a speed and everything and it’s creeping into the box collider despite its existence (albeit definitely resisted, given the jitteriness). Letting go also forces me out onto a nearby tile, but I’m just not sure how to circumvent that and why.

However, for 2: It may be that I jsut need to invest time into practicing this. I’m not entirely sure why I’m having this issue, since many people seem to avoid it just fine, but I digress. Regardless, it appears that will get me better results, assuming it is able to do that pre-check, which may be the entire reason I’m phasing through in the first place.

3: While this is absolutely what I’ve seen elsewhere and assume to be correct, I thankfully have a workaround (which, to be fair, might be tossing me some issues from itself too), because I’m using Tiled and Tiled2Unity to create the maps. Elsewise, I would have accepted the need to learn all of that.

I super appreciate the input.

If you or anyone else has some ideas for good tuts/vids on Raycast (2D) usage and practice, I’d love to see them!