Mouse Position and World Space

I’m working on a 2D project within a 3D world (most objects are 2D sprites, but there are a few 3D objects).

One sprite object has a grid texture on it. The grid can have various number of cells horizontally and vertically. The sprite position does not change but depending on the grid, it can be square or rectangular in a horizontal or vertical orientation, so it’s size does.

I need to ‘click’ on a cell and know what cell that is clicked on using a grid index (upper left cell = 1,1 and lower right cell = grid width, grid height). Then, I need to instantiate a prefab object centered in the clicked cell, and add data to an 2D array mimicking the grid. If you need a visual, think of tick-tack-toe with different sized grids.

I’m struggling to find a solution so I know which cell is clicked and how to position the prefab. Compounding all this is window scaling. I’ve been trying to come up with some sort of universal algorithm to handle multiple grids and various window sizes. I’ve been converting vector3’s to screen space coordinates and vice versa but can’t figure out the proper procedure.

I’d be very grateful if someone could provide a simple step by step to get me out of the ditch I’m in.

How are you resizing this grid sprite, and changing the number of grid cells on it? That sounds like fairly big magic in itself. And how you are doing that probably impacts how you figure coordinates from it.

But the basic idea is, when the mouse goes down, you should do a Raycast to figure out where exactly it intersects your grid sprite, in world space. And then you just do a bit of math with that world-space coordinate to get the cell clicked (and a bit more math to compute the prefab position).

Hi Joe,

The sprite lives in a 3D world, resizing the window resizes all elements in the scene. The grids are pre-made sprites. The smallest is 6x6 and the largest is 10x10 and all variations of those. I just swap out different sprites into the sprite renderer of the object.

After a little more hair loss, I think I’m starting to unravel the problem. I’ve been trying to get all coordinates into world space or screen space before doing my math. I was making two operations into a single confusing mess. Since I know the grid dimensions, I’ve managed to place objects on the grid correctly by providing x and y locations. One operation done but still having issues with mouse location and scaled windows. Think I’m getting close though.

I don’t understand your suggestion about doing a raycast, but I’ll check the docs to see how that would work.

Yep, the raycast is the right solution here, and trying to do it any other way would indeed cause loss of hair.

You’re already studying the docs, so you know the syntax. Just in case the theory isn’t clear, here’s the idea in a bit more detail: you will cast a ray from the camera position, through the screen at the position of the mouse. This will hit (or not) something in the world — there are ways to use layers to restrict what it can hit to just your grid sprites, but don’t worry about that right away. The raycast function will report a lot of info about what it hits, including the collider that was hit (oh yeah — your grid sprites need to have colliders!) and the point in the world that was hit.

So now you have the point in the world, so from that you can work out what grid point was hit.

Good luck!

I didn’t realize hit.point returned an actual 3D point. I thought it returned just the collider. Regardless, I’m trying to avoid a collider on the grid object because of some poorly thought design issues from the start. I know I should refactor the entire project but I’m in so far now and the grand kluge is working, so I’m more than reluctant to build a proper foundation and claw my way back to where I am now just for simpler and cleaner code. A must have for v.2.0 if there ever is one.

Once I realized everything I was trying to do centered around the x, y coordinates system, everything clicked. I needed to get an x, y mouse position in screen coordinates, and x, y in world space, and an x, y of an array to store what was placed. From my last email I had the world space positioning working and also the data array. Now I have it all working correctly, and I have to say it was a WWF brawl all the way.

My grid sprite is not centered in the scene, which added another wrinkle to the mix. I realized the grid was a percentage offset from the top and left. Once I figured out the correct offset percentage, calculating the top left corner allowed me to then calculate grid positioning as an x, y and that scales with any window size. I gave it my best to break it, but I’m getting 100% results, so I call it done for now.

Thanks for the ray cast tip, I’m thinking if I had started this project correctly, that would have been easier way to go.

1 Like

Considered using a world space canvas and the event system? It might be another option to think about.