# Custom Logic

## Player Level

Skills support player level requirements—preventing upgrading if the required level is not met. If you'd like to use custom logic to get the player level, use the `SkillNode.playerLevelGetter` field.

By default, the `SkillWeb.playerLevel` field is used. The example below sets a custom one.

```csharp
public class PlayerLevelGetterExample : MonoBehaviour
{
    public int myPlayerLevel;

    private void Awake()
    {
        SkillNode.playerLevelGetter = () =>
        {
            return myPlayerLevel;
        };
    }
}
```

## Custom Upgrade/Downgrade Logic

You can add on to the upgrade/downgrade prevention logic to add your own upgrade/downgrade requirements. You can implement your own logic by using the `SkillNode.canUpgrade` and `SkillNode.canDowngrade` fields. By default, both simply return `true`.

```csharp
/// <summary>
/// Sets a custom upgrade method. This uses an example custom dataset.
/// </summary>
public void SetCustomUpgradeMethod()
{
    SkillNode.canUpgrade = skillNode =>
    {
        // Get the custom dataset
        var myDataset = skillNode.dataset as MySkillDataset;

        // Allow upgrading only if the skill is cool
        return myDataset.isCool;
    };
}

/// <summary>
/// Sets a custom downgrade method. This uses an example custom dataset.
/// </summary>
public void SetCustomDowngradeMethod()
{
    SkillNode.canDowngrade = skillNode =>
    {
        // Get the custom dataset
        var myDataset = skillNode.dataset as MySkillDataset;

        // Allow downgrading only if the skill is cool
        return myDataset.isCool;
    };
}
```

## Skill Points Binding

By default, every [web](https://stylishesper.gitbook.io/skill-web/scripting/api/graph/web "mention") simply uses the `SkillWeb.skillPoints` field as the reference of the player's current skill points. You can bind your own numeric skill points field for each web. The supported numeric types are `int`, `float` and `double`.

```csharp
public class SkillPointsBinder : MonoBehaviour
{
    public float mySkillPoints;

    private void Awake()
    {
        // Get a web
        var myWebGraph = SkillWeb.GetWebGraph("My Web Graph");
        var myWeb = new Web(myWebGraph);

        // Bind a value
        myWeb.Bind(() => mySkillPoints, // Set skill points getter
            skillNode => (skillNode.dataset as MySkillDataset).cost, // Set skill cost getter (this example uses a custom dataset)
            x => mySkillPoints = x); // Set skill points setter  
    }
}
```

## Custom Upgrade/Downgrade Flow

By default, the UI simply upgrades or downgrades a skill when you click on a skill node with the appropriate button. You can actually override this behavior by implementing your own version of the skill node by inheriting from the [skill-node-ugui](https://stylishesper.gitbook.io/skill-web/scripting/api/ui/ugui/skill-node-ugui "mention") class.

This new class would have to replace the [skill-node-ugui](https://stylishesper.gitbook.io/skill-web/editors/components/ugui/skill-node-ugui "mention") component of your skill node prefab.

The example below uses a custom dialog box which will only allow downgrading if the "Confirm" button is pressed.

```csharp
public class MySkillNode : SkillNodeUGUI
{
    public override bool TryDowngrade()
    {
        // Display a custom confirmation box
        MyDialogBox.Instance.DisplayDialog(
            title: "Downgrade Skill?",
            description: "Downgrading this skill will also remove any skills that depend on it. Are you sure you want to continue?",
            onConfirm: () => base.TryDowngrade(), // Call base downgrade method on confirm pressed
            onCancel: () => { }); // Do nothing on cancel pressed (or close the confirmation prompt)

        // Simply return true by default since we're not utilizing the return type at all
        return true;
    }
}
```
