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

2d Tile Mesh

Discussion in '2D' started by piggybank1974, Dec 19, 2015.

  1. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    Hi All,

    I need some advice, I've just started unity, I've build a couple of examples and I'm getting the hang of it, my goal is to build a gauntlet type game(I'm 41 so the old games are the best) in unity, after looking around some tutorials I decided to use the Mesh example from quill18creates site
    but I cannot get the mesh to display in 5.3.0 of unity

    Here is the script

    using UnityEngine;
    using System.Collections;

    [RequireComponent(typeof(MeshFilter))]
    [RequireComponent(typeof(MeshRenderer))]
    [RequireComponent(typeof(MeshCollider))]
    public class TileMap : MonoBehaviour
    {

    // Use this for initialization
    void Start()
    {
    BuildMesh();

    Debug.Log("Build Mesh Started");
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void BuildMesh()
    {
    Vector3[] mVerticles = new Vector3[4];
    // 2 = number of trigangles
    // 3 = number of points on the triangle
    int[] triangles = new int[2 * 3];
    Vector3[] mNormals = new Vector3[4];

    mVerticles[0] = new Vector3(0, 0, 0);
    mVerticles[1] = new Vector3(1, 0, 0);
    mVerticles[2] = new Vector3(0, 0, -1);
    mVerticles[3] = new Vector3(1, 0, -1);

    triangles[0] = 0;
    triangles[1] = 3;
    triangles[2] = 2;

    triangles[3] = 0;
    triangles[4] = 1;
    triangles[5] = 3;

    mNormals[0] = Vector3.up;
    mNormals[1] = Vector3.up;
    mNormals[2] = Vector3.up;
    mNormals[3] = Vector3.up;


    Mesh mMesh = new Mesh();
    mMesh.vertices = mVerticles;
    mMesh.triangles = triangles;
    mMesh.normals = mNormals;

    MeshFilter mFilter = GetComponent<MeshFilter>();
    MeshRenderer mRenderer = GetComponent<MeshRenderer>();
    MeshCollider mCollider = GetComponent<MeshCollider>();

    mFilter.mesh = mMesh;
    mCollider.sharedMesh = mMesh;
    Debug.Log("Mesh Done");
    }
    }

    it does call the script fine but I don't see the mesh in the Scene window or the Game window, I thought it might be the Camera z access so I place a sphere and this displayed ok.

    I'm at a loss

    Can anybody point me in the correct direction?
     

    Attached Files:

  2. DuffyT

    DuffyT

    Joined:
    Dec 16, 2014
    Posts:
    37
    He makes mistakes in his video's, don't get me wrong, he's a great coder, I used his tutorials myself many times. But I remember he made a mistake in one of those video's on tilemaps that puts the tilemap upside down, something to do with the order of vertices in the triangles. Check your scene-view if it is displayed upside down? Play with your vertices and triangles untill you get it right. And keep looking at his video's, he goes much deeper into this subject, very interesting.
     
  3. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    Hi DuffyT,

    thanks for the reply, I've done everything, it does not display in the scene view, or the game view, it is getting calculated, I had a look at other tutorials and they are the same they just don't view, even if I press the Q key and the right mouse button and look around the camera view, is it possible that you are anybody else could create a working version I'm using 5.3.0 as I said, just to get me started, please???

    I ran one of his tutorials and that did not display either, so is it this version of the unity editor??

    or am I doing something wrong I've spent a weekend on this and I'm no further forward, furthermore I am using 2D project, but I did notice that if you create a plane, you have to rotate it in the X position by 270 to see the flat surface of the plane, I would of thought that when you add it to the hierarchy tab it would be in the correct plane to start with??

    anyways please can you help on this??
     
  4. DuffyT

    DuffyT

    Joined:
    Dec 16, 2014
    Posts:
    37
    Well, this is the script I use in my project at the moment to generate a single quad, the indentation is a little off because I removed some project-specific code. You just need to add this script onto a gameobject and call the BuildNewSingleTileMesh method in start. And make sure it has a mesh-filter and renderer. Also add a desired tilesize in the inspector. I did notice in your code you don't add the uv's? I doubt that's the problem but it's worth a try?

    Code (CSharp):
    1.    
    2.  
    3.     public Float tileSize;
    4.  
    5.     private Mesh mesh;
    6.     private Vector3[] vertices;
    7.     private Vector2[] uv;
    8.     private int[] triangles;
    9.  
    10.     //Builds new single-tile mesh
    11.     public void BuildNewSingleTileMesh()
    12.     {
    13.             mesh = new Mesh();
    14.                  
    15.             vertices = new Vector3[]
    16.             {
    17.                 new Vector3(0, 0, 0),
    18.                 new Vector3(0, 0, tileSize),
    19.                 new Vector3(tileSize, 0, tileSize),
    20.                 new Vector3(tileSize, 0, 0)    
    21.             };
    22.  
    23.             uv = new Vector2[]
    24.             {
    25.                 new Vector2 (0, 0),
    26.                 new Vector2 (0, 1),
    27.                 new Vector2(1, 1),
    28.                 new Vector2 (1, 0)
    29.             };
    30.  
    31.  
    32.         triangles = new int[] { 0, 1, 2, 0, 2, 3 };
    33.  
    34.         mesh.Clear();
    35.      
    36.         mesh.vertices = vertices;
    37.         mesh.triangles = triangles;
    38.         mesh.uv = uv;
    39.      
    40.         mesh.RecalculateNormals();
    41.      
    42.         mesh_filter.mesh = mesh;
    43.     }
    44.  
     
  5. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    Hi Duffy T,

    First I want to thank you for your support on this matter, I'll create I new 2D Project and report back, if I get any hassle I post the new project, I couldn't see why the own I created does not work based on your code example.

    Yeah the uvs might be the problem in a later version of unity?? I thought though this is only if you want a texture on the mesh, I will in the future, as I will be taking this from a position on the png picture file.
     
  6. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    Hi Duffy T,

    I couldn't get your version to fully work, it only gave me a single right hand triangle, but after a bit of fiddling and a tutorial from here http://answers.unity3d.com/questions/154324/how-do-uvs-work.html, I managed,

    I thought I would help others so I've posted the code here.
    Code (CSharp):
    1.  public void BuildNewSingleTileMesh()
    2. {
    3.   Debug.Log("Mesh Creating");
    4.   mesh = new Mesh();
    5.  
    6.   vertices = new Vector3[4];
    7.  
    8.    // 0 ------------ 1
    9.    //   |         /|
    10.    //   |        / |
    11.    //   |       /  |
    12.    //   |      /   |
    13.    //   |     /    |
    14.    //   |    /     |
    15.    //   |   /      |
    16.    //   |  /       |
    17.    //   | /        |
    18.    //   |/         |
    19.    // 2 ------------ 3
    20.  
    21.    // Y + value to go up screen
    22.    // Y - value to go down screen
    23.    // X + value to go right screen
    24.    // X - value to go left screen
    25.  
    26.    vertices[0] = new Vector3(0, 0, 0); //top-left
    27.    vertices[1] = new Vector3(tileSize, 0, 0); //top-right
    28.    vertices[2] = new Vector3(0, -tileSize, 0); //bottom-left
    29.    vertices[3] = new Vector3(tileSize, -tileSize, 0); //bottom-right
    30.  
    31.    uv = new Vector2[]
    32.    {
    33.    new Vector2(0, 0),
    34.    new Vector2(0, 1),
    35.    new Vector2(1, 1),
    36.    new Vector2 (1, 0)
    37.    };
    38.  
    39.    int[] triangles = new int[] { 0, 1, 2, 3, 2, 1};
    40.  
    41.    mesh.Clear();
    42.    mesh.vertices = vertices;
    43.    mesh.triangles = triangles;
    44.    mesh.uv = uv;
    45.    mesh.RecalculateNormals();
    46.    (GetComponent<MeshFilter>()).mesh = mesh;
    47.    Debug.Log("Mesh Created");
    48. }
    thanks for your help all I need to do is create a 32x32 map full of these and use a png file to display each tile from a certain position in my XMl file, how hard can that be?? lol

    I'm not sure if I should have coordinates 0,0(tile placement centre as of now) as the centre of the map, or screen 0,0(Top Left), this will be a scrolling map so it only displays tiles that from the centre of the user??

    I did want to mention I'm still not able to see the mesh in scene window, but in game mode it's fine not sure why??
     
    Last edited: Dec 22, 2015
  7. DuffyT

    DuffyT

    Joined:
    Dec 16, 2014
    Posts:
    37
    You could add a line on top of your class ([ExecuteInEditMode]) to make it execute in the editor/scene-view but the actual map-generation only works after you start the game. I think it's one of the first things Quill18 does in his tutorials on this and as you followed his tutorials I didn't think you expected it to work in scene-view. I assumed you didn't see any mesh after pressing play. :p

    As for the "bug" in my code with the triangle. I'm using this method to generate very large maps for a builder-game and I use the single-quad for alot of things, like regenerating different-size items/placements with only one object/quad. I removed alot of code from my class for that example to make it simple to try out so I might have changed something in the vertices/triangle-order unwittingly.

    My project in action:


    If you want to see what can be achieved with this simple method of mesh-building. The main map is several layers of code-generated meshes. The item/building/path/... placement is also done with a dynamic mesh generated on the fly and resized according to the current needs. On top of the mesh-generation also come alot of uv-manipulation so be prepared for that if you go this way.
     
  8. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    Hi DuffyT,

    That looks awesome, I'm not sure if this is the correct way if you take a look at gauntlet pics https://www.google.co.uk/search?q=g...ved=0ahUKEwinqq-op_LJAhWKWBQKHZhqAxEQ_AUIBigB is what I'm after, I've already created a part of the mapping system in vb.net, see Map.png,(and created a fully png of the map picture.png) the circle(which represents the player) can walk around the map, but I was going to convert this to Android(java), and use a surface view which I've done before on an arkanoid clone, but I tought way not learn and use Unity!!

    Are meshes the way to go here or do it like Quill18 wrong way first episode tutorial.

    any advice would be great DuffyT,

    I'm going to use my own map editor I've created in .net it uses layer etc.
     

    Attached Files:

  9. DuffyT

    DuffyT

    Joined:
    Dec 16, 2014
    Posts:
    37
    With a bit of work and research that kind of game is very easy in Unity, and essentially (map-wise) the game you want to make is exactly the same as mine. Only I give the player full control on what to place on the map and where. Your game is easier as you probably want to pre-make maps, or generate them procedurally. I think you're focusing a little too much on the visual side of things. Essentially these types of games that use tilemaps are 90% checking a data-structure for info on a single tile (is the tile walkable, a wall, a chest of loot, a table, ...). That data-structure can be represented in the game-world in any number of ways.

    The data-structure I created for my game can be used for any type of game that uses tilemaps, and I intend to re-use it in the future for other games where I need a tilemap. Utilizing unity's scriptable objects and a decent editor-extension I made a tile/map-editor where I can pre-make placements and save them. You could use the same kind of system to create tiletypes and/or create maps and save them. But I admit creating a decent unity-editor extension requires some research but there are alot of tutorials to find on this, not the least Unity's own tutorials.

    As for the single-mesh vs multiple single tiles, watch Quill18's new tutorials on the base-building game. The first few episodes are about the creation of a multiple-object tilemap, and he gives pro's and con's.
     
  10. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    Hi DuffyT,

    I would love to see your code(either privately or published here), on how your mapping system works, may be that will point me in the right direction, It's usual to be all over the place when you trying to learn a new piece of software, experience counts and you have it with unity, that's why I try to produce snippets of all sorts of things then I put them together, I must admit I've not seen all Quill18 video's on the based builder, because I was having problems with the mesh.

    Yesterday I was in the process of producing a series of classes to produce Mesh builder, it works and it's in it's early stage as it still needs works but it can produce a triangle with very little lines of code.

    As a homage to yourself I might call it the Duffies Mesh Builder with my classes in your project and the follow code(which produces a Square/Quad).

    Code (CSharp):
    1. public class DuffiesMesh : MonoBehaviour
    2. {
    3. public float tileSize;
    4.  
    5. private Mesh mesh;
    6.  
    7. // Use this for initialization
    8. void Start()
    9. {
    10.    CreateMap();
    11. }
    12.  
    13. // Update is called once per frame
    14. void Update()
    15. {
    16. }
    17.  
    18. private void CreateMap()
    19. {
    20.   mesh = new Mesh();
    21.  
    22.   MyListCollection mLists = new MyListCollection();
    23.  
    24.   mLists.OnAdded += mLists_OnAdded;
    25.  
    26.   mLists.Add(new Triangle(new Vector3(0F, 0F, 0F), new Vector3(tileSize, 0F, 0F), new Vector3(0F, -tileSize, 0F)));
    27.   mLists.Add(new Triangle(new Vector3(tileSize, -tileSize, 0), new Vector3(0, -tileSize, 0), new Vector3(tileSize, 0, 0)));
    28.  
    29.   foreach (Triangle item in mLists)
    30.   {
    31.    Debug.Log("Triangle is: " + item.ToString());
    32.    foreach (int number in item.Triangles)
    33.    {
    34.     Debug.Log("Number is: " + number);
    35.    }
    36.   }
    37.  
    38.   mesh.Clear();
    39.   mesh.vertices = mLists.VerticesArray();
    40.   mesh.triangles = mLists.TrianglesArray();
    41.   mesh.RecalculateNormals();
    42.   (GetComponent<MeshFilter>()).mesh = mesh;
    43.   Debug.Log("Mesh Created");
    44. }
    45.  
    46. void mLists_OnAdded(ItemBase Item)
    47. {
    48.   Debug.Log("Item has been added");
    49. }
    50. }
    I usually have each tile(or cell if you like), represented by a class but until I get the hang of what I'm trying to achieve here I'm not to sure on how to have it, as I want it to aid collision detection etc but this is way down the line, as I said if you willing to help I'm willing to learn, and I hope other will pick up some information that might help them also.
     

    Attached Files:

  11. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    As of right now, I've added Square class properly into the Mesh Builder, I've also changed Triangle to inherit from Shape which has been added, this makes the code a little cleaner.

    By creating a Square(I could of called it a Quad, but I thought people understand what a square is easier, at least new users will do).

    by using Square for example it will automatically create the desired vertices, as well as the triangles internal numerical values, then as the example shows just pass this on to the mesh, using the desired functions VerticesArray(), TrianglesArray().

    this should make adding a form of map a breeze now.

    Code (CSharp):
    1.  private void CreateMap()
    2. {
    3.   mesh = new Mesh();
    4.  
    5.   MyListCollection mLists = new MyListCollection();
    6.  
    7.   mLists.OnAdded += mLists_OnAdded;
    8.  
    9.  
    10.   mLists.Add(new Square(new Vector3(0F, 0F, 0F), new Vector3(tileSize, 0F, 0F), new Vector3(0F, -tileSize, 0F), new Vector3(tileSize, -tileSize, 0)));
    11.  
    12.   mLists.Add(new Triangle(new Vector3(tileSize, 0F, 0F), new Vector3(tileSize * 2, 0F, 0F), new Vector3(tileSize, -tileSize, 0F)));
    13.   mLists.Add(new Triangle(new Vector3(tileSize * 2, -tileSize, 0), new Vector3(tileSize, -tileSize, 0), new Vector3(tileSize * 2, 0, 0)));
    14.   foreach (Shape item in mLists)
    15.   {
    16.    Debug.Log("Triangle is: " + item.ToString());
    17.    foreach (int number in item.Triangles)
    18.    {
    19.     Debug.Log("Number is: " + number);
    20.    }
    21.   }
    22.  
    23.   mesh.Clear();
    24.   mesh.vertices = mLists.VerticesArray();
    25.   mesh.triangles = mLists.TrianglesArray();
    26.   mesh.RecalculateNormals();
    27.   (GetComponent<MeshFilter>()).mesh = mesh;
    28.   Debug.Log("Mesh Created");
    29. }
     

    Attached Files: