Here is what I am attempting to do: Imgur: The magic of the Internet - If Link gets close enough to the corner of a wall or other object and attempts to walk, he is nudged a bit in the right direction. I tried using a circle collider to replicate this behavior, and although it helps a bit, it is not enough. It needs more of a “push.”
I am using a tilemap, so my colliders are all over the place, but they are one entity (using Tiled and Tiled2Unity to build a map generates colliders as one big collider if on the same layer, even if spaced out). Therefore, writing code that accounts for colliders’ extents or centers does not seem to be helpful, but perhaps using the vertices/points of the PolygonCollider2D “chunks” is.
The logic would go loosely like this:
Player touches other collider
Note player’s movement/facing direction
While OnCollisionStay2D, calculate all vertices of other collider
If any vertex is touching player’s collider/certain part of collider, nudge player in the axis opposite of the current moving/facing one
This seems like an expensive and overly complex method of completing what seems to be a relatively simple task. A PolygonCollider2D on a tilemap can easily have hundreds of vertices, and calculating them every time a collider is touched, multiplied by several NPCs and enemies seems expensive.
Am I wrong? Since I’m a beginner, I am sure that there is something that I do not know that will make this easier. Has anyone worked on a problem like this before?
One way to do is to ray cast in movement direction and just rotate the normal of the object you hit by 90 degrees and then instead set velocity in that direction instead of the movement direction.
This can be cast into any collider and would even work in 3D.
A normal is a vector that is perpendicular to a line. By being a normal to the object I mean perpendicular to the line that the ray cast hits! So if you rotate the normal by 90 degrees you would get a vector that is aligned with whatever surface you are touching. Then you basically just need to move the player in that aligned direction, given that the distance to the line you hit is higher than a threshold that you decide.
Thanks. I am trying to avoid having every corner be its own collider. This would get complicated once NPCs and otherwise moving sprites are in the scene. One of my first thoughts was to have colliders with diagonal edges for corners - basically, octagons - that the character can slide easily around. Currently, if my character walks north, for example, onto a diagonal wall, the character slides up the diagonal.
If your game is tile based, and all colliders are 1x1 squares, then you can solve this by just finding the normal and calculating distance from corners when deciding how to move.
The game is tile-based, but movement is not, and not all colliders are 1x1 squares. But since I use a tilemap via Tiled and Tiled2Unity, my colliders are merged into a single mesh, so an object with tens to hundreds of vertices.