So here’s my conundrum. I’m relatively new to Unity’s 2D features so there’s a chance I may have overlooked something simple or I don’t know what I’m talking about.
I want to know if it’s possible to have a TileMap Collider 2D make edge colliders that can be linked together using a Composite Collider.
I created a player controller initially using 2D Rigidbodies and Colliders where I manipulated the Rigidbody.velocity in FixedUpdate. However, I found this was suboptimal because it created a jittery movement with my camera follow script, and other oddities such as falling slowly while my character is air dashing when I didn’t want it to. I need a solution that updates every frame during Update() and not FixedUpdate().
Rather than rewrite my player controller from scratch again, I found this 2D Character Controller online since Unity doesn’t provide one. I’m able to just use the velocity logic I have right now (with a few small tweaks) and I just have to apply my own gravity before I call move.
Unfortunately, for one-way platforms it uses Edge colliders where before I was using a Platform Effector 2D.
What I want to do is generate an edge collider from the top edge for my semisolid/one-way platforms so that I can use this script.
I tried creating a thin box for my custom physics shape but the TileMap Collider 2D is ignoring it and using the auto-generated one.
The script does appear to respect these colliders for one way, (somewhat) but it’s possible to get stuck inside of the outline so I either need it to have a thickness of 0 (meaning the top and bottom edges are touching) or only generate the top edge.
Is there any way I can use the TileMap Collider 2D for this without having to manually create my own edge colliders?
EDIT: If I make my collider 1 pixel thick it works, but it’s still suboptimal because it’s possible to accidentally hit the bottom edge and be 1 pixel below the floor. This is ok I guess, but the edge collider doesn’t have this issue.
I do not think it is possible right now for the TilemapCollider2D to automatically generate a particular edge for each Tile right now. If you can show some examples of your one-way platforms, that would be great!
I believe this should be possible, but it depends on how thin your box is in the Custom Physics Shape. Could you share a screenshot of the size that you want (eg. a single pixel in height or so)?
I have a Grid with 4 children. Each child has a TileMap and is tagged to a specific sorting layer/tag. For example, background props render behind the player, and in front of the background. So on and so forth.
The two children that deal with ground have their tilemaps as child objects.
I currently have the shape set to one-pixel width. I don’t know how I was able to do it, but eventually, I got the TileMapCollider to register my custom shape. I think I eventually had to close and reopen the editor. (Which I’ve been having to do a lot anyway because for some reason if I leave Unity open for too long it gives me an Access Denied error for my account)
Now the problem with this is if I have the width anything less than 1 pixel, the shape doesn’t get created correctly. With the script I found at the GitHub repo I linked earlier it seems to work with this setup, but if I’m unfortunate enough to land inside of that 1 pixel box coming in from the side, the ray casters will treat that 1 pixel height collider edge as a wall and the player will have to jump in order to get past it. I think this is a bug I’m willing to work with. If I have the collider type set to outline it seems to work ok. Landing in that box is extremely hard to do, after 30 minutes of intentionally trying to do it I was only able to do it once. (Though to be fair I’m not the most coordinated player either lol)
If it’s not possible to create edge colliders that answers my question and I’ll either have to live with the workaround I have right now or just create them by hand. Once I get close to letting other people play I’ll probably just manually edit them in anyway as the level design should be solidified at that point.
Thanks for the help, though! I greatly appreciate it!
If you edit the Custom Physics Shape after the TilemapCollider2D, you will need to reset the TilemapCollider2D to update the shapes. You can do that by clicking on the 3 bars icon thing at the top right of the Inspector and select Reset.
We will put this in our features backlog and see how we can handle this better! Thanks for bringing this up!
I did not know that! Even though I’ve had my Unity account since 2014 this is the first time I’ve ever sat down and actually tried to use it for more than just a few hours so I still have a lot to learn.
What would actually be more useful is a CharacterController2D package that made use of all of the current collider logic but without the physics! The one I found gets the job done but doesn’t work well with anything that isn’t a Box/Edge collider. The PlatformEffector2D already does a great job of handling one-way collisions which is what I was using before this when I was using Rigidbody physics for movement. Unfortunately, in order to use the built-in physics engine I have to use FixedUpdate which didn’t work well with the Vector Smooth Dampening of my camera. If I used LateUpdate for my camera script my player character would appear to jitter between frames. If I used FixedUpdate the world would jitter between frames. That’s why I made the choice to just handle my own physics with a Character Controller.
Now, if there was a way to get the built-in Character Controller to play nice with 2D Colliders I’m all ears. Maybe I overlooked something.
However, I bet adding edge colliders as an option for Sprites and the TileMapCollider might benefit someone else as well.
Whist (by default) physics runs per fixed-update, you can select “Interpolate” mode on any Rigidbody2D. This updates the Transform per-frame from the old body position to the new one so this provides smooth movement. You can then key other movement like the Camera to the Transform. Note the Rigidbody2D.position/rotation will always only be updated when the simulation steps.
You can also run the physics per-frame (with a loss of determinism) too (see Physics2D.autoSimulation).
I’m not following why you need edges. The PlatformEffector2D works with the collision normals to determine if the collision should be disabled therefore allowing the collider through. Boxes, Edges, Circles, Capsules etc all work.
This I did not know. I will try it out again to see if I can go back to using Rigidbody Velocity movement rather than this Character Controller script I found.
My camera movement was reading the Transform position so if that gets updated every frame then the movement should be smooth. (Hopefully)
I’m still relatively new to using Unity so I’m not well versed on all of the options available to me.
It’s a specific requirement of this script that I found here.
It uses edge colliders for the detection of semisolid surfaces and cannot use the PlatformEffector2D without heavy modification. However, if I can just avoid using this script altogether then there’s no need for edge colliders anymore and I can go back to using Rigidbody physics with the PlatformEffector2D.
EDIT: After playing around with the suggestions, the best thing I found was turning off auto simulation, then at the end of Update calling Physics2D.Simulate(Time.deltaTime);
No jittery player movement, no jittery camera! Most importantly, I can still use all of the built in colliders!
I don’t think I’m supposed to do this, but it works.
The Interpolate / Extrapolate settings were smoother than running without them, but still created jittery character movement.