Minigame Monday: Selection Boxes

 Selection Boxes:

  • The concept:

Happy new year! For my first minigame of 2023, I wanted to do another game in Unity, and practice with some of the areas I wanted to learn more about. The main thing I wanted to do was play around with converting between screen and game co-ordinates, so this turned out to be another project where I started working on the game before I actually knew what the gameplay would be! After getting the rough behaviour in, I quickly realised I wanted to make a level based puzzle game using it.

  • The challenge:

My rough idea was that I wanted the player to be able to draw a box on screen, select objects, and move them around the screen. Breaking this down into steps, the first thing I needed to do was draw the box. To do this, I recorded the point at which the player first clicked, and then converted this point and where the mouse currently was into a box. I then converted these co-ordinates into world space, making sure to provide a z co-ordinate away from the camera.

        if (bIsSelecting)
        {
            //Draw selection box
            Vector3[] points = { 
                boxStart,
                new Vector3(boxStart.x, Input.mousePosition.y),
                Input.mousePosition,  
                new Vector3(Input.mousePosition.x, boxStart.y),
               boxStart };
            for (int i = 0; i < 5; i++)
            {
                points[i] = Camera.main.ScreenToWorldPoint( 
                    new Vector3(points[i].x, points[i].y, boxDepth));
            }
            box.SetPositions(points);
            box.enabled = true;
        }
        else
        {
            box.enabled = false;
        }

 In the code snippet above, box is a line, making up the selection box, and boxDepth is the distance from the camera to show the box. This needs to be far enough from the camera so that it is not culled, but other than that as long as it's not further than the main objects, any value will display the same.

The next issue was choosing which objects to select. This was simply a matter of converting both the object transforms and the screen positions of the box to the same frame of reference (I chose the viewport), and checking which movable objects fell within the correct bounds. After that, the last part was moving the selected objects. This was a little difficult to do, as moving the mouse doesn't take into account the angle of the play field. Here was my solution:

    RaycastHit beforeHit;
    if (!Physics.Raycast(
         Camera.main.ScreenPointToRay(lastMousePos), out beforeHit))
    {
        break;
    }
    RaycastHit afterHit;
    if (!Physics.Raycast( 
        Camera.main.ScreenPointToRay(Input.mousePosition), out afterHit))
    {
        break;
    }
    Vector3 movement = afterHit.point - beforeHit.point;
    selectedObjects[i].transform.position += movement;

I'm using a raycast here, to collide with the play area and give me the co-ordinates I want. I was able to set the objects other than the floor to ignore raycast, so the ray will always hit the floor correctly.

It was at this point that I worked out what I wanted to do with the gameplay, and decided on puzzles where you had to correctly move coloured blocks into target boxes. I decided I wanted to make a wireframe design for the target boxes, so that you can see the blocks inside them, and that lead me to my next challenge: making a shader for a wireframe material. I followed a tutorial from https://blog.logrocket.com/building-wireframe-shader-unity/ for this; this was my first experience with shaders, and although I didn't go into too much depth with shaders this time it was interesting starting to gain an understanding of how they work. I unfortunatly discovered that unity shaders don't work with Webgl, so I had to simply use transparent boxes for the web version, but I've made a downloadable version using the shader.

Boxes using the wireframe shader
Boxes using the wireframe shader

  • The result:

I'm pretty pleased with this game, I used a number of things that were out of my comfort zone, however the end result is one of the cleaner games I've made. I also had to do some level design for the puzzles, and I think I managed I managed to make some of the levels good enough that they'll require a bit of thought, and hopefully give the player a nice sense of accomplishment when they're solved! The game can be played at https://reddragonmakesgames.itch.io/selection-boxes, and the code is on my github.

Comments

Popular posts from this blog

Armageddump (Boss Rush Jam 2023)

Introducing: Minigame Monday! (3D Minesweeper)

Minigame Monday: Covert Behaviour