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

Question A few questions on TileMaps

Discussion in '2D' started by tgrim991, Jul 18, 2023.

  1. tgrim991

    tgrim991

    Joined:
    Feb 22, 2023
    Posts:
    14
    Greetings.

    First, let me thank you guys for making RuleTiles and the other 2dExtras open-source. :)
    • My first question is in regards to RuleTile's random functionality. It seems when ever the domain is reloaded, and other instances I haven't been paying attention to, these tiles will reset and re-randomize. Is there a way to prevent this? I don't think disabling reload is feasible and even then, I think I've caught it happening in other circumstances. It kind of makes it impossible to toy with the settings on the rule tile until you get a layout you like. I've seen a post, I can't remember what it's called, but someone from Unity I believe suggested added a boolean check against Application.isPlaying on RefreshTile. However, the application is not in play mode during reload and from a brief observation using break points, it doesn't seem to be RefreshTile that is being executed. It looks like it's StartUp, but I didn't dig much deeper simply because I'd like to knock out the core functions before spending a large amount of time on something that is essentially just bothersome because I guess I'm a little obsessive. So essentially I'm hoping someone more experienced than I can shed some light on this and save me some time. Ideally, this would only happen when painting tiles, I would imagine? But I'm sure there's things I'm not aware of as I've only recently begun using 2D and it may just be my ignorance. As I'm not sure of its purpose, and I can't go deeper than the RuleTile itself, I'm not sure how to approach this.
    • The second question is also about the RuleTile. When looking through it in order to extend it, I noticed that Math.Floor is being called on the function that obtains a value for the index based on PerlinNoise. I'm completely ignorant when it comes to Perlin, truly, so my question is what is the purpose of this? With Math.Floor rounding towards negative infinity, instead of zero, and the object to be producing an index for an array between zero and the array length, I don't quite understand why not just cast it to an int? Again, this may be my complete lack of understanding when it comes to Perlin, but the fact it's also then wrapped in a clamp function that is also from zero to the array's maximum index, I'm a little confused.
      • I'm more or less trying to better understand what the expected output might be and the purpose. You have my word this is not one of those instances where people condescend behind the veil of a question. <3
    • Thirdly, I seem to be unable to get an empty TileMap to match the bounds of another TileMap using ClampToBounds (https://docs.unity3d.com/ScriptReference/BoundsInt.ClampToBounds.html)
      • Essentially I have an empty TileMap that overlays the TileMap with content in order to be able to display a sprite on top of a cell when it's been selected. However, when taking the BoundsInt from the populated TileMap and using ClampToBounds on the empty one, I've attempted to call ResizeBounds on the TileMap after using ClampToBounds, This does not change the values of the TileMap's bounds.
      • This does not seem to matter in terms of placing new tiles on top of it, as I'm able to add tiles to cells that aren't within the bounds of the TileMap used as an overlay, but my concern was the ability to select cells that were not within the TileMap with content's bounds. This functionality also leaves me wondering what determines the empty TileMap's bounds as when I run CompressBounds on the one with content, it does not change, leading me to suspect that it's bounds are automatically sized based on the tiles that exist at Start and only need to be compressed after tiles have been removed and possibly added.
        • I'm sure this is my lack of experience with the architecture of TileMaps, but I don't quite understand why we'd be able to place tiles outside a TileMap's bounds? I figure I can just check if the bounds contains the cell's position, but I'm just trying to understand the why so I can better understand the intentions behind the bounds.
    • The last one will probably seem pretty silly, but I noticed that the localBounds were stored as Vector3 as opposed to Vector3Int like the others. I'm kind of just curious as to why, what are its intended functions? This may seem irrelevant, I know, but the more you know..
      • That being said, if anyone is willing to share with me instances in which they've used local cell positions, that would be great. I know I'm going to look really dumb.. It kind of confuses me. I'm assuming this is required for instances in which a grid's center is not actually the center of world space. However, and maybe I'm misunderstanding this, but it appears we can select cells with world space, so I'm curious about when this would have to be used. I know.. judge not!
     
    Last edited: Jul 18, 2023
  2. venediklee

    venediklee

    Joined:
    Jul 24, 2017
    Posts:
    143
    Make no mistake, it is not open source. It is under Unity companion license https://github.com/Unity-Technologies/2d-extras/blob/master/LICENSE.md <- from their old github repo

    They only re-randomize if you change the count of random sprites in a rule tile. This is the only non-editor place random output is used and you can clearly see and rationalize why it would re-randomize
    upload_2023-7-18_20-10-40.png
    (sorry for the small text, line was too long)

    I am assuming you are talking about the line I pasted above. I also thought the final clamp was extra until I saw this: upload_2023-7-18_20-19-44.png
    They could clamp the result inside the GetPerlinValue method or just(lol) fix the Mathf.PerlinNoise but it is what it is

    Clamping is not supposed to increase something, it is supposed to decrease something if that thing is larger than given values. I don't even know what/why you are trying to use bounds, cant you just align another tilemap with the main one(and increase its sorting by 1 to make sure it stay above) then just place a tile with a sprite to a cell?

    It may be because there could be sprites that don't fill the entire cell or the tilemap's tile anchor could be a float etc., but I am not sure. It doesn't really matter though imo.
    A quick reference search for cellbounds(there isn't local cell positions?) on my project shows that navmeshbuilder2d uses it to collect resources. There is a pinned thread in this forum if you want to check it out yourself
    upload_2023-7-18_20-35-2.png

    Let me know if I missed anything
     
    Kurt-Dekker likes this.
  3. tgrim991

    tgrim991

    Joined:
    Feb 22, 2023
    Posts:
    14
    Kind of new to this, so I'm not sure how to do the fancy quotes and stuff.

    For the first thing, as far as open-sourced-ness, it's my understanding that we may use and extend the RuleTile? I have noticed that intellisense sends me to a different RuleTile that is only for reference but the tile I've extended is a script in 2dExtras. From what I gather, as long as it's inside a Unity Project, this is allowed?

    (Would be really nice to have more open-sourced-ness. *cough, ScrollRect, cough*


    The map re-randomizes all rule tiles with random functionality every time the domain reloads. That's what I'd like to figure out how to stop from happening. I understand why it would re-randomize when the tiles around it change. However, when nothing on the map has changed, and I modify a script, and unity does an auto-domain-reload, all of the tiles change where they have rules with random tiles to select from.

    I understand that part, but my question pertains to the Math.Floor function, as it rounds towards negative infinity instead of towards zero. Meaning if we have a negative number, it will round down, as opposed to round up, and I don't understand why this is. That's the reason for using Floor versus other methods, it won't round negative numbers up towards zero by default. If we're looking to get no less than zero, I'm either missing something or simply don't understand something. It would seem to me, if we're looking for a value between 0 and length, rounding down when negative seems counter intuitive.

    I know what clamping is for! This was based on my assumption that the tilemap went outward in all directions until using CompressBounds and I was simply trying to synchronize one tilemap's bounds with another. What you've suggested is actually exactly what I've done. It was just my hope that if I was able to synchronize their bounds, tiles could not be placed outside the bounds. However, that does not seem to be the way it works. I'm just going to have to check if the bounds contain that tile, I suppose.

    No, it may not matter at all.. but questions like these are more about understanding what the developer who wrote them had in mind because knowing may help in ways I don't yet know, and it's not like I can acquire another's purpose through experience.

    I'm not sure what the code posted below this means in regards to the the local position, however I was getting tired of writing and probably did not explain myself well.

    Specifically, and this is just a curiosity, as I find things that seem not to matter at the time help me with architecture in the future, but I was more just hoping people would be willing to share their experiences in when they had to use
    Code (CSharp):
    1. tileMap.CellToLocal()
    in their own architectures. Not necessarily what it is or does.
     
  4. venediklee

    venediklee

    Joined:
    Jul 24, 2017
    Posts:
    143
    select a section of a message and click reply

    yes

    I tested this with a project on Unity 2023.1.04beta(2D tilemap extras @4.0.0-pre.2) with domain reload disabled and there was no change after script change. Just tested it again with domain reload enabled and there was still no change. Check the references to
    TilingRuleOutput.OutputSprite.Random
    in your unity version/2d tilemap extras package

    from the offical docs of Mathf.Floor ->
    Returns the largest integer smaller than or equal to f.
    . Please check your facts. I have never heard of a library that floors a floating point number to negative infinity, they always FLOOR it to the largest int smaller than the given float. There is also the frac method in some libraries, that gives the fractional part(non integer part, the one that comes after comma)
    floor(x)+frac(x) = x


    This is probably the easier and safer to understand(after years) method of doing things. You'll probably want to add additional rules to prevent two sprites getting placed on the same tile or preventing sprites getting placed on tiles that contain an enemy etc. in the future anyways

    Maybe stressing about what is inside a black box is just a waste of time? Are you sure it is not going to change in the future? Are you sure what you 'learnt' at this point of time is going to be correct when you need to use that 'knowledge' in the future?

    "Converts a cell position to local position space" it says exactly what it does in the docs and in the method summary. In everyone's libraries, it will literally be used for converting cell position to local position for that tilemap. Yes, you can calculate that position in many ways, but an easy one line method helps too.

    Here is a quick search on google with "cellToLocal" https://stackoverflow.com/questions...e-vector2ints-from-an-boundsint-c-sharp-unity .This one shows how 1 thing can be done in multiple ways so hopefully you'll be able to compare the options
     
  5. karderos

    karderos

    Joined:
    Mar 28, 2023
    Posts:
    376
    i assume that the logic of mathf.floor is that for example if you have a grid with negative values, you can always expect mathffloor to round to the leftmost point of the grid, whether you are in negative or positive range it will allways go left
     
  6. tgrim991

    tgrim991

    Joined:
    Feb 22, 2023
    Posts:
    14
    This is definitely occuring..
    ChangeInTiles.gif


    There's really no need to be rude or condescending, especially when you haven't checked your own facts.

    I think you're being mislead by the fact it says "the largest integer smaller than the given float"
    Pay attention to the "smaller" part next to the largest integer part. I know it can be confusing.

    https://stackoverflow.com/questions/14/difference-between-math-floor-and-math-truncate
    https://learn.microsoft.com/en-us/dotnet/api/system.math.floor?view=net-7.0

    The point of Math.Floor, in some cases is to be able to round a number down that is negative. By default, a cast will round a number towards zero which is fine if you're using a positive number. However, you are required to use Math.Floor is the number is a negative number, and you still want to round down.

    This is where my question, and confusion comes from. I'm aware the perlin value can be below zero. However, if it is below zero and we use Math.Floor, it will be rounded down to the next lowest integer value, which is the purpose of moving towards negative infinity being its target direction as opposed to zero.

    What I'm saying is that in this case, it seems we would never want this to happen as our target values are between zero and the length of (n), and that furthermore, with the clamp function, it makes it irrelevant as well. I honestly suspect if it was rewrite we could do away with the clamp function as well, but I'll look into that later and can't make that statement assuredly.

    Check out the links above, I think they'll give you a better understanding.

    If you don't know the answer, there's no reason to turn to condescension. Curiosity should be something that is valued. It's strange to me the negativity one has to prepare for when asking questions that pertain to things like this. In no circumstance is learning more about something a bad thing. I do wish it was not a black box, but is is. So is a neural network, but it's good to understand their inner workings. What changes when an activation function is a sigmoid versus a hyperbolic tangent? I'm kind of shocked that curiosity is met with such malice.

    I am perfect aware of what the function does. Again this seems to be more malice based than answer based. I was asking people to share their experiences in using it. Experience is a function of time and sharing it is helpful to others. It was my understanding this was a community in which people helped other people learn. I'm not asking you how to use it, or what it's for. I'm asking for those kind enough to share how it solved requirements in individual solutions. If you think this information is not valid either, or for some reason that other people are not worthy of sharing these things with, the perhaps I misunderstood the meaning of community or perhaps.

    @karderos
    Yeah, that's my assumption to. I'm assuming to since the arguments require positions that could be negative. The thing is, I can't figure out why rounding that number down while attempting to obtain at minimum, a zero, for the index, would be required and is then completely made irrelevant by the fact it's clamped to a value no less than zero. I'm sure the Perlin value can of course return a negative value.

    Thanks for your insight. :)
     

    Attached Files:

  7. venediklee

    venediklee

    Joined:
    Jul 24, 2017
    Posts:
    143
    Have you checked the references to
     TilingRuleOutput.OutputSprite.Random
    in your project(the gif doesn't show the unity version)? It probably has been fixed in the newer versions, I am not getting different outputs when domain reloads.

    I wasn't trying to be rude or condescending, apologies if it seemed that way, stating that "Mathf.Floor rounds towards negative infinity instead of towards zero" seemed wrong, and you said it in two different replies. I now understand you meant it 'directionally' which is a non-orthodox way of saying what floor does. I understand truncate has direction
    I have checked both the mathematics library and the mathf class, they were both the same description, no 'directionality'

    Truncate could work but since we or they don't know what exactly the output of the perlin noise will be at different versions of the software/package, it is a safer way to just clamp between [0,random sprite count). Will the compiler produce a different output if truncate was used? Idk. Would it make a huge difference? I don't think so. Would unity try out your feedback if you open a feedback thread showing the results of your performance test? Probably. Everyone would be thankful btw!

    I was just asking questions to make you your own judge.

    Honestly I don't know why you think it is negativity/malice/condescension when someone asks you rhetorical questions or tells you some insignificant detail doesn't matter.

    (Correct me if I am wrong) That is within your control, not a black box that can change from one version to another of a 3rd party tool.

    And I said that in every use case this method will be used for what it describes. I even gave a link to an answer that showcased its use compared to other, similar methods. This isn't a broad topic where you can use your learnings in quite different ways; if a hammer exists, it will be used for hammering not as a nail in some situations. If cellToLocal is used somewhere, it can't be something different other than converting cell to local space.

    If you still want additional concrete real world examples of that specific function or any other function post a new thread with that title, you'll have much better chances of finding someone who used it

    -----

    Heyo @Kurt-Dekker could I bother you for your input on the post above, I am sure your experience would be more valuable for everyone. Thank you for your time
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Hey vend, love to but there is so much going on in the massive walls of text above... could someone just summarize what the remaining behaviour is??

    I haven't used Tilemaps a lot, but everything I have done with them worked perfectly according to the documentation, with the single exception that the .z value of Vector3Int coordinates had unexpected behaviours on certain grid rendering modes, IIRC.
     
  9. venediklee

    venediklee

    Joined:
    Jul 24, 2017
    Posts:
    143
    Honestly, it is hard to summarize, I'll try

    1. tgrim asks for a concrete example when people *had to use* this specific method of tilemap class. I told tgrim
      and gave a direct link to stackoverflow where they use it along with other options, but tgrim thinks that was condescending. Do you have a piece of code you could share for tgrim? Also was I condescending? Could cellToLocal could be used in any other way than converting cell to local space?
    2. tgrim asks why some place of tilemap script uses Vector3 instead of Vector3Int. I said something like it could be because of half sized tiles or tile anchor not being int. I added that it doesn't matter. Tgrim said yes but knowing may help him/her in ways s/he doesn't know yet. I then said
      .Tgrim says "If you don't know the answer, there's no reason to turn to condescension", "It's strange to me the negativity one has to prepare for when asking questions that pertain to things like this", "I'm kind of shocked that curiosity is met with such malice." . Do you think I sounded malicious or uninformative?
    3. Tgrim essentially asks why did Unity not use truncate instead of flooring and clamping between [0,n) for the code above; I said this ->
      Do you think changing floor+clamp to truncate matters for performance, usability etc.?
    Thanks again!
     
    Last edited: Jul 20, 2023
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    I don't...like I say, I've only barely scratched Unity tilemaps. I tried some procgen with tilemaps a few years back and it all worked as expected, I set it aside because a) we don't use tilemaps at my workplace, and b) I prefer 3D stuff when working on my own doodles.

    I don't know how to reason about performance except through the profiler and gross A/B testing on target hardware.

    Also, choosing a different data conversion algorithm may cause your output to be different for certain inputs.

    In the general sense, reasoning about these differences should be obvious from the documentation.

    In a practical sense, it may not be obvious because you don't necessarily have insight into how to varying output gets consumed by the next step of the process, such as being used as coordinates.

    My only defense against this type of confusion is just diligent debugging.

    That's why they pay me the big bucks to find the big bugs! :)
     
    venediklee likes this.
  11. tgrim991

    tgrim991

    Joined:
    Feb 22, 2023
    Posts:
    14
    I literally just upgraded to 2022.3.4f1 because it's the latest Lts. Not sure, I don't want to upgrade any further and it would be helpful if we could find the cause of that as opposed to just having to upgrade because that can be a huge pain in many cases.

    My apologies I guess but Math.Floor does indeed round towards negative infinity. However, even telling me you didn't understand what I was saying because it was 'unorthodox' seems like you're still putting it on me. That's what Math.Floor does, it rounds towards negative infinity and that's a very common way of explaining it. It is strange when you tell me to check the documentation and tell me it's not condescension and then tell me I'm explaining what a function does wrong. I guess it's a matter of opinion, but you can find plenty of people explaining Math.Floor..

    https://www.mathworks.com/help/matlab/ref/floor.html
    https://learn.microsoft.com/en-us/dotnet/api/system.math.floor?view=net-7.0
    https://stackoverflow.com/questions/14/difference-between-math-floor-and-math-truncate

    Telling someone to read the documentation, implying they haven't, is being condescending. Especially when then to defend yourself to say I worded it in an unorthodox manner when it's worded like that.. everywhere.

    So, I'm not sure how it's unorthodox.

    See links above.

    I'm not sure. I highly doubt that there's many API's that allow you to change the activation function per neuron.

    However, this was more of an attempt to explain how knowing things about how a black box functioned could be beneficial and you answer seems to be an attempt to side skirting the issue I actually have, which is the way you deemed my questions pointless and not worth asking.

    Then we get into the summarizing of what I said.. please do not put words in my mouth.

    I never asked why they did not truncate instead of using Math.Floor because it would be more performant.

    Lastly, if I can't ask general questions about the purpose of things, the reason behind things, or hope other are willing to share their experience as it's a function of time, I'm not sure the purpose of this while forum thing.

    I guess the mind state of stack overflow has infected everyone. I guess I asked the wrong questions.

    For those of you that are going to as someone else to summarize what I wrote and put words in my mouth,

    TL;DR

    All I wanted to know was:
    1.) Is there a way to keep these tiles from rerandomizing after every domain reload
    • I'm using the latest RuleTile that comes with the package manager via unity, it still happens.

    2.) The purpose of Math.Floor in an instance where we do not want a negative number AND are inside a clamp function (both of which now seem pointless, but I never said anything about performance).

    3.)The function "ClampToBounds" seemed to have no effect on an empty map and my hope is that it would synchronize its size without another map's bound. It's not as if Unity does not have a history of poorly named functions and/or lack of documentation...

    4.)To understand why we could draw tiles outside a map's bounds, and this was wondering what the purpose of these bounds were

    5.) As for the last one, it was simply an innocent curiosity as to ask other's if they had examples in which they had used local space as opposed to world space in their projects. If we're not here to share our experiences and rather ridicule other for not knowing every application this could be used in, and shame others for wanting to know more about a subject, then I'm not sure what to say.

    Jesus, Christ, Almighty. All that, still no answers..

    "Does that even matter?" and "You asked It wrong" and "It's your fault I didn't understand"

    Stackoverflow has come a long way.

    And no, I'm not proof reading. Time, tick, tick, tick
     
    Last edited: Aug 12, 2023
  12. tgrim991

    tgrim991

    Joined:
    Feb 22, 2023
    Posts:
    14
    upload_2023-7-20_18-40-23.png

    For the sake of being as transparent, this is the package version.

    I would still think it would be nice if we could have an area in which people shared their usages of functions.

    And I don't specifically mean for the Grid's local position functions, I just mean in general. I ask about that function in particular, just looking for idea, truthfully. Never know when a lightbulb may hit!

    You get better by reading other people's code. :) Well, sometimes.. :confused:
     
  13. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    I did a quick test of this and the RuleTile does not re-randomise after a domain reload unlike your example. If you could file a bug report with your Unity project and post the case number here, we can check this out!

    I suppose using Truncate would be fine as well. I believe that there was a possibility that after flooring or truncating the result from PerlinNoise * Length of Sprites would still result in a negative number that still required clamping of the values. If you have suggestions on improving this, do let us know!

    This function sets the calling bounds to the intersection of calling bounds and the given bounds. Calling it with an empty bounds (of size 0) would still produce an empty intersection. If you wish to synchronise the bounds or a Tilemap with another, you could set the origin and size of the Tilemap with the values from the other Tilemap and then call tilemap.ResizeBounds() to ensure the contents are within the new origin and size.

    If you draw tiles outside of the current bounds, we would extend the bounds of the Tilemap itself. We do not explicitly limit painting/setting of Tiles within the set bounds.

    The cell coordinates may not correspond with the actual local space or world space coordinates used by GameObjects. This could be affected by the Grid's cell size/gap/layout or the Tilemap's transform (position, rotation, scale). An example would be using a default Hexagonal Point Top Grid. Any cell coordinate with a Y value other than zero would not map to the same Y value in local space, since the cells are staggered.

    Methods for converting between cell to local to world are provided to aid in this, in case the actual cell coordinates to do align with the local or world coordinates.

    If I missed out other queries from this long thread, do let us know and we will try to answer!
     
    tgrim991 likes this.
  14. tgrim991

    tgrim991

    Joined:
    Feb 22, 2023
    Posts:
    14
    1. ) I'm going to do some experimentation before I decide whether or not to bother you guys with a bug report, it may not be a bug at all and just something I did.
    2. ) I was not complaining about the Math.Floor function being "inefficient" or that it needed to be changed, I simply was curious as to the usage due to its behavior. If the randomization using the perlin value does indeed generate a random number, why would we want to round a negative number down, when we want no less than zero? Then there's the fact it's inside a clamp function. This is not me trying to school you or something, I know how things can be around here, this is not the case. I'm really just trying to learn about this system.
    3. ) As for the clamp to bounds, that was simply my misunderstanding, I was honestly just hoping I could use another map's bounds to clamp it. But I get it now, thank you.
    4. ) Makes sense, otherwise it would require resizing it every time you wanted to add a time outside of the bounds. My first thought when I heard bounds is like.. "a size limit" - which it is not in this case, it is purely a measurement. Thanks for clarifying that.
    5. ) This one seems to just be a lack of my experience, it's my first go with 2d. Thank you for the example.
    My apologies for the long-ed-ness of the thread, I do tend to write a lot. I'll try to keep questions to one-per-thread from no on. I'm a bit of an old dog, I guess when it comes to forums, where we used to write just to write to for whatever reason that may be.

    Then again, I am the type that will watch a useless twenty-minute youtube tutorial and come out with one useful detail and consider it a success due to the availability of quality information these days.

    Thanks again, @ChuanXin
    I assure you this isn't one of the cases in which someone is taking out their frustration on the people who made the tool they never could. <3