Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

SpriteTile, a fast dynamic tile system (RELEASED)

Discussion in 'Assets and Asset Store' started by Eric5h5, Dec 11, 2013.

  1. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's correct.

    --Eric
     
  2. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    I'm looking to change my tilemap process from 2D Toolkit's mesh based system to a sprite renderer based system and SpriteTile looks to be just the thing but I have a few questions.

    1) My game currently uses gameobjects with tags to identify specific tiles. Can I set individual sprite tags?

    2) I have a tilemap and a corresponding normal map. I currently use the standard unity shader to get somewhat realistic lighting in my levels but is it easy to implement the same system in SpriteTile?

    I'm hoping that these are easy to set up as SpriteTile looks pretty great.
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    1. No, but there is a trigger system where each tile can be assigned a number, which may work depending on what you're doing. There are functions like GetTriggerPositions, and you can use enums for the numbers to make code more readable.
    2. There's a discussion about normal maps here.

    --Eric
     
  4. jameskyle

    jameskyle

    Joined:
    May 7, 2013
    Posts:
    37
    Thanks. I'm not sure if SpriteTile is right for my current project but I can definitely see myself using it at some point.
     
  5. journeyman

    journeyman

    Joined:
    Mar 19, 2013
    Posts:
    7
    Hi Eric! I think I've found a bug that prevents saving .bytes files.

    1) When i open a .bytes file I previously saved, and then save it again, an invalid savepath gets generated, an exception is thrown in the console window, and nothing gets saved.

    I sent you a PM with the download for the example project that shows the error, can you please let me know if you see this behavior too?

    Reproduction steps:
    - open tilemap_one_layer_only.bytes
    - press "save as" and either leave the filename the same or change it, the behavior is the same.
    - notice a DirectoryNotFoundException gets thrown in console (the save path is invalid, it has the filename twice at the end)

    The trouble is, the same thing happens when I first import a .TMX file and then try to save it as a .bytes file.

    For myself, I hacked something into FileIO.js quickly to remove the duplicate "something.bytes" entry in the savepath, but I guess you'll want to fix the problem at its root, hence my bug report.
    http://pastebin.com/KEVvbg4L
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I followed the repro steps but don't get any error. I would guess this is probably the same thing that happened to another user on the previous page, and though I also wasn't able to reproduce that, I made a change for the next version which solved it for the user.

    --Eric
     
  7. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Hello Eric

    I have had a really easy time implementing SpriteTile so far, I would just like to make a wish for another feature that would be great.
    I wrote up a quick A* Pathfinding system to work with SpriteTile and would like something like Tile.isRendered, to use in the pathfinding. So that the player can't find paths using tiles outside the camera.

    Is this something you would be willing to implement?

    //Mcwool
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I haven't tested it, but if you put this in the Tile.cs script, it should hopefully work:

    Code (csharp):
    1. public static bool IsRendered (Int2 p, int layer, int camera) {
    2.     return (p.x >= tileLayers[layer].pLowerLeft[camera].x && p.y >= tileLayers[layer].pLowerLeft[camera].y && p.x <= tileLayers[layer].pUpperRight[camera].x && p.y <= tileLayers[layer].pUpperRight[camera].y);
    3. }
    --Eric
     
  9. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Thanks a lot for the fast reply, haven't had a chance to implement it to the .dll yet but I'll let you know how it turns out.

    //Mcwool
     
  10. bitbiome_llc

    bitbiome_llc

    Joined:
    Aug 3, 2015
    Posts:
    58
    Is there a way to fully unload SpriteTile from a scene? EraseLevel leaves a number of game objects that persist into another scene.

    I don't really care for those objects persisting into scenes where they are no longer needed. Removing them manually of course throws and error if I attempt to load a new level as SpriteTile has a cache of those objects.

    Is there a way to clear the cache? Is the speed of loading a new level later worth keeping those objects hanging around in scenes that don't make use of them?
     
  11. Nanofus

    Nanofus

    Joined:
    Sep 27, 2012
    Posts:
    12
    Hi, and thanks a lot for the tool! However I'm having trouble actually using it; when I run a scene with a level in it, the tiles do not appear. The gameobjects are there, but with disabled SpriteRenderers, and they don't appear even if I enable them. I can, however, detect triggers through scripting, so those work.

    This also affects the included demos. When I run Acorn Antics I get a lot of warnings like this in the console:

    Code (csharp):
    1. Set 2, tile 0 doesn't exist, at location (0, 0)
    2. UnityEngine.Debug:LogWarning(Object)
    3. SpriteTile.Tile:UpdateMapData(MapData)
    4. SpriteTile.Tile:LoadLevel(Byte[], Boolean, Boolean, Int32)
    5. SpriteTile.Tile:LoadLevel(TextAsset)
    6. Manager:LoadTitleLevel() (at Assets/SpriteTile Demos/Acorn Antics/Scripts/Manager.js:80)
    7. $:MoveNext() (at Assets/SpriteTile Demos/Acorn Antics/Scripts/Manager.js:63)
    8. UnityEngine.MonoBehaviour:StartCoroutine_Auto(IEnumerator)
    9. $:MoveNext() (at Assets/SpriteTile Demos/Acorn Antics/Scripts/Manager.js:53)
    10. UnityEngine.MonoBehaviour:StartCoroutine_Auto(IEnumerator)
    11. Manager:Start() (at Assets/SpriteTile Demos/Acorn Antics/Scripts/Manager.js:48)
    12.  
    I'm running Unity 5.2.3f1.

    Thanks in advance!
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'd recommend using SetActive on the parent objects; having them in the scene but inactive won't have any negative effects.

    The camera needs to be positioned where it can see the tiles. You can use the preview function in the editor to help with this if necessary.

    You apparently altered the tile sets, so set 2, tile 0 doesn't exist any more. It would be best to import the demos into a separate project if you intend to change the tiles.

    --Eric
     
  13. bitbiome_llc

    bitbiome_llc

    Joined:
    Aug 3, 2015
    Posts:
    58
    Thanks. That should work I suppose.
     
  14. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Hi again, haven't been able to implement the IsRendered bool into the .dll, could switch to source i suppose, but i rather not. Any chance this will be implemented in next update?

    //Mcwool
     
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It probably will, but I'm not sure when that will be.

    --Eric
     
  16. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Ok, thank you. I'm in no hurry at the moment.

    //Mcwool
     
  17. Eric-Gu

    Eric-Gu

    Joined:
    Feb 19, 2014
    Posts:
    28
    Hi, Eric. I want to know something about performance issue. If I create too many layers in the level, such as 7, with the size 20x20 for each layer, Will that affect the performance? What the maximum number of layers do you recommend?
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It depends on how many tiles are actually used, how many are on the screen (size of tiles), what the target hardware capabilities are, etc. So I can't effectively give any specific recommendations; you'd need to test it to see.

    --Eric
     
  19. BreadWeek

    BreadWeek

    Joined:
    Aug 12, 2014
    Posts:
    45
    I updated to SpriteTile 2.12 and when I even hover over the SpriteTile Editor I get this constant error:

    DivideByZeroException: Division by zero
    TileControls.SetupTileCountControls ()
    TileControls.TileControls ()
    TileEditor.OnGUI ()
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)


    I've since tried deleting and re-importing everything related to Sprite Tile with the same results. Am I missing some obvious instructions for updating/installing in the docs?
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You could try this: use the source, and in the TileControls script, in the SetupTileCountControls function, before this line:

    Code (csharp):
    1.     Label ((32768 / System.Convert.ToInt32 (setCount)).ToString());
    insert this code:

    Code (csharp):
    1.     if (setCount == 0) {
    2.         setCount = 32;
    3.     }
    Logically it should never be possible for setCount to be 0, since the value is derived from an EnumPopup (plus the TileEditor script also runs the above code on startup just in case), but that's the only thing that could somehow be dividing by 0.

    --Eric
     
  21. BreadWeek

    BreadWeek

    Joined:
    Aug 12, 2014
    Posts:
    45
    Thank you, that does allow me to use the Tile Editor and set the layer names. But now when I run Unity simply crashes with no report. Upon opening Unity I get this error a good 54 times:

    FileNotFoundException: Could not load file or assembly 'SpriteTile, Version=1.0.5694.27359, Culture=neutral, PublicKeyToken=null' or one of its dependencies.

    It feels like something more than Sprite Tile may have gone wrong but I can't imagine what and the issue only appeared when updating.
     
  22. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Unfortunately I have no idea, and can't reproduce that. Maybe start a new project and move things over.

    --Eric
     
  23. BreadWeek

    BreadWeek

    Joined:
    Aug 12, 2014
    Posts:
    45
    EDIT: It seems fixed now. I had previously called NewLevel, then AddLayer, then LoadLevel. The AddLayer step appears to be causing a problem when I would load the level (and regardless, I believe NewLevel and AddLayer are pointless if I'm loading the level anyway... old code). This was going from 2.8 to 2.12.

    ---

    Well, re-importing all of my assets and using the source with your suggested edit has worked for the most part, I'm able to run now. But calling LoadLevel (on all levels, old and new) gives this error:

    Error loading file: Argument is out of range.
    Parameter name: index
    UnityEngine.Debug:LogError(Object)
    SpriteTile.Tile:LoadLevel(Byte[], Boolean, Boolean, Int32) (at Assets/Plugins/SpriteTile/Tile.cs:1435)
    SpriteTile.Tile:LoadLevel(TextAsset) (at Assets/Plugins/SpriteTile/Tile.cs:1163)


    And later calling NewLevel gives this error:

    ArgumentOutOfRangeException: Argument is out of range.
    Parameter name: index
    System.Collections.Generic.List`1[System.Collections.Generic.List`1[System.Collections.Generic.List`1[UnityEngine.PolygonCollider2D]]].get_Item (Int32 index) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
    SpriteTile.Tile.DeleteLevelColliders () (at Assets/Plugins/SpriteTile/Tile.cs:1152)
    SpriteTile.Tile.DeleteLevelObjects () (at Assets/Plugins/SpriteTile/Tile.cs:1647)
    SpriteTile.Tile.NewLevel (SpriteTile.LevelData[] levelData) (at Assets/Plugins/SpriteTile/Tile.cs:1564)
    SpriteTile.Tile.NewLevel (Int2 mapSize, Int32 addBorder, Single tileSize, Single zPosition, LayerLock layerLock) (at Assets/Plugins/SpriteTile/Tile.cs:1522)


    There was also briefly an issue with SpriteTile giving warnings about tiles from Set 4 not existing when I don't even have a set 4, but saving my level under a different name and using that made those warnings disappear.

    I'm sorry for the trouble, thank you for your help.
     
    Last edited: Dec 12, 2015
  24. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Hello Eric

    Im having some problems when loading a .bytes file that I have saved at runtime.

    When something in the world changes i run this.

    Code (CSharp):
    1.         var currentMapBytes = Tile.GetLevelBytes();
    2.         File.WriteAllBytes (Application.persistentDataPath + "/myCurrentWorld.bytes", currentMapBytes);
    and in awake i run this.

    Code (CSharp):
    1.         if (File.Exists (Application.persistentDataPath + "/myCurrentWorld.bytes")) {
    2.             var myCurrentWorldMap = File.ReadAllBytes (Application.persistentDataPath + "/myCurrentWorld.bytes");
    3.             Tile.LoadLevel (myCurrentWorldMap);
    4.             Tile.SetLayerSorting(3,"WorldObjectsOverPlayer");
    5.         }
    6.         else
    7.             Tile.LoadLevel (worldMap);
    But upon entering the scene from another scene that is using SpriteTile, I get this. (When entering from a scene that isn't using SpriteTile it works as intended)


    Error loading file: Argument is out of range.
    Parameter name: index
    UnityEngine.Debug:LogError(Object)
    SpriteTile.Tile:LoadLevel(Byte[], Boolean, Boolean, Int32)
    SpriteTile.Tile:LoadLevel(Byte[])
    WorldTilesManager:Awake() (at Assets/Scripts/WorldTilesManager.cs:96)

    ArgumentOutOfRangeException: Argument is out of range.
    Parameter name: index
    System.Collections.Generic.List`1[System.Int32].set_Item (Int32 index, Int32 value) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:639)
    SpriteTile.Tile.SetLayerSorting (Int32 layer, System.String layerName)
    WorldTilesManager.Awake () (at Assets/Scripts/WorldTilesManager.cs:97)

    ArgumentOutOfRangeException: Argument is out of range.
    Parameter name: index
    System.Collections.Generic.List`1[System.Int32].get_Item (Int32 index) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
    SpriteTile.Tile.SetTileObjects (Boolean update, Int32 layer, Boolean cameraChange)
    SpriteTile.Tile.AddLayer (SpriteTile.LevelData levelData)
    SpriteTile.Tile.AddLayer (Int2 mapSize, Int32 addBorder, Single tileSize, Single zPosition, LayerLock layerLock)
    WorldPlayerMover.Start () (at Assets/Scripts/WorldPlayerMover.cs:76)

    ArgumentOutOfRangeException: Argument is out of range.
    Parameter name: index
    System.Collections.Generic.List`1[System.Collections.Generic.List`1[SpriteTile.SpriteCached]].get_Item (Int32 index) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
    SpriteTile.Tile.MoveTileCamera (Vector3 translation, Int32 camNumber)
    SceneManager.LateUpdate ()

    Any ideas what I'm missing? Tried using EraseLevel before leaving the previous scene, and just before loading the new level.

    /Mcwool
     
    Last edited: Dec 17, 2015
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I tried that and it works fine here, so I'd need more info, or you could send me a project where it happens.

    --Eric
     
  26. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Im trying to reproduce it in another project but somehow it doesnt happen.

    All I know so far is that if i remove Tile.SetCamera(); from the scene Im leaving. It works perfect.

    I will get back to you as soon as I can give you more info. If anything cross your mind to what you think I might have messed up, Im all ears.

    //Mcwool
     
  27. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Thought I share whats up with this issue. Setting the layers from the scene I was leaving to the same as the one I am entering and removing any tempering with the layers during runtime fixed the problem. So I'm just leaving it there for now.

    //Mcwool
     
  28. dasbin

    dasbin

    Joined:
    Jan 14, 2012
    Posts:
    261
    Scene preview seems to be buggy: it doesn't seem to apply tile rotations/flips to the preview, and it also *sometimes* seems to be able to create multiple copies of the preview GO without considering if one is already in the scene.
     
    Last edited: Jan 1, 2016
  29. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Use Tile.LoadLevel to load a SpriteTile level. I'd recommend looking at the demos to see how they work. The preview does rotated tiles, but you're right about flipped tiles; I'll add that to the next version.

    --Eric
     
  30. DugelStudios

    DugelStudios

    Joined:
    Feb 21, 2015
    Posts:
    92
    Is it possible to tile GameObjects/Prefabs? I have a script that I want to attach to each individual tile.
     
  31. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, sorry. Tiles exist only as a few bytes in RAM, and don't have GameObjects (except for display, but the GameObjects aren't tied to any particular tile, and will change as the camera moves).

    --Eric
     
    DugelStudios likes this.
  32. Nixaan

    Nixaan

    Joined:
    May 30, 2013
    Posts:
    118
    Hi,
    Is there a way to offset the preview? On runtime I offset the grid (on both x and y) by +1/2 cell and this makes the preview to be displayed off to where the level actually is.
     
  33. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You'd have to offset the parent object that the preview objects are under (manually).

    --Eric
     
  34. Nixaan

    Nixaan

    Joined:
    May 30, 2013
    Posts:
    118
    I thought about that but its position is reset on every preview. That makes using it pointless for me because correcting each time is slower than just keeping in mind the offset, or entering the coordinates in the inspector straight after checking the corresponding cell coordinates in Spritetile editor.

    Is it possible to point me to where in code i can hardcode the offset?
     
  35. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    In the TileEditor script, in the ShowEditorPreview function, after the line

    Code (csharp):
    1. previewContainer = new GameObject("TileEditorPreview");
    you could set previewContainer.transform.position.

    --Eric
     
  36. Nixaan

    Nixaan

    Joined:
    May 30, 2013
    Posts:
    118
    Thanks a lot, now its perfect.

    Actually it was slightly different. At first nothing changed because tiles were populated after the change of the parent's position. So they were still placed at their original world positions. Then I moved it to being the last line of the function, just after the tiles population loop, and it worked.
     
  37. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Ah, good point.

    --Eric
     
  38. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    I'm having low frame rate issues with using a single point light and SpriteTile. Attached is a screen shot. It's just using 1 point light attached to the camera. The screen is filled with 2 screen width 16x16 pixels tiles, which I reset back to x = 0 to make the scroll continuous. But as you can see I'm getting 18fps, which can't be right, or maybe it is, I've not used lights in Unity yet, so is that just how slow things are when you use lights? or is there something wrong? Any ideas?

     
  39. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Look at the profiler and see where the slow-down is coming from.

    --Eric
     
  40. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    This is what the profiler is showing.

     
  41. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Look under Camera.Render, since that seems to be using the most time.

    --Eric
     
  42. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    Here's an expanded view of the profiler for Camera.Render, i've got non-transparent ticked for the tiles that are being displayed as well.

     
  43. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Since it's mostly in Render.TransparentGeometry, you can expand that to see more details. But in general try to use less transparency, such as using "tight" for the sprite mesh type, rather than "full rect".

    --Eric
     
  44. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    I've expanded it some more, not sure if that helps narrow down the issue. How do I change the sprite mesh type? can I set this in the editor for the tileset that it's using?

     
  45. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Change the mesh type in the Unity import settings (for each sprite).

    --Eric
     
  46. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Hello

    Will SceneManager change name in coming updates? I was just thinking due to unity's new "SceneManager" replacing "Application" in 5.3.

    //Mcwool
     
  47. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, there's no need for any changes.

    --Eric
     
  48. BusyRobot

    BusyRobot

    Joined:
    Feb 22, 2013
    Posts:
    148
    I've found the mesh type setting, it was already set to "tight", anything else I can do to improve frame rate?
     
    Last edited: Jan 14, 2016
  49. mcwool

    mcwool

    Joined:
    Jan 8, 2014
    Posts:
    14
    Ok, I'm probably missing something then. When i try to use "SceneManager.LoadScene" it doesn't find it, and i assumed that was because it tries to use ur "SceneManager" instead.

    I can do a workaround by using "UnityEngine.SceneManagement.SceneManager.LoadScene" but it would be nice to just have "using UnityEngine.SceneManagement;" then use SceneManager.LoadScene directly.

    //McWool
     
    Last edited: Jan 15, 2016
  50. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If it's taking that long to render transparent geometry, then it's pretty much up to the GPU/drivers/shaders. Possibly you could write a custom shader that's a little faster.

    I see; when using Unityscript there aren't any issues. For C#, I could put SceneManager in the SpriteTile namespace, but you'd still need to disambiguate if you're importing both SpriteTile and UnityEngine.SceneManagement namespaces.

    --Eric