Rotorz Tile System Icon
Rotorz Tile System for Unity
Docs
Available on the Unity Asset Store
TOC Prev Next Download PDF

Painting at Runtime

The runtime API makes it easy to paint and erase tiles at runtime by reusing the brushes that you have already defined.

Important
Important
Ensure that stripping preset of associated tile system is set to Runtime Painting, No Stripping or alternatively Custom with appropriate selection.

Painting and erasing tiles

The following source code demonstrates how to paint and erase tiles at runtime. When creating an in-game level designer it is likely that you would want to create some sort of user interface for selecting brushes, etc.

using UnityEngine;
using Rotorz.Tile;

public class RuntimePaintingExample : MonoBehaviour {
    // Tile system to paint on
    public TileSystem tileSystem;
    // Brush to use with left mouse button
    public Brush brush;

    void Update() {
        // Find mouse position in world space
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        // Nearest point where ray intersects tile system
        TileIndex ti = tileSystem.ClosestTileIndexFromRay(ray);

        if (Input.GetMouseButtonDown(0)) {
            // Paint with left mouse button
            brush.Paint(tileSystem, ti);
            tileSystem.RefreshSurroundingTiles(ti);
        }
        else if (Input.GetMouseButtonDown(1)) {
            // Erase with right mouse button
            tileSystem.EraseTile(ti);
            tileSystem.RefreshSurroundingTiles(ti);
        }
    }
}
// Assets/RuntimePaintingExample.js
#pragma strict
import Rotorz.Tile;

// Tile system to paint on
var tileSystem:TileSystem;
// Brush to use with left mouse button
var brush:Brush;

function Update() {
    // Find mouse position in world space
    var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    // Nearest point where ray intersects tile system
    var ti = tileSystem.ClosestTileIndexFromRay(ray);

    if (Input.GetMouseButtonDown(0)) {
        // Paint with left mouse button
        brush.Paint(tileSystem, ti);
        tileSystem.RefreshSurroundingTiles(ti);
    }
    else if (Input.GetMouseButtonDown(1)) {
        // Erase with right mouse button
        tileSystem.EraseTile(ti);
        tileSystem.RefreshSurroundingTiles(ti);
    }
}
FigureĀ 7-2. Source Listing: Painting with brushes at runtime

To use the above script:

  1. Create a script called "RuntimePaintingExample.cs".
  2. Copy source listing from above.
  3. Attach script to a game object and specify the following properties using the Inspector panel:
    • The Tile System that you would like to paint on.
    • Brush to use when painting with left mouse button.
Note
Note
A slightly more advanced demonstration is provided with Rotorz Tile System.

See Rotorz/Tile System/Demo/Hat Guy/hatguy_level_designer.unity

Improve performance using bulk edit mode

The performance of painting multiple tiles sequentually can be improved using bulk edit mode:

  • Tiles that are painted using orienting brushes (including autotile brushes) can change multiple tiles as their surrounding tiles are changes. During bulk edit mode the actual creation of tiles is suppressed until all changes have been made.
  • Procedural tiles are presented using procedurally generated meshes which only need to be updated once regardless of how many tiles have been changed.
void PaintTwoTiles(int row, int column) {
    tileSystem.BeginBulkEdit();
        brush.Paint(tileSystem, row, column);
        tileSystem.RefreshSurroundingTiles(row, column);
        brush.Paint(tileSystem, row, column + 1);
        tileSystem.RefreshSurroundingTiles(row, column + 1);
    tileSystem.EndBulkEdit();
}

void PaintExampleTiles() {
    tileSystem.BeginBulkEdit();
        PaintTwoTiles(5, 5);
        PaintTwoTiles(6, 5);
    tileSystem.EndBulkEdit();
}
function PaintTwoTiles(row:int, column:int) {
    tileSystem.BeginBulkEdit();
        brush.Paint(tileSystem, row, column);
        tileSystem.RefreshSurroundingTiles(row, column);
        brush.Paint(tileSystem, row, column + 1);
        tileSystem.RefreshSurroundingTiles(row, column + 1);
    tileSystem.EndBulkEdit();
}

function PaintExampleTiles() {
    tileSystem.BeginBulkEdit();
        PaintTwoTiles(5, 5);
        PaintTwoTiles(6, 5);
    tileSystem.EndBulkEdit();
}
FigureĀ 7-3. Source Listing: Bulk editing tiles at runtime

Improve performance with pooling

By default tiles are painted using the default runtime object factory which simply instantiates tile prefabs to create tiles, and destroys tiles upon erasing them. This is generally acceptable for in-game level designers or when generating tiles at the start of a level, though you should consider a pooling solution if painting and erasing tiles in-game.

A pooling system can be utilized by providing a custom object factory implementation. You might opt to implement your very own specialized pooling solution, or simply to integrate a third-party solution.

An open-source object factory called RtsPoolManagerObjectFactory has already been implemented which provides support for PoolManager by Path-o-logical Games.

Tip
Tip
A pooling solution is only beneficial when using tile prefabs or prefab attachments. Tiles painted from a procedural tileset would otherwise not benefit from pooling.