Get a position on an image relative to its top left corner?

Hello, I’ve got an issue with my new grid based inventory system. I’ve no problems getting the grid position on the image, but I’m struggling to turn that grid position into the position of the item that is meant to go in the inventory. My code for this is basically botched together & jury-rigged for a 10x10 grid, with the top left corner as (0, 0), which is the only thing it works on. If I use it on a 5x5 or any other size the image goes out of alignment. I’ve renamed some of the stuff here and broken it down so it’s easier to see what’s going on. gridPosition is the tile the player clicks on, and works fine. The +1 is a botched offset to account for the image going one square too high and too far from the left. I’m thinking if I can put something more dynamic there it might work.

//Calculate how large a tile is because the size used currently depends on the resolution
float tileX = grid.sizeDelta.x / inventorySizeX,
                  tileY = grid.sizeDelta.y / inventorySizeY;
//Return the tile position.
            return new Vector2
            (tileX * (gridPosition.x + 1) + tileX * itemToPlaceWidth / 2,
            -(tileY * (gridPosition.y + 1) + tileY * itemToPlaceHeight / 2));

Why are you manually calculating this stuff???

Unity’s uGUI has components for grid layouts.

It has a what?

Oh. Dammn.

I’m like 90% of the way there too.

https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/script-GridLayoutGroup.html

No need to do work you don’t need to do.

Thank you. But I’m working with a single image and I’d probably have to redo my entire system to use a layout group with individual tile images… Might consider it, but I’m nearly done here. I also found this ‘grid’ component, but I can’t really find much on what it does. Or, in fact, how to get it to do things. It’s like nobody knows about it.

Sounds like you have fallen for the Sunk Cost Fallacy.

https://en.wikipedia.org/wiki/Sunk_cost

You’ve already wasted time on it and now you assert that as a reason that you want to waste more time on it when there is a far-superior approach.

Anytime you attempt to manipulate RectTransform properties in code, you’re gonna have a bad time.

Move up the foodchain, use the GridLayoutGroup Component.

Otherwise, if you insist on fiddling with RectTransform properties and moving UI around on your own, break out the UnityEngine.UI codebase for how they did each step.

It’s a LOT of steps. Simply putting anchors on the corners of a RectTransform is about 15 lines of code.

http://forum.unity3d.com/threads/script-simple-script-that-automatically-adjust-anchor-to-gui-object-size-rect-transform.269690/

Well, I mean, maybe. But I do feel like fixing this one calculation that almost works, or even replacing it, would be quicker and easier than inventing an entirely new system. But thank you. I’ll try that first, and if it doesn’t work I might try the layout group. But what’s the deal with the grid component? It doesn’t really seem to do anything I can see.

EDIT

Actually, reading that code a bit more I can’t even tell how I would use it to set an image to a grid. Sorry. It’s all about modifying object pivots. That’s not something I’m doing right now. I don’t know why I wouldn’t just pre-set anchors. That’s what I’ve been doing.

Yeah, I don’t think that’s going to work tbh. I may have to do the layout group. Annoying, as I really hate those things.

I don’t understand this thinking.

You need a regular grid of positions in a UI.

GridLayoutGroup can give you this.

What’s there to hate?! Are you not using UI or something?!?!

Be kind to yourself. Accept the help you can get from existing tried-and-tested libraries.

I’ll post it again for you, but this is just another classic example of why Inventory systems are a Very Hard Thing™ to get right.

These things (inventory, shop systems, character customization, dialog tree systems, crafting, etc) are fairly tricky hairy beasts, definitely deep in advanced coding territory.

Inventory code never lives “all by itself.” All inventory code is EXTREMELY tightly bound to prefabs and/or assets used to display and present and control the inventory. Problems and solutions must consider both code and assets as well as scene / prefab setup and connectivity.

Inventories / shop systems / character selectors all contain elements of:

  • a database of items that you may possibly possess / equip
  • a database of the items that you actually possess / equip currently
  • perhaps another database of your “storage” area at home base?
  • persistence of this information to storage between game runs
  • presentation of the inventory to the user (may have to scale and grow, overlay parts, clothing, etc)
  • interaction with items in the inventory or on the character or in the home base storage area
  • interaction with the world to get items in and out
  • dependence on asset definition (images, etc.) for presentation

Just the design choices of such a system can have a lot of complicating confounding issues, such as:

  • can you have multiple items? Is there a limit?
  • if there is an item limit, what is it? Total count? Weight? Size? Something else?
  • are those items shown individually or do they stack?
  • are coins / gems stacked but other stuff isn’t stacked?
  • do items have detailed data shown (durability, rarity, damage, etc.)?
  • can users combine items to make new items? How? Limits? Results? Messages of success/failure?
  • can users substantially modify items with other things like spells, gems, sockets, etc.?
  • does a worn-out item (shovel) become something else (like a stick) when the item wears out fully?
  • etc.

Your best bet is probably to write down exactly what you want feature-wise. It may be useful to get very familiar with an existing game so you have an actual example of each feature in action.

Once you have decided a baseline design, fully work through two or three different inventory tutorials on Youtube, perhaps even for the game example you have chosen above.

Breaking down a large problem such as inventory:

https://discussions.unity.com/t/826141/4

If you want to see most of the steps involved, make a “micro inventory” in your game, something whereby the player can have (or not have) a single item, and display that item in the UI, and let the user select that item and do things with it (take, drop, use, wear, eat, sell, buy, etc.).

Everything you learn doing that “micro inventory” of one item will apply when you have any larger more complex inventory, and it will give you a feel for what you are dealing with.

Breaking down large problems in general:

https://discussions.unity.com/t/908126/3

The moment you put an inventory system into place is also a fantastic time to consider your data lifetime and persistence. Create a load/save game and put the inventory data store into that load/save data area and begin loading/saving the game state every time you run / stop the game. Doing this early in the development cycle will make things much easier later on.

I wanted to build my own specifically because I want it fully integrated into my game, and so I understand it. But tbh the grid part is the only truly painful bit without putting 3D objects on the physical player. Redoing the grid as a layout group is annoying though. I’ll need to rethink how I want to interact with it.

I’m mostly just uncomfortable with layout groups generally because they seem to fly apart if you look at them wrong. But I’ll use them if you think it’s best. Mostly I wanted to do it like this because it would be better on mobile if I port it to a different game. A little bit, too, because it’s a challenge. And a little bit because I’m so close to done with the inventory I can taste it. It’s not a complex one because there’s no 3D player model to deal with. Object goes to world when you click on the world. Object vanishes when you click on it and you get a sprite in your hand that follows the mouse like it owes it money. Click on a few coded buttons to put it in equipment slots. If I wasn’t doing a grid inventory, I’d be done now. That’s about it really.

Also, A 20x20 grid (about the max I’d use) contains 400 separate images. I get the feeling that’s going to eat performance for no real reason, except to make this trick work tbh. Meanwhile my previous inventory was a 32x32 tiled sprite.

Alas we humans just suck at guessing what is hard for a computer to do.

I’m no better, trust me.

That’s why I defer to the profiler but ONLY when I actually have a problem.

Otherwise, full steam ahead. Lay in the code, see how it goes. Unwritten code is useless.

Look, you need a regular grid.

You can do that yourself (two nested for() loops, the standard way)

Or you can have a component do it… you could even use the non-UI Grid Component that the Tilemap uses.

Either way you’re gonna have 400 things in view.

And they have to be regularly positioned.

The only OTHER way is to hand-position them yourself in the editor.

And you don’t want that.

Well, tbh, I’ve done some benchmarks and I think that it does eat extra memory. Not a lot, but I’m trying to design my game with crummy laptops in mind. But anyway I’ve managed to adapt my current system to work with it. Objects are now going where I want, so there’s that I guess. Thanks for your help.