Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Discussion Ideas on how to fix my "Castle stairs" problem

Discussion in 'Scripting' started by wideeyenow_unity, Jul 26, 2023.

  1. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    In my current project I found how to create/use a Texture2D(png) to setup PlayMap configuration. So each pixel color32 can reference which tile to place(and where) when creating the play map. For instance, green = grassTile, brown = dirtTile, and black = castleWall, etc...

    I have found a way that lets a standard castle wall piece think for itself, by getting adjacent pieces, to know that a open edge requires crenulation, and when next to another wall piece to leave the connection open as floor. The conundrum I now face, is when particular wall pieces are set to a enum type of "stairs", my mind is drawing a blank.

    Here is picturization:



    So assume the far left piece, noted as "W" is standard wall, and 0-3 are wall that are now labeled as stairs. Each wall piece knows it's straight adjacent(N, E, S, W), and can easily read(or set) any variables within them.

    So I was attempting to somehow chain the stair pieces, which read off themselves to know which direction the stair(ramp) should rotate, and then set their height appropriately once knowing one end was ground floor, and the other end wall top. However, this configuration is giving me massive coders block, and the simplest way I know, is to set particular colors in the Texure2D to reference height, so then the stairs would only need to think what direction they should face to make a proper incline.

    The only problem with this, is my current color palette contains 64 colors, quarter sized containment of each RGB(0-255). And I would like to keep as many colors open as possible for additional map changes. So setting a color for each height segment of a wall piece, especially defining stairs can eat up to (4-8-12-etc...) depending on each new level(height) of floor, which I would like to avoid.

    My current attempts wind up turning into spaghettis code, and hundreds of [if] statements. And another method I thought of would make a List in each of the 4 mentioned stair pieces, which having 4 Lists of the same instances within each of the 4 stair pieces, seemed a bit non-efficient.

    So I'm wondering if anyone can think of a simplified method, just using pseudo code, as real code would take too much effort. I'm also thinking that this relevance is related to cloth physics, as each piece(vert/object) would be taking in information from 2 pieces and know one is supposed to be up, and the other down, and know to modify accordingly?

    Any help, insight, or discussions on my problem would be greatly appreciated. Cheers!
     

    Attached Files:

  2. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    It's crazy how looking at your problem stated as a question, helps you think clearer. I just realized if stair[0] seeing that its adjacent wall[w] is at a height of 8, it could easily set it's height to 6, then tell stair[1] to go down to 4, or just stair[1] seeing that stair[0] is at 6, knowing itself to go down to 4, and then other pieces follow.

    However, I'm reminded of the issue at heart, what if this was a wall[w] at a height of 8 leading up to another wall with a height of 16. It would obviously need to know to go up or down, so communication between both end pieces, as well as all the middle pieces, would need to know height of each end pieces adjacent not inclusive of stairs. And I'm right back to where I started... oof..
     
  3. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    And incase anyone asks why use a Texture2D to use as map making? A saved ".png" 100x100(10,000 units) is 234 bytes of information. And a saved ".txt" file only up to 100 lines is 1,000 bytes. So I found storing information into a ".png" as very performant and space saving. And also you can visualize the data, if creating the texture from code, and then saving into a byte array. As well as have a proper mini-map. Just.. a lot of reasons :)
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    In psychology this is called Rogerian Therapy or patient-centered therapy.

    In programming this is called explaining it to your dog. You can see me doing so in my avatar picture.

    Overall this process works remarkably well.

    So what you are doing is ultra old skool level definition and I love and respect you for it because I have done it a great deal myself.

    One handy way is to store the data for a given level as separate layers, layers that you edit in a multi-layer Photoshop (or Gimp) document and then export one layer at a time and use those colors to control your generation code.

    You might have one layer that encodes open / wall stuff, another that encodes possible stairs or doors, another layer that encodes monster starting positions, etc.

    This lets you keep the number of colors low per layer.

    You're welcome to dig around my implementation, as published in my MakeGeo project as
    Bitmap2Grid
    .

    oldskool.png

    how_it_works.png

    MakeGeo is presently hosted at these locations:

    https://bitbucket.org/kurtdekker/makegeo

    https://github.com/kurtdekker/makegeo

    https://gitlab.com/kurtdekker/makegeo

    https://sourceforge.net/p/makegeo
     
  5. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Ahhh, I see what you're saying. It would make the process a bit more complicated, but eventually I am going to need a heightMap for data on declared heights. As the castle walls, when damaged by catapults are going to lower/shrink in height, to simulate health left so when fully destroyed, they are no longer there and troops can easily walk over the rubble.

    So in my thoughts now, I have no way to save the data, if after a battle, to know what the state of everything is. Like how much stone it would take to repair walls, or time to re-dig the moats, etc... So true, I could use another texture just for height.

    mapTextureTest.jpg

    Currently I was hoping to have just one image, but the color aspect was starting to deter me, as I was hoping the data to also be the mini-map. But as you can see, 2 colors were needed for the moat, 1 to be a dirt material with no height change, and then the brown to be dirt, but with full mesh with a lower height, that moves the related verts from other tiles to make inclines appropriately. But that color difference drove me nuts looking at it.

    castleCorner.jpg

    So once it came to having higher wall pieces for the towers, gate house, or just user created designs, the process for additional colors had me stuck, lol.

    Now I do remember looking a bit into mipmaps, but I think that was for performance with rendering textures from a distance. But as far as ".png" layers, I didn't know Unity could read them, or possibly even create the data within them. So if I can't figure that out, I'll probably just have to make a data-oriented-texture height map, or maybe even a third texture for other data. Hmmm, gotta put my research cap on and do some digging, lol.

    But thanks for the heads up, that's going to make the whole thing easier on me. Cheers!
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    The more purpose you ascribe to a single thing, the harder it becomes to work with.

    This is because every purpose and use imposes risks and additional connections that must be reasoned about.

    This is why we have the Single Responsibility Principle.

    https://en.wikipedia.org/wiki/Single-responsibility_principle

    If you have a kitchen sink and a bathroom sink and a shower, you can use them for different things: washing your face, washing your hands, washing your body. If you only have one sink then your showers won't be great, you'll bump your hands on the dirty dishes, etc.

    The purpose of using a bitmap to describe a level is primarily rapid prototyping.

    If you want to take it farther into the development cycle, tech debt and tech costs will simply continue to rise.

    In the end, it's always best to do the engineering necessary, and no more, to get what you need.
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    I've always heard it referred to as "rubber duck debugging", you explain it to a rubber duck sitting on your desk. Also, trying to explain it to ChatGPT and seeing its responses is a great use of that :)
     
    Kurt-Dekker likes this.