Avesta: Procedural Tilemap Generator

Changelog

Note: If you are upgrading from v1.+ please remove everything first and then install Avesta v2+

Introduction

First of all, we would like to personally thank you for trying out this asset! We hope it helps you on your game dev journey.

What is Avesta?

Avesta is an easy-to-use Procedural Tilemap Generator Tool. It contains several algorithms for you to play around. This is not a replacement for a normal Tilemap, it’s a creative tool to start designing your world!

Start using Avesta

Setup

First of all, make sure you have a Rectangular Tilemap in your Scene by right clicking on your Hierarchy, 2D Object -> Tilemap -> Rectangular. This will create a GameObject with a Grid script attached to it and with a child GameObject with a Tilemap component attached.

Note: if you are making a 3D game, please see the 3D extras setup below after you finishing this setup.

Once you have your Rectangular Tilemap in place, drag the Level Generator prefab from Runtime/Prefabs folder to your scene. Click the added prefab to see it on the Inspector.

You will notice there’s a new view inside your Scene view called “Preview Overlay”.

Whenever you made a change on the Level Generator in the Inspector the Preview Overlay will update automatically.

As from Avesta v2.0.0 you have support for multiple layers, each with different configurations. Now, change that “ 0” to the right of the “ Layers” attribute to a “ 1”.

This is the first step of your journey. Drag the previously created Tilemap to the Tilemap field.

The Clear on Generate checkbox is useful to toggle in between clearing the map before generating the new one or not. If true, it will clear the map before generating new one, false otherwise.

At the end of this component you will see the final fields. Choose a tile (or a Rule Tile for example) and put it into the Type of Tile field.

The Generate Colliders checkbox is also there if you want to choose to generate or not colliders to this tilemap when generating a map.

Next you need a MapConfiguration file. In any folder you want, right click then:

Create → Avesta → Maps → Choose any of this algorithms.

After that you should see a new file created. You can edit this file or even better, just drag it into the LevelGenerator’s layer Map Config field under the Algorithm header

As you can see, the name for this Layer has changed matching the algorithm’s name as well! Also you can see on the picture above that this layer is Inactive by default. Let’s change that but clicking the “Active” property under the title:

This will enable the preview for that layer.

You will notice that there’s also a field called “ Is Additive”. This is used to “add” or mix multiple layer algorithms into the generated map. By using this on the same tilemap you can generate really unique maps.

There’s also a “ Randomize” button on the top right corner of each layer. This helps to randomize that specific layer. Each algorithm changes some of their parameters when clicked.

This again will change the title to display the status of this layer. This is useful whenever one is playing around with different algorithms and layers to create the best possible map.

Also, the “ Generate Colliders” field helps us creating standard collision detection for the given Tilemap. This is super useful if you have a Walls map layer for example.

From here you can edit all the configurations for that specific algorithm.

Change some parameters such as the width and height and then press the “ Generate Map“ button below!

The “ Clear Map” button just resets all Tilemaps on the active layers, clearing all the tiles on them. This will not reset any configuration made on that layer, just the visuals and the collisions if the “ Generate Colliders” is enabled.

Finally you can drag and drop your character inside the map and play around. We provide 2 sample scripts for a simple player movement and a camera follow so you can test around your newly created map!

Making a 3D Tilemap

If you follow along but wanted to make a 3D scene, you will notice it looks strange. You will need to make some adjustments.

  1. Delete the Level Generator prefab from the Hierarchy view
  1. Drag & Drop the Level Object Generator prefab (under Avesta/Runtime/Prefabs)

After that you will need to adjust the tilemap itself. Click on the Grid GameObject and change the Cell Swizzle to XZY.

After that you will need to change every child inside the Grid gameobject that has a Tilemap component attached. On this component, change Orientation to XZ.

That’s it! now you can use the Level Object Generator as usual.

If you want to simulate height, you can make multiple Tilemaps and change their Y position on the transform accordingly.

Placing Objects

We imagined that you would like to place objects on your Tilemap and this has never been as simple as with Avesta!

Attach the MapObjectPlacer script to your Level Generator game object (or any other you want).

Drag the target Tilemap where you want the objects to be placed. If you have any other Tilemap that is used as water or walls and you want to avoid those ones when placing objects, just drag them into the “ Obstacles Tilemaps” field.

