I’m creating a 2D puzzle. Here, the rule is that, player clicks on puzzle pieces. If the piece is not under another piece, it will be cleared. However, if there is another piece on top of it, a penalty is applied.
One approach i thought was to use renderer.SortingOrder. But, problem is, it is common for two a higher order piece to exist in the scene and not be on top of a lower order object. In such a case, the lower order piece can be removed.
For example, this image:
Here, yellow is on top of blue, blue is on top of green and green is on top of red. So to solve the puzzle, the player has to first remove yello, then blue,green and finally red. Now if there was another orange piece not above or below any of these pieces, it can be removed first.
Using colliders that are “higher” than your planes, and checking if they are colliding with another of these colliders, and if so, check if the other object is below or above your plane. I think that’s the best idea
You could simply keep track of the positions using your own depth order of sorts. If you are using a 3d view(even if 2d game) you can simply use an axis position, say if they are further in the z direction. And if you are using an ortho camera things won’t get smaller no matter how far away they are.
I assume you are already in some fashion sorting the objects by distance(or something) because they are getting rendered that way. Just use the same system.
@N1warhead_1 , it’s 2D with Orthographic camera. I don’t think i can add trigger to both sides of the blocks.
@kburkhart84 , with that problem is, it is possible say one block has depth order 1 and another 0. Now, it is possible that both these objects are not in contact with each other. In that case, either of them can be cleared any time.
If there is only ever 1 top-most item, you can check for clicks on just that object. If you receive a click event on an object that is not that one, apply your penalty. When you do click on the top one, remove it and set the next most-top one to be checked.
Is the issue choosing & determining the top or having them visually in order? If you’re using an orthographic camera and you use 3D planes for the objects, you can just order their transforms. Since it’s an orthographic camera, the sizes will never change, but the visual layering should. Then a raycast should work, and you can check the z distance from the camera to determine if it is a top item.
@Tomnnn the problem is, it is possible that two pieces of varying transforms are on top. For example, in the image i have attached, say there is an orange block with same transforms ordering as the blue block. However, this orange block is placed separately without being in contact with any other piece. In such a case, blue block cannot be removed unless yellow is removed. But, orange block can be removed at any time since it is not in contact with any other block.
Isn’t that intended? I was already assuming your game was being inspired by mahjong
What you’re describing sounds like an issue with design. If it isn’t intended for the orange block to be removed yet, why is it placed in the same layer as the blue block with nothing above it? What is supposed to happen? If your game is not supposed to have cases like this, do not consider them while designing your other systems. Focus on making sure your level generator does not bug out and produce incorrect layouts
If this kind of situation is intended to happen, how is the user supposed to handle it?
@Tomnnn this is embarrassing :x i did not know how Mahjong is played. Since you brought up the similarity, it’s easier to find the required solution. Thanks a lot.
I would just set the Z order of all objects based on the order they are layered, then with a raycast again triggers/colliders, if the player chooses one with a Z order that is further away than the closest remaining Z coordinate, it’s an error. Keep track of the closest object’s Z coord, use an array of object positions. etc
You need to use a sweep rather than a ray, though from memory that only works for certain shapes.
Edit: Checked the docs. Works for anything that’s a Rigidbody as long as it’s not using a mesh collider. You might also have to do an overlap test if there’s any possibility that your objects can penetrate one another, as I don’t know if the sweep will report pre-existing collisions.
If there are non-overlapping stacks of different heights that won’t work, though.
[RequireComponent(typeof(BoxCollider2D))]
public class Stick : MonoBehaviour
{
void OnMouseDown()
{
// Find all colliders that overlap
BoxCollider2D myCollider = GetComponent<BoxCollider2D>();
Collider2D[] otherColliders = Physics2D.OverlapAreaAll(myCollider.bounds.min, myCollider.bounds.max);
// Check for any colliders that are on top
bool isUnderneath = false;
foreach (var otherCollider in otherColliders)
{
if (otherCollider.transform.position.z < this.transform.position.z)
{
isUnderneath = true;
break;
}
}
// Take the appropriate action
if (!isUnderneath)
{
Debug.Log("HOORAY!");
Destroy(this.gameObject);
}
else
{
Debug.Log("OOPS!");
}
}
}
@AdamScura_1 Thanks a lot. I’ll try it. @angrypenguin i can’t use rigidbody in this case. @imaginaryhuman_1 i checked pickup sticks. Except for the pairing part, it does look similar. Thanks.