# Custom Generators & Modifiers

With TileWorldCreator you can easily create custom generators of modifiers for blueprint layers.

Simply create a new class and inherit from:

```csharp
BlueprintModifier
```

Add the Modifier attribute to your class:

```csharp
 [Modifier(ModifierAttribute.Category.Generators, "My Generator", "")]
```

Override the **Execute** method and add your logic there. The Execute method must return a HashSet\<Vector2> with the modified/generated positions.

```csharp
HashSet<Vector2> Execute(HashSet<Vector2> _positions, BlueprintLayer _layer)
```

## Example

```csharp
[Modifier(ModifierAttribute.Category.Generators, "Random Noise", "")]
public class RandomNoise : BlueprintModifier
{

    public float weight = 0.5f;
    public int rndSeed;

    private int width;
    private int height;
    
    public override HashSet<Vector2> Execute(HashSet<Vector2> _positions, BlueprintLayer _layer)
    {
        // Get the map width and height
        width = asset.width;
        height = asset.height;
        
        for (int x = 0; x < width; x ++)
        {
            for (int y = 0; y < height; y ++)
            {
                // Use the layers random struct.
                float sample = Mathf.PerlinNoise((float)x / (float)width + _layer.random.NextFloat(0, 100), (float)y / (float)height + _layer.random.NextFloat(0, 100));
                
                if (sample > weight)
                {
                    _positions.Add(new Vector2(x, y));
                }
            }
        }

        return _positions;
    }
}
```

## Create custom UI

You can create a custom UI for your modifier by overriding the **BuildInspector** method.

```csharp
public override VisualElement BuildInspector(Configuration _asset)
{
    var _serializedObject = new SerializedObject(this);

    var _root = new VisualElement();
    
    var _label = new Label();
    _label.text = "Custom UI";

    var _weightField = new PropertyField();
    _weightField.BindProperty(_serializedObject.FindProperty(nameof(weight));
    
    _root.Add(_weightField);

    return _root;
}
```

You may want to hide properties by default when creating a custom UI for those. Simply add the **\[HideInInspector]** attribute to it.

```csharp
[HideInInspector]
public float weight = 0.5f;
```

## Blueprint Layer Dropdown

TileWorldCreator has a custom Blueprintlayer dropdown UI Element which can be used if you want to create a custom UI where the user can select a blueprint layer.

<div align="left"><figure><img src="https://2133013324-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfgGGWDc5VbrbZt1JQsfN%2Fuploads%2FzcIZAvpLkp8o6JGrH8fd%2FBlueprintLayerDropdown.png?alt=media&#x26;token=31b05113-93e9-42d7-a5e4-707ee94ef867" alt=""><figcaption></figcaption></figure></div>

```csharp
LayerSelectDropdownElement(Configuration asset, string selectedLayerGuid, Action<string,string> _onSelectedCallback, string _label = "");
```

<pre class="language-csharp"><code class="lang-csharp">[HideInInspector]
public string selectedLayerGuid

<strong>public override VisualElement BuildInspector(Configuration _asset)
</strong>{
    // Use the LayerSelectDropdownElement to assign a blueprint layer guid
    var _selectedLayerField = new LayerSelectDropdownElement(_asset, selectedLayerGuid, SelectLayer, "Selected Layer");
    _root.Add(_selectedLayerField);

    return _root;
}

// Callback called by the LayerSelectDropdownElement on selection
void SelectLayer(string _layerName, string _layerGuid)
{
    // Assign selected GUID
    selectedLayerGuid = _layerGuid;
}
</code></pre>
