Avesta: 2D Procedural Tilemap Generator

If you are looking for the v1.2.1 documentation, please go here

Changelog

v2.1.0

v2.0.0

v1.2.0

v1.1.1

v1.0

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

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.

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 it doesn’t do much... yet. 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, choose a tile (or a Rule Tile for example) and put it into the Tile field.

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

Create → 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 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.

The “Save Map” button creates a new Prefab of any GameObject you drag on the Object to Save field. This will preserve all the configurations. This is useful when you want to create chunks of maps so afterwards you can just drag them to your Scene easily.

Prefabs are saved on a new folder “Assets/Prefabs/Maps/Generated/” with a distinctive name or alternatively you can name the prefab using the “Map Name” field on the Inspector. After saving you can just Drag and Drop that prefab on any scene and use it as a normal Tilemap.

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!

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.

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

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: 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.

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 2 different Scenes: Demo Scene and Occlusion Demo 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.

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