Search Unity

UniTile - 2d Tile-based Map Editor within Unity

Discussion in 'Assets and Asset Store' started by mudloop, Jan 6, 2011.

  1. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Well, for now you could loop through the map once at startup, look for the one with the correct tile id, store the tile coordinates in a list, and then loop through that every frame to animate them.
    I would suggest keeping the group size down when animating, as it has to check and rebuild the entire group every time you call SetTile. You may even want to put the animated tiles on a separate layer with a very small group size.
    If I add an "animated tile" system, what you described is pretty much how it would work - you go to the tile's properties, and create an animation there. I could probably make it more performant than using SetTile. SetTile has to check if there's already a tile in that spot, resize the arrays, etc, but an animated tile could just change the uv coordinates, as there will always be a tile.

    As for the resizing, I'll think about adding an anchor point. If you need it urgently, you may be better off adding an editor script (like a small popup triggered by a MenuItem) that shifts all tiles to the right or upwards. You could use the API for that. I should be able to include this in the next update, but it will take at least a week as my schedule is quite full at the moment.

    And thanks for the review! I also don't know what the other reviewer was talking about, I never had any problems with U3.4 (though the latest version may not work in 3.4 anymore, but at the time of his review it did work). He could have run into a bug, but I would have prefered it if he contacted me about it first, and I would have helped him out. Oh well :)
     
  2. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    How would you go about looping through the map? I was looking at TileLayer.tiles last night before I went to bed which I suspect may help me. :)

    I may try something like that, but by all means I won't need it for weeks or even months. This is just a hobby for me and my schedule is packed as well, not to mention there's a million things my game still needs that don't depend on UniTile. :)
     
  3. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Code (csharp):
    1.  
    2. for(int i = 0; i < layer.layerSize.x; i++) {
    3.     for(int j = 0; j < layer.layerSize.y; j++) {
    4.         int id = layer.GetTileId(i, j);
    5.     }
    6. }
    7.  
    I actually found some time to do it already. If you want to test it, send me a mail at sven at mudloop dot com.
     
  4. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Coming soon to UniTile: Tile Replacer

    Draw this :



    Set up some replacement rules, press a button, and get this :




    Another example :






    This makes level design a lot faster.
     
  5. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Great stuff, can't wait to try that out. As for the anchor point I am in no dire need for that feature. I'm not going to start creating my actual map until I have some actual gameplay. :)

    Regarding your latest update, wow.

    When I watched the Vimeo video and the update date in the asset store I knew this project was a winner. :D

    However, I'm not so sure about you having this thread in the iOS forum. Perhaps it should be moved to Showcase? I mean, I'm not using it on iOS and I was a tiny bit hesitant when this was the only thread about the project.
     
  6. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Yeah, I originally posted this both in the showcase forum and here, but they locked the other thread (presumably because there were two threads about it). It seems like the Asset Store forum might be a better location though. I'll get someone to move it once the new version is released.
     
  7. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Having some issues with the "Edit tiles" option, ie. the tile properties.

    A lot of my tiles suddenly lost their collider property. Not sure exactly when it happened, but when I hit "Create objects" a lot of colliders disappeared. Prior to that I had increased the layer size, hit rebuild map, accidently hit clear layer and undo, but by doing those things again I can't reproduce it. :)

    Also, a quick question on performance. What's best between having a couple of huge layers or dozens of smaller layers? I'm making something like Zelda (http://ian-albert.com/games/legend_of_zelda_a_link_to_the_past_maps/light_world-1.png) where I have this big map with dozens of portals to smaller maps (dungeons, houses etc.)

    I was thinking I either have every map drawn on the same layers or I make a ton of smaller layers for each dungeon/house.
     
  8. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Hmm, not sure what happened here. It's the first time I heard that this happened. Some questions :
    - Are the tile properties still set to generate colliders and the gameobjects were removed, or did it change the actual properties?
    - Did you remove the .tileset file from the project?
    - Did you rename the material?


    Well, UniTile splits up the map into meshes, and from my experience, Unity's culling system is good enough to determine which meshes it should draw. So as far as I'm aware, one map would usually be enough, but in your case it would be really huge, and I haven't tested that.
    If you run into performance issues because of this, one easy solution would be to create a system that enabled/disables the group meshes based on the camera. That would be easier to maintain than having multiple maps, but should have the same result.

    Another problem may be that there could be a lot of colliders in the scene. But making different maps wouldn't help that - activating a section with all it's colliders would probably take too long.
    So if that causes any slowdown at some point, you might want to add them all to some list and disable them as needed, based on the camera. You'll probably have to add a system like that for your sprites anyway.

    Two solutions come to mind for that :
    - Use a big List or Array, and check N objects from that list every frame (I used this technique myself, but if the list is too big, some things will not be shown in time).
    - Divide the map into virtual areas of the same size as the screen, each area being a separate list (so an array of lists). There are always four areas tops that are on the screen. When leaving an area, add all it's sprites and colliders to a deactivation list, and each frame you deactivate N items from that list. When entering a new area, either enable everything, or add them to a list that also activates N items per frame.

    There may be better techniques, but that's what I can come up with. However, for the colliders it could be allright, as Unity has it's own system to determine which colliders are to be taken into account.
     
  9. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    I can't complain about the support on this plugin at least. :)

    The actual properties were changed, as in the checkbox for box collider was unchecked.

    No, but I did move it from it's original location into a folder called "Misc".

    I did change the material shader from "Unlit/Transparent" to "Transparent/Diffuse" because I wanted lighting in my game.

    Also, I just now realized I have 2 "Tilesheet.Tileset" prefabs in my project. The one I moved to "Misc", but there's also one in my "Materials" folder. And from inspecting them it seems the one in my "Misc" folder has the correct collider settings. It also contains the templates I just now realized I'm also missing. I guess that explains it.

    I just created a new Project to test it out and then it was clear as day. This all happened when I moved the .Tileset prefab. A new one gets created in the same folder as the material it's using when I create a new layer thus creating 2 prefabs.

    I just dragged the one I moved back and replaced the other one and problem solved. Thanks for the help, again and again. :)

    Guess I will make a separate "UniTile - don't touch it noob" folder for my tilesheet material and tileset prefab. :D

    I will try having just a few huge layers at first because that's by far the easiest solution to administer in the editor. Will let you know how it turns out. :)

    Edit: Well, that was easy to test. Performance in game didn't seem to be hampered by having 500x500 layers, but it's impossible to draw on those layers in the editor because it is so sluggish. I'll stick to something smaller for now and when the need for a bigger map arises (if it ever does) I'll look for a solution then. :)
     
    Last edited: Apr 5, 2012
  10. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Eureka, here's my fairly usable tile animation script. :)

    At first it made my game slow to a crawl, but then I changed the grouping of my animated layer to 1x1 and it improved dramatically. Then I made sure to only animate the tiles visible to the camera and now it actually performs acceptable. It's still a bit choppy with Vsync on though.

    Here it is in case you or anyone else is interested:

    Keep in mind it is very crude, but I'm currently just trying to make things work so I'm not paying that much attention to readability, usability and performance. :)
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class TileLayerAnimatedTiles : MonoBehaviour {
    7.  
    8.     private TileLayer layer;
    9.     private float nextFrameTime = 0.0f;
    10.     private int length, fps, currentFrame, counter;
    11.  
    12.     // Remember to put animated tiles next to eachother horisontally in the tilesheet
    13.     // so they are easier to animate
    14.     private Dictionary<int, List<Vector2>> animatedTiles = new Dictionary<int, List<Vector2>>();
    15.  
    16.     // The animation (length, framerate, current frame, current counter) of each animated tile
    17.     private Dictionary<int, Vector4> animationInfo = new Dictionary<int, Vector4>();
    18.  
    19.     void Start() {
    20.         // Hardcoded the animated tiles in my tilesheet for now
    21.  
    22.         // Campfire
    23.         animationInfo.Add(384, new Vector4(3, 6, 0, 1));
    24.         animationInfo.Add(416, new Vector4(3, 6, 0, 1));
    25.         // Small wave
    26.         animationInfo.Add(1125, new Vector4(4, 6, 0, 1));
    27.         // Small rock in water
    28.         animationInfo.Add(1157, new Vector4(4, 6, 0, 1));
    29.         // Leaf in water
    30.         animationInfo.Add(1191, new Vector4(2, 1, 0, 1));
    31.         // Big rock in water
    32.         animationInfo.Add(1600, new Vector4(4, 6, 0, 1));
    33.         animationInfo.Add(1632, new Vector4(4, 6, 0, 1));
    34.         animationInfo.Add(1664, new Vector4(4, 6, 0, 1));
    35.         animationInfo.Add(1696, new Vector4(4, 6, 0, 1));
    36.         // Shore wave
    37.         animationInfo.Add(2848, new Vector4(19, 12, 0, 1));
    38.         animationInfo.Add(2880, new Vector4(19, 12, 0, 1));
    39.         // Sea wave
    40.         animationInfo.Add(3072, new Vector4(15, 12, 0, 1));
    41.  
    42.         // Get the tile layer and find every active tile in this layer
    43.         // For simplicity I've only put animated tiles on this layer
    44.         layer = GetComponent<TileLayer>();
    45.         for (int x = 0; x < layer.layerSize.x; x++) {
    46.             for (int y = 0; y < layer.layerSize.y; y++) {
    47.                 int id = layer.GetTileId(x, y);
    48.                 if (id != -1) {
    49.                     if (animatedTiles.ContainsKey(id)) {
    50.                         animatedTiles[id].Add(new Vector2(x, y));
    51.                     }
    52.                     else {
    53.                         animatedTiles[id] = new List<Vector2> { new Vector2(x, y) };
    54.                     }
    55.                 }
    56.             }
    57.         }
    58.     }
    59.  
    60.     void Update() {
    61.         if (nextFrameTime < Time.time) {
    62.             // Loop through the different tiles types
    63.             foreach (KeyValuePair<int, List<Vector2>> pair in animatedTiles) {
    64.                 // Get the animation information about this tile
    65.                 Vector4 animInfo = animationInfo[pair.Key];
    66.                 length = (int)animInfo.x;
    67.                 fps = (int)animInfo.y;
    68.                 currentFrame = (int)animInfo.z;
    69.                 counter = (int)animInfo.w;
    70.                 // If it's time to animate this tile do so. If not, wait for the next iteration and test again
    71.                 if ((counter * fps) == 24) {
    72.                     if (currentFrame >= (length - 1)) {
    73.                         currentFrame = -1;
    74.                     }
    75.                     currentFrame++;
    76.                     counter = 0;
    77.                     // Loop through all the individual tiles for this tile type
    78.                     foreach (Vector2 vector in pair.Value) {
    79.                         // If they are visible animate them
    80.                         Vector3 viewPos = Camera.main.WorldToScreenPoint(new Vector3((vector.x * layer.tileSize.x) + (2 * layer.tileSize.x), (vector.y * layer.tileSize.y) + layer.tileSize.y, 0));
    81.                         if (viewPos.x > 0  viewPos.y > 0) {
    82.                             // Change the current tile to the next one in the animation.
    83.                             // All the animated tiles are next to each other in the tilesheet so
    84.                             // we don't have to track rows and columns
    85.                             layer.SetTile((int)vector.x, (int)vector.y, pair.Key + currentFrame);
    86.                         }
    87.                     }
    88.                 }
    89.                 counter++;
    90.                 // Store the current frame and counter for this tile type so we can keep track of it
    91.                 animationInfo[pair.Key] = new Vector4(length, fps, currentFrame, counter);
    92.             }
    93.             // Run this loop 24 times a second
    94.             nextFrameTime = Time.time + (1.0f / 24);
    95.         }
    96.     }
    97. }
     
  11. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Ok, it wasn't actually that usable. It seems it's still tied to the size of the actual layer and I don't think that's a problem with my code, but rather the SetTile() function itself? For now it seems just spawning prefabs with animation on the tiles is a better solution.

    It worked well with a 100x100 layer, but when I increased it to 200x100 it slowed to a crawl even though I didn't add any additional tiles to my animated tiles dictionary.

    I also have a feature request that I hacked into my local copy. :)

    The prefab feature only allows an x,y offset and always spawns the prefab at z = 0. I use z-space to sort my tilelayers and z = 0 is behind most of my layers. I changed the prefabOffset variable from a Vector2 to a Vector3. It gives some additional flexibility and was only a 10-second change.
     
  12. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    You have NO IDEA how long I've been waiting for someone to do this! Any word on when that feature will be added? If you do, I highly suggest also adding the animated tiles... they will be very helpful for water and waterfalls.

    I've also got a quick question... I can't seem to find where to set up collision per layer. In the demo, background layer is ignored and other layers are used for collision. It looks like all layers have the collision box checked though.

    I really like this product. I can confirm that it works with Smooth Moves. I just tested a bunch of animations in the demo. My animated sprites walk across the ground and plummet to their deaths where they should.
     
    Last edited: Apr 13, 2012
  13. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    You have to actually add colliders yourself to each tile regardless of the collision checkbox. You do this by selecting one or more tile(s) in your tilesheet and click the "edit tiles" button. Here you can add box colliders to the selected tile(s). And because this will affect all your layers you have the checkbox to enable/disable collision for this layer. However it doesn't mean what you think. There still aren't any collision in your layers. The checkbox only determines whether or not colliders will be created when you click the "create objects" button. You have to manually click this button to create colliders for your layer.

    If you want layer specific collision you can use Unity's own physics settings which has an option in the settings for collision per layer, the Unity term layer in this case, but you can use this by just adding a layer tag to each of your tile layers.

    The documentation included with UniTile explains most if not all of this.
     
    Last edited: Apr 13, 2012
  14. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    That is exactly what I needed, Twiik! I took a second look at "edit tiles" in the demo's main layer and saw that tiles settings were different than the background layer.

    I have a quick question. Is it possible to make the collision for a tile not square? For example, perhaps we could enter an X1, X2, Y1, and Y2 value? In my game I have slopes that creatures need to walk up. Here's an example:



    [UPDATE]
    I ended up using PolygonTool to create custom objects and use these as ramps. Still, I wish there was a way to have the polygon function available for selected tiles. PLEASE? :D

    I've posted a review on the app store. Love the tool and that first score was bunk. I hope you add auto-terrain and animated tiles. That would be deluxe!
     
    Last edited: Apr 15, 2012
  15. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Sorry to hear that, I will look into a better animation system when I get a chance.


    Consider it done :)


    Correct - but you can also double-click a tile in the tileset to open the tile editor.


    It's finished, I will release it this week (though I'm having some issues with the asset store, but I'll try from a different computer). The animation system is up next.


    Currently, you need to use a prefab that contains the collider (you can either script the generation of the collider, or find another way to create it - ie PolygonTool), and then assign that prefab to the tile - it will then be instantiated when you press the Create Objects button.
    I've actually started making a polygon collision editor, but it's far from complete, so it might still be a while before it's included. But for now, assigning it as a prefab will do the trick.

    Thanks for the review!
     
    Last edited: Apr 16, 2012
  16. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    I've got things running, but I ran into two small problems that might be worth fixing:

    (a) The position of the Z axis for my tile+prefab always defaults to 0 (in my game, I need this to be -31)
    (b) Even though my tiles are 32x32, when I add a prefab at 0,0, the prefab appears way off to one side. I have to manually correct it by more than 200 points. When I do this and I rotate the tile, the prefab appears way off to one side again. I suspect this is due to the size of the game object.

    Small things, but I thought you should know. First one might be an easy tweak. I know I can fix it through script, but the less scripts the better.

    [Update]
    Prefabs are working great! Thanks for the tip!
     
    Last edited: Apr 17, 2012
  17. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    UniTile 1.3.2 has been released (pending approval in the asset store).

    UniTile will be sold for $25 (that's half the price) for a limited time only - so get it while it's hot!

    New features :

    - Tile replacer
    - Improved workflow - no need to create the UniTileManager prefab
    - Cosmetic improvements
    - Custom anchor for resizing the map
    - Tile ID is now shown in the scene view
    - Added UniTile shortcuts to the "Create" menu
    - Tile selection is now remembered correctly
    - Prefab offset is now a Vector3 instead of a Vector2
    - Small bug fixes


    As of now, UniTile will only be for sale through the Asset Store. Existing customers will still get updates through email.
     
  18. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    That problem should be fixed with the new version.

    Not sure why this is happening. Could you mail me an example project (info at mudloop dot com)?
     
  19. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    You rock Mudloop! :D

    I wouldn't worry about (b) if it isn't happening for you. I think it's PolygonTool that's causing the problem.
     
  20. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    The update just went up in the asset store - temporarily at half price ($25).
     
  21. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Great stuff.

    Quick question. Does UniTile work in the XZ-plane?

    I asked in Support on how to generate nav meshes for the built in pathfinding in the XY-plane instead of XZ. I got no answers, but from what I've read it only works in XZ which means it can't be used with my tilemap unless it is rotated. I'm making a top down RPG btw. :)
     
    Last edited: Apr 24, 2012
  22. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    You can rotate the map any way you like, but internally it will always be in XY. But that's probably ok for your purposes. Just rotate the map using the transform settings (set x to 90). Let me know if that does the trick for you.
     
  23. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Obviously I didn't try it before I asked, I'm sorry. Was at work and just thought I would throw it out there so I had something to go on when I came home, but ended up looking like a fool instead. :) I can even see that you've covered it in the documentation.

    I've rotated my map and imported the new updates and it's all working great.

    Thanks alot.

    The new features are great.
     
  24. Azaphrael

    Azaphrael

    Joined:
    Nov 17, 2011
    Posts:
    41
    Would be nice if the Tile Replacer feature works while you draw. Just like RPG Maker does it, for example.

    +1 for tile animation. Every serious tile-based game needs that.
     
  25. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    And advice on how to get rid of or remedy such problems?



    I've tried to remedy it as best I can by:
    - Turning off AA
    - Turning on Vsync
    - Offsetting my map slightly
    - Offsetting the camera slightly
    etc. etc.

    The tile overlap option didn't work for me and made the tiles look blurry so I'm not using that, but I'm using most of the above and they seem to help, but I still can't get rid of it completely. Seems to only happen when the camera is in an exact position like 10, 10 or similar, if you understand what I mean. Every time the camera lands on an exact position (with no decimals) in a frame these gaps appear.

    I can live with it, but I would love to live without it. :p

    Another issue I have is that sprites I place in the world seem to jiggle when I run around. If you test the game here (http://www.twiik.net/unity/pixelquest) and run towards the upper left you'll see half the trees jiggle. They are placed as game objects and it happen to all objects I place like that. Not sure how to fix it. I thought it was enough to mvoe the player in update and the camera in lateupdate, but that made no difference.

    I know none of these issues are actually related to Unitile, but seeing as you've made a tile editor I was hoping you had some experience similar issues. :p

    Edit: 1 question and 1 issue related to UniTile for good measure:

    Q: Is there a performance loss in using flipped tiles? The tilesheet I'm using has duplicate tiles for everything that can face both ways. I could make them unique or just remove them if there's no difference in performance between placing normal or flipped tiles.

    I: When trying to flip tiles it's extremely slow to actually react. I have to press H or V like 20 times before the tile actually flips.
     
    Last edited: May 7, 2012
  26. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    About the image you posted, that's most likely "edge bleeding". What you need to do to cure that is use the TexturePadder tool, as described in the manual. It will change your texture's size though.
    An alternative you might try is making sure your camera is always on rounded numbers (possibly +0.5). So at the end of LateUpdate, you round the numbers, and add 0.5f.

    About the jiggling trees - I haven't seen that before. Do they have rigidbodies attached to them? If you want, you can mail me the project (info at mudloop dot com) and I'll have a look.
     
  27. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Are you sure it's edge bleeding? Those tiles are nowhere near eachother in the tilesheet.

    The green color is the camera clear color and the beige is the layer below visible through the grass. I changed the camera clear color to green in a futile attempt to make it less visible on the grass. :p

    I don't think I have experienced edge bleeding in my game, unless that actually is it.

    When you say you haven't seen the jiggle before I'm thinking it's something shoddy in my movement code. I will check in a different project. :p They are just normal gameobjects. The only thing that moves is the player and the camera follows him.
     
    Last edited: May 7, 2012
  28. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Oh, right, because it was both different colors and because it were colors that are in the tileset I assumed it was edge bleeding. But it is indeed gaps. The only way to solve that is by setting the tile overlap, like you already tried. It has always worked for me, so I'm not sure why it's blurry in your case. I want to look into it, but I need the project for that.
    Otherwise, you can still try rounding the camera's position as I suggested above. I think it should take care of the problem.
    Try reason you haven't experienced edge bleeding is possibly because you turned off filtering on the texture (just guessing though).
     
  29. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    That makes sense. AA introduces edge bleeding or some other form of edge artifacts as well. Luckily for me point filtering is what I want for my game. :p

    I will try some more and if I find no solution I'll send the project your way.
     
  30. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    TwiiK, that game looks charming! Just had to say it. I had the same problem that you are having. You're using 32x32 tiles? I believe that one of the ways I got rid of the lines was to save the smaller tileset on a 1024x1024 canvas. Maybe my settings will help you:







     
    Last edited: May 7, 2012
  31. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    I'd also like to put a vote for the tile replacer (autotile) to show the change as you draw. Tidy mapper does this nicely.

    Out of curiosity... is it possible for the player to make changes to the map? For example, perhaps you want to let them add objects? Like is done in terraria?

    And one more! I have no idea how to use the tile replacer. Is it possible to get a youtube video so we can learn how to create our first one?
     
    Last edited: May 8, 2012
  32. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    I have this on my list.

    Currently it's a bit slow, but I'm thinking about adding a "changeable" property to the tiles, which would remove some optimizations that only make sense when the tile is kept static.

    Did you read the manual? Anything I didn't explain well enough?
    I'm not very good at making videos due to the fact that I'm not a native English speaker and I stumble over my words often. But I'll think about it :)
     
  33. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    About the video tutorial doing it without sound or with subtitles is also a possibility. I hate doing screen casts myself because I sound awful, both in english and norwegian. :D

    As for the tile replacer I just created a new scene and experimented with it until I understood what everything did. I'm a man so I don't read the documentation. :p
     
  34. MarigoldFleur

    MarigoldFleur

    Joined:
    May 12, 2012
    Posts:
    1,353
    I've been working with UniTile lately and I have to say it's probably the best addition to Unity I've ever used. I was doing something similar to it with my own implementation but it was far less efficient and I had to do all the collision detection by hand. I've run into a small problem though.

    I'm using it with SpriteManager2 and, for some reason, I just can't spawn sprites on top of the tile layers, regardless of how I spawn them. They always spawn underneath. When the player dies, I want to spawn the explosion sprites on top of all the terrain, but they always spawn underneath. When I try and change the z-position of the layers or sprites directly, it seems to have no effect. Am I doing something wrong here?

    Also, is there a way to replace tiles during gameplay?
     
  35. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    That's most likely the shader that draws things on top. You can either try using the same shader with SM2 (but that would probably remove vertex colors), or you can use another shader on your tiles (possibly one included with SM2).
    EDIT : I also have another shader with vertex colors that could be used for both the sprites and the map. Drop me a mail to info at mudloop dot com if you want it.

    The tile replacer has not been tested for runtime usage. It may work, but it will most likely not be efficient at all.
    Or do you mean just changing certain tiles? Then you can use the SetTile(int x, int y, int newTileId) method.
     
  36. MarigoldFleur

    MarigoldFleur

    Joined:
    May 12, 2012
    Posts:
    1,353
    Wow, I wasn't expecting such a quick reply! I'm not using any vertex colouring, so that won't be a problem for me. I changed the shader and, yep, worked perfectly! And I did just mean certain tiles and it seems that SetTile is exactly what I needed! Thanks!
     
  37. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    I'm trying to call SetTile while the game is running, but no matter what I do, it just isn't working. When I try to get the layer, it comes back null. TwiiK, I tried to use your animation code as reference, but I always get an error when this line is hit: layer = GetComponent<TileLayer>();

    This is what I'm doing:
    1. I created a script called DrawTile.cs and I put this code in it:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class DrawTile : MonoBehaviour {
    7.     private TileLayer layer;
    8.     void Start() {
    9.         layer = GetComponent<TileLayer>(); // I get an error on this line
    10.         layer.SetTile(128,448,1);
    11.     }
    12. }
    13.  
    2. I attached the script to an object in the game.
    3. When the game runs, the script runs but layer is never found.

    Any ideas what I'm doing wrong? (Yeah, TwiiK, I'm one of those gals who stops for directions! :D)

    Notes from Husband:
    1) "layer" is NULL no matter if it is created on the stack or heap... any chance it needs to be initialized or perhaps passed into a function like "FindObjectsOfType"?
    2) What is the promoted mechanism to derive "TileLayer" objects from "MonoBehaviour" derived classes (as shown above)?
     
    Last edited: May 16, 2012
  38. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Hi,

    It can't work like that - GetComponent only gets components that are assigned to the current GameObject (that's a Unity thing, not a UniTile thing).

    So you have a couple of options :
    - Assign the script to the TileLayer GameObject instead of an unrelated GameObject.
    - Make the layer property public and assign the TileLayer in the editor.
    - Find the gameobject first, and then get the component (ie GameObject.Find("LayerName").GetComponent<TileLayer>() )
    - Use FindObjectsOfType like you said.

    There's probably other ways as well, but these methods should do the trick. As for the prefered method, that's up to you. Unity offers a number of ways to get references to objects, so it depends on how you like to do things.
     
    Last edited: May 16, 2012
  39. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    I've got another question. Can InstantiatePrefabs() be called while the user is playing the game? I've figured out how to swap tiles, but not how to rebuild box colliders for objects during gameplay.

    [Update]
    Okay, it appears not.

    [Update 2]
    Found a way to do what I needed with prefabs and a bit of custom coding.
     
    Last edited: May 18, 2012
  40. GermyGames

    GermyGames

    Joined:
    May 20, 2012
    Posts:
    38
    Hey, I'm really loving Unitile! How do I find out the grid X,Y coordinates of a prefab on an object layer? Also, is there a way to snap a prefab to the grid?
     
  41. GermyGames

    GermyGames

    Joined:
    May 20, 2012
    Posts:
    38
    Whoops, I just had the prefab misaligned. I just had to re-add it and the transform X and Y match grid coords now.:p
     
  42. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Sorry for not responding sooner - I was gone for a few days.

    Glad you found a way. The box collider system is not really suitable for runtime use. As you're probably aware, it combines multiple tiles together, which would probably be a bit too expensive to calculate at runtime.

    Good to hear you figured it out.
     
  43. GermyGames

    GermyGames

    Joined:
    May 20, 2012
    Posts:
    38
    Is there any way to modify properties of prefabs in a tile layer? For example: I have a tile with a prefab that has a text property, I then edited the text property of one of the tile instances, but I can only get the default value instead of my changed value when the game starts.

    Is there a way to make each prefab instance retain its changes?
     
  44. bananamouth

    bananamouth

    Joined:
    Apr 10, 2012
    Posts:
    6
    I'm having a perfomance issue: If I get my grid bigger than, say, 250x250 my viewport performance drops and unity starts to stutter, and more than once it crashed. It also affects my game window when I try to play, dropping my fps considerably, even though the other stats don't seem remarkably high.

    However, if I select any other object on my hierarchy my performance goes back up to normal, and even with a 750x750 grid I see no performance drop when messing with the viewport or in-game. As long the tile layer is not the one highlighted I have no problems.

    I would like to build one big map, and theoretically it seems to be possible to do it without having performance problems when in-game, but how would I go about creating the map on the viewport? Is there anything I'm doing wrong, or do you have any tips to solve or minimize this problem? Would several smaller tile layers overlapping on contact points be a better way to do it? Would that incur into any problems?


    That said, great tool, it already helped me immensely.

    Thanks
     
  45. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    When you press "create objects", all tile prefabs are deleted and recreated. So currently, it's not possible. I'll add it to my list, but I can't give an ETA on the next version yet.

    It's just a guess at this point, but I think it may be the code that draws the grid that's causing the problem. So in that case, several smaller maps would likely solve it, as it would only draw the grid for the current map. You can move maps around, and if you set up the tile setting correctly, I don't think you should see any gaps/bleeding at the overlapping edged of the maps.
     
  46. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    If anyone uses PlayMaker, I've created a bunch of actions:

    -UnitileGetMouse: Get the coordinates of the mouse and convert to UniTile coordinates.
    -UnitileSetTile: Paint a tile.
    -UnitileGetTileInfo: Get information about a tile.
    -UnitileGetTileProperty: Get the property of a tile.
    -UnitileGetBoxCollider: Get information about a box collider attached to a tile.

    You can get them on the PlayMaker forum here:
    http://hutonggames.com/playmakerforum/index.php?topic=1592.msg6929#msg6929
     
  47. MarigoldFleur

    MarigoldFleur

    Joined:
    May 12, 2012
    Posts:
    1,353
    I think I might just be really stupid, but I honestly have no idea how to access the API features. What I'm trying to do is find the value of the tile that the player is currently over. The translation for that is simple enough:

    Code (csharp):
    1. var xTile : int = Mathf.Round(player.position.x/16);
    2. var yTile : int = Mathf.Round(player.position.y/16);
    Which gives me the player's current position in TileXY coordinates. But I'm just really dumb and I can't figure out how to make the API call to check the tile value at that point. I'm working in JavaScript, so I made sure to move UntTile to the Standard Assets folders but now I'm completely stuck.
     
  48. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Well, I have no real UnityScript experience, but I believe you should move UniTile to a folder called "Plugins".
    Then you can use GetComponent on the GameObject to get a reference to the map. Let me know if this doesn't work, and I'll have a look asap.
     
  49. MarigoldFleur

    MarigoldFleur

    Joined:
    May 12, 2012
    Posts:
    1,353
    It took a bit of futzing, but I got it to work. What I had to do was move just the scripts folder into Standard Assets. I should have done this first since this is a mistake I make with every single thing I download from the asset store.
     
  50. MarigoldFleur

    MarigoldFleur

    Joined:
    May 12, 2012
    Posts:
    1,353
    I just thought I'd share something I came up with while making a non-ridigbody based collision system because I just realised that this is likely a very fast way to change the collision value of a specific tile without having to rebuild the entire map. Keep in mind that this only works for tile based collision.

    First, I'd like to point everyone here to this, because it was my primary inspiration for the idea: http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/

    What I do is set the value of the tiles rather than setting a rigidbody to them. For instance, solid objects are 5, water is 10, an upward slope (right) is 1 for the first part and 2 for the second, and so on and so on. Now, you may be thinking "isn't calling the x and y value of the map for every collision test really slow and frustrating?" And yes! It is! Which is why I load it all into an array, like so:

    Code (csharp):
    1. function Start () {
    2.  
    3.     var mapSize : Vector2 = mapTiles.layerSize;
    4.     var tileID : int;
    5.            
    6.     mapArray = new int[mapSize.x,mapSize.y];
    7.  
    8.     for (var yAllocate : int = 1; yAllocate < mapSize.y; yAllocate++) {
    9.         for (var xAllocate : int = 1; xAllocate < mapSize.x; xAllocate++) {
    10.             tileID = mapTiles.GetValue(xAllocate,yAllocate);
    11.             mapArray[xAllocate,yAllocate] = tileID;
    12.             Debug.Log(mapArray[xAllocate,yAllocate]);
    13.         }
    14.     }
    15. }
    Since the mapSize is likely to remain static, this means the array is very, very fast in both reading values from and committing values too! And because the array is nicely matched up to the mapCoordinates, you can use it to automatically set new tile graphics and collision info without having to rebuild the whole map! Remember that the array's origin points are going to be 0,0 and not 1,1.

    This obviously isn't for everyone, but if your map mostly just requires simple slopes and flat surfaces, it should be very very fast, especially if you want things like semi-deformable terrain.

    Anyway, I hope this continues to work as well for me as it has and that it maybe helps some of you in the future.
     
    Last edited: Jun 9, 2012