Change the Objects size to match how many different type of prefabs you would like to place. Drag your objects on the fields and play around with the weight. The bigger the weight, the more chances it has to appear. Adjust your Object Fill Percent for the total amount of objects to place and finally press the Place Objects button.

The “ Clear Objects” button just removes all the objects you placed on that given Target Tilemap field.

Map Additive

Now we can place tiles within another Tilemap. Imagine for example that you have your map with water and some ground. Now you want to add some grass to this ground but only where there's a ground tile. With MapAdditive now you can.

It's called MapXXAdditive where XX can be Object (3D) or Tile (2D).

How to use:

Supported Algorithms Configurations

All configurations have Width and Height fields that needs to match to whatever dimensions you would like this layer to have.

Basic Random

Cellular Automata

Full Grid

Basic configuration. It will fill the entire tilemap with the desired dimensions.

Game Of Life

If you want to know more about this algorithm here is a good resource

Path

Perlin Noise

Random Walk

Fractal Noise

Island

Domain Warping

Fourier Noise

Ridged Multifractal

Voronoi

Wavelet Noise

Destructible Tilemaps

Welcome to the world of destruction! Creating 2D destructible maps has never been easier.

Destructible Tile

The first step is to create a Destructible Tile. For this right click on your Project window go to CreateAvestaTilesDestructible Tile

This will create a new asset

Destructible Tile inherits from the Rule Tile. It has the same functionality but it adds some fields

The rest is just as any other Rule Tile you had done before.

Destructible Tilemap

For a normal Tilemap to have Destructible capabilities, just add the Destructible Tilemap script to it. Also you can create/change the Layer of this object so it makes it easier afterwards to interact with it.

Note 1: Since you adjust the Layer of this tilemap, be sure to update accross the scene (Culling masks on the Camera game object, etc)

Note 2: at this point you can also add a TilemapShadow to this Tilemap. Be aware about the Order In Layer. Adjust it accordingly so it looks good.

Once the script is added you can use it normally in your Level Generator script as any other Tilemap. Drag it and also drag the previously created Destructible Tile.

Notice that we are generating the colliders. This way we can detect the collisions and destroy the tiles accordingly.

In the demo scene we are using a Geometry Type of Outlines since it’s more performant but Polygons works as well.

When doing research on this matter, using a CompositeCollider2D is way more performant since it wraps every tile’s colliders into one. The drawback is that the detection of the collisions is better on the edges of your tilemap. For some projects this is fine but if you need a better “per-tile” approach you can remove the CompositeCollider2D and the Rigidbody2D and uncheck the “use by composite” on the main TilemapCollider2D (you can see this on the Bomberman Destructible demo Scene.

You can also add a “destroyed tile” status when a tile is destroyed (a simple visual like a ground tile). To do this, create a new Tilemap object on your hierarchy. Add the Destructible Tilemap Background script to it and drag the destructed tile and tilemap to follow. Afterwards just click on the “Update Background” button. This will copy the reference Tilemap and add the visual tile.

Note: this tilemap should be rendered below the main Destructible Tilemap. Just change the Order In Layer to do this.

If you have any doubts, you can see this in work in the Destructible Scene.

Destroying Tiles

Too much blah blah until now, let me destroy things!

To destroy tiles we need a new script. This one could be attached to the player or anything you want. On this script you just need to have a point in the world and send it to the destructible tilemap.

In this example we will see how we can destroy a tile when the mouse is clicked.

					public class ClickAndDestroy : MonoBehaviour
{
		// the Layer of the Destructible Tilemap
    [SerializeField] private LayerMask targetMask;
		// how big we need to check
    [SerializeField] private float checkRadius = .4f;
    // Depending on the type of game you could have different tools/weapons with different amount of damages
    [SerializeField] private int tileDamage = 3;

    [Header("FX")] 
		// show a visual on the grid
    [SerializeField] private Transform tileVisuals;
    [SerializeField] private ParticleSystem destroyParticles;
    
    private Camera _mainCamera;
    private Vector2 _mousePosition;

    private void Awake()
    {
        _mainCamera = Camera.main;
    }

    private void Update()
    {
				// get the moouse position
        _mousePosition = _mainCamera.ScreenToWorldPoint(Input.mousePosition);
				// check if collides with something using the LayerMask
        Collider2D overlapCircle = Physics2D.OverlapCircle(_mousePosition, checkRadius, targetMask);

        DestructibleTilemap destructibleTilemap = null;
        
				// display a visual if it hits the target mask
        if (overlapCircle != null && overlapCircle.TryGetComponent(out destructibleTilemap))
        {
            if (!tileVisuals.gameObject.activeSelf)
            {
                tileVisuals.gameObject.SetActive(true);
            }
            
            tileVisuals.position = destructibleTilemap.GetTileCenter(_mousePosition);
        }
        else
        {
            tileVisuals.gameObject.SetActive(false);
        }

        if (!Input.GetMouseButton(0) || overlapCircle == null || destructibleTilemap == null) return;
        
        // if we clicked on a proper destructible tile we perform the visuals and destroy the tile
        
        destroyParticles.transform.position = _mousePosition;
        destroyParticles.Play();
        // here we send the hit position where we clicked and the amount of damage to that tile.
        // depending on the type of game you could have different tools/weapons with different 
        // amount of damages.
        destructibleTilemap.PerformContact(_mousePosition, tileDamage);
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(_mousePosition, checkRadius);
    }
}
				

Extras

On the Samples folder you will find 3 different Scenes: Demo Scene, Occlusion Scene and Destructible Scene.

Demo Scene

This is a basic scene where you can play around with the LevelGenerator settings. Some things to notice are the Order in Layer for the different Tilemaps under the Additional Settings on the Tilemap Renderer.

For example, in a normal settings you would have

Layer Order In Layer
Ground 0
Paths/Decorations 1
Wall Shadows 2
Walls 3

In the Demo, we provide a TilemapShadow script with a simple “shadow material” (just a normal gray color with alpha)

This script copies a tilemap and also offsets it downwards (0.25f down) of the reference tilemap.

Occlusion Demo Scene

This scene has the same functionality as the previous one but it adds a simple way of making it more performant but hiding and showing the tilemaps to the player while it moves.

The player has a OcclusionCullingDetector script on one of the child game objects. This one helps detecting a tilemap and activate it.

Another thing to note is that each Chunk container has an Occlusion Tilemap and a Trigger Collider components attached to them. This helps the OcclusionCullingDetector script detect them.

Bomberman Demo Scene

This scene shows how easy is to create a Bomberman-like game with the Destructible Tiles. Play around with the ship and place bombs using the Spacebar on your keyboard.

Wrapping up!

Now you are set to start your own game! Play around with the settings in the inspector and come up with great worlds!

The possibilities of expansion are endless! Just use the Tilemap as usual afterwards to place different objects and tiles to tweak your world as it fits better.

Thanks again for trying Avesta! If you are curious about what else we have, check more of our content in our Shop on the Asset Store!

For any further question not covered here feel free to contact us at support@berserkpixel.studio

F.A.Q

Help! I can’t see the Rule tiles properly. It shows Missing (Mono Script)

This is because in order to use Rule Tiles, one has to install the 2D-Extras preview package. For safety reason we are not allowed to include a preview package into our assets. But it’s a super quick fix!

Solution 1

The following line needs to be added to your Packages/manifest.json file in your Unity Project under the dependencies section:

            					"com.unity.2d.tilemap.extras": "https://github.com/Unity-Technologies/2d-extras.git#master"
            				

For more information please check out the official Github Repo: https://github.com/Unity-Technologies/2d-extras

Solution 2

Another way of adding it is going to you Package Manager window (Window → Package Manager), click on the gear icon and select Advanced Project Settings.

Afterwards just enable preview packages

And then the 2D Tilemap Extras should appear in your Package Manager

Library\PackageCache\com.unity.2d.tilemap.extras@2.2.5\Runtime\Tiles\AnimatedTile\AnimatedTile.cs(171,26): error CS1061: 'ReorderableList' does not contain a definition for 'IsSelected' and no accessible extension method 'IsSelected' accepting a first argument of type 'ReorderableList' could be found (are you missing a using directive or an assembly reference?)

Solution

The following line needs to be modified on your Packages/manifest.json file in your Unity Project under the dependencies section:

            
"com.unity.2d.tilemap.extras": "2.2.5",            
to
"com.unity.2d.tilemap.extras": "X.Y.Z",
            
            

where “X.Y.Z” is the version corresponding to your Unity version. Here you can find all the available version on the toggle group on the top left.

For more information please check out the official Github Repo: https://github.com/Unity-Technologies/2d-extras