In my 2D non-tile game, I have small colliders at the bottom of all my trees. The player can move behind the upper part of the tree, which is what I want, and it cannot walk behind the bottom of the tree, which is also what I want. However, when I added Rigidbody to the player, it affected the entire player, so that it cannot pass in front of the trees with its head passing in front of the collider. I hope this doesn’t sound too confusing. The only way I can think of achieving this is somehow splitting all of the player’s animation frames into top and bottom halves, as completely different sprites, and only apply Rigidbody to the bottom sprite. But this would take a very long time, and I’m not too sure how exactly to do it, and it seems to me like there must be a simpler solution. I only really started using Unity a few days ago, so I might not be able to understand anything too advanced…
There’s no reason to split up the sprites-- you can give more than one collider to the same object. I would add one to the feet area of the sprite that is used for collisions and triggers, and if you need any more, add them to the appropriate parts of the object.
You can manipulate layer interaction with the Collision Matrix, and choose appropriate layers for each collider. Really, though, I think you only need to resize your current collider so that it only covers the bottom half of the object.
Thanks for the reply! And yeah, I finally figured out how to change the size of the player’s collider and move it down to the feet, after a while. But the problem I still have is that when the player walks in front of the tree, its head is still behind the trunk of the tree, as if it were still walking behind the tree. I’m guessing that the Collision Matrix thing you linked might be what will fix this, but I don’t really know what that is. I can’t seem to find any more info on it. If collision matrix isn’t what I actually want, I’m thinking that maybe I have to write some code so that if the player’s Y position is less than a certain point, it will be moved to a layer above the tree’s layer. But this, too, would be a lot of work since all trees are on the same layer and at different Y positions so I would have to split them all… I’m probably overthinking this.
The collision matrix can be found in the physics (2D) manager, accessed Edit > Project Settings > Physics (2D). Of course, in your case you want to use the 2D one.
The matrix is used to selectively disable interactions between two entire layers of colliders. This means that they won’t run into each other, and they won’t call collision events when they touch. Often you want certain types of colliders to ignore each other, and this is one way to do that (also check out Physics.IgnoreCollision, a way to disable collision between two specific colliders regardless of layer).
This may come in handy for you if you ever want the characters head to collide with something in the game, for example, but you still don’t want it to interact with trees and walls. Use some method to disable the interaction between them while preserving the desired interactions.
Draw order of sprites (or any other renderer) can be defined by sorting layers and sorting orders. You can set the sorting layer of a renderer, then set its order within that layer to define the order that all 2D renderers are drawn, even when they have the same z-position. This is what you want to play with to fix your new problem. Both of these can be set in sprite renderers and by script (look in the SpriteRenderer documentation)
I think you have the right idea of checking the y-position of the object. You could put the tree and the character in the same sorting layer, but change the order in the layer of each based on the y-position. This way, you’ll be able to walk your character around the same tree prefab placed anywhere in the scene without graphical errors. Note that sorting order is an integer, and is limited to values between -32768 and 32767. This means that assigning order based on a position value is going to have some granularity to it, which I think you’ll find acceptable. Maybe use one sorting order for every 0.1 distance in the y-direction?
If you plan on having multiple height levels in a top-down game (and so walking past a high bridge while on a lower level should always result in the character appearing “under” the bridge), you could handle this by assigning a sorting layer to each discrete height level, then set sorting order as before. Things in “higher” layers will always be drawn on top of things in “lower” layers, giving the expected appearance of depth.
If you use this technique, you can of course still use other layers for other things, like foreground scenery that is always drawn last.
I’ve said a lot already, but make sure you read about the Sorting Group component as well. This is a component that you can add to an object to override the sorting properties of itself and its children by defining a different sorting layer and order to use for the whole object family. The relative draw order of the object and its children is preserved, however, and the whole group is treated as though it were in a position in the draw order, even though the draw order of all of its parts is still correct. If that sounds pointless, check out the manual page I linked in this paragraph, there is a typical use case described with pictures.