I’ve been trying to get this to work for a while now without luck. So was hoping I could find some help here on the forums.
What am I trying to do?
I’m making a randomly generated map, and using randomly generated instanced static meshes to create the map. I then need to be able to click on any of the multiple different meshes and get it’s index/location in the array.
Whenever I select a mesh, I get back the index of just that mesh type.
Example: Spot 1-10 is generated. 1-3 is blue and 4-8 is green and 9-10 is blue. If I select the first green tile I see, it will give me an index of 0, instead of 3. If I select 2nd blue tile I get 1 which is correct. If I select Tile number 9 i’ll get 3 instead of 8.
Sorry if this is hard to understand, is quite hard to explain.
Anyone know how I can go about to get the correct results?
So first, keep an array that is indexed to match your grid. Lets say the first column is 0 through 9, the second is 10 through 19, and so on. You know that clicking on the bottom corner tile will always give you index 0, the top corner 9, and so on. Then, for every array that needs to hold map data, ensure they all match your data structure. For me, that looks like this:
I have a few dozen arrays that hold every bit of information about the map. 1 for temperature, 1 for precipitation, etc.
So you could keep arrays with the Instance Type(Green), and its reference Index.
Spawn an invisible collision mesh at every tile that is the same size as your instances, and is indexed in the same way as the rest of your map data.
When you click your map, you hit your collision volume, break hit actor, find hit actor in the actor array, get that actor’s index, and then use that index to get any information about that tile you need.
Thanks Zeustiak, I will try to set this up later tonight. I see where I was going wrong, I was using the same array that generated the tiles and breaking the hit from that. But once I setup the collision grid I will be able to get the correct tile. So glad you went through and already figured out so much for your map ha. Thanks a bunch!
I’m trying to solve the exact same problem and this is the only discussion I’ve found on this topic! I don’t really understand what you mean though, so clarification would be much appreciated.
In short, I’ve created a grid by adding instances of an instanced static mesh. I then save the vector and any other information I need in an array. When pressing the tile, I get the instance index which I used to grab the correct information from the array I created. From there I can now map/access everything I need and it’s all good.
However, I want to use two different materials, let’s say odd and even tiles. I’ve created 2 instanced static meshes to handle this and the grid is created fine. However, the odd and even tiles are indexed separately, ie first tile is 0, second also 0, third is 1, fourth also 1. This instance index is the only information I seem to have when clicking a tile, and unfortunately it’s not enough to determine which item it is in my array.
Your are saying to create a collision mesh. Can you explain what that means exactly? Keeping in mind I’m very new to this. I assume you mean that after adding each instance, I use the transform data and whatnot to create some sort of collision mesh which overlaps the individual tile I just created. I’m doing this in blueprints, and the only thing I could add which sounded similar was a collision box, but that takes an actor. Or are you saying to just spawn a mesh of the same type as my instanced mesh and I can then make it invisible (but still have collision)?
If you can just explain this last step in some more detail, preferably with the blueprint node I’m supposed to use, that would be fantastic. Also, if I spawn a “collision mesh” for every tile, would that impact performance? Or would it have an insignificant impact because it’s not actually visible/drawn? This is for mobile.
When I say collision mesh I just mean a normal mesh that is not visible. Since you keep them hidden the only cost is the memory cost associated with them being in the world which is small as long as there isn’t anything in them(blueprint logic and whatnot if they are individual actors). You can use actors with a static mesh base, but depending on what you need it is simplest to just use plain static meshes with no baggage.
In my case, I have a hexagon that matches the underlying tile but is a bit thicker and is located just above it. I also use my collision meshes for a separate visualization of map data which you see in many of my later map thread posts.
The key is to have an array of vectors that matches your instance placement. When you spawn the collision meshes you just do it in the same order as your instances so that the data structure matches.
So you click on your map, hit one of the collision meshes, get it’s name, search your collision mesh array for it’s name, get the index, and then as long as the data structure is aligned you also have the index of the instance underlying it.
Then you can store more details about what instance reference is at each index in your array because as you found out, each separate instance mesh type will have separate instance references. Basically as you spawn your instances you will want to store what reference the instance came from, which instance in the series it is, it’s vector, etc so you can selectively change instances on the fly. Just throw all the needed bits into a struct and make an array of that matching your data structure.
Alternatively you can respawn all the instances(tens of thousands) practically instantly as an interim solution. I did that for a long time because it was more convenient when I set it up.
Cool, so basically just spawn the same mesh again but invisible (and in my case, probably just change z axis slightly to ensure its hit when clicking). That’s the only thing I could think of, but I was thrown by the wording, thinking something clever already existed thanks a lot for the quick reply.