Script de RuleTile personnalisé pour Unity2D

Analyse des ressources disponibles

Au moment de la rédaction, les documents concernant cette fonctionnalité sont très limités. Avant de poursuivre la lecture, il est impératif de maîtriser l'utilisation basique de Tilemap ainsi que le fonctionnement standard de RuleTile.

À la date du 11 juillet 2023, seules quelques références ont été identifiées :

  • Documentation officielle Unity
  • Dépôt GitHub Unity
  • Contenu technique provenant de sources communautaires
  • Ressources partiellement pertinentes issues de forums comme StackOverflow

Première implémentation

Après avoir créé un script personnalisé héritant de RuleTile, une certaine confusion peut survenir face aux options proposées. En effet, les paramètres d'entrée et les champs personnalisés ne sont pas toujours explicites.

L’attribut [CreateAssetMenu] permet de générer facilement une instnace utilisable dans l’éditeur. Une fois celui-ci appliqué, de nouvelles valeurs numériques apparaissent dans l’interface au lieu des traditionnelles icônes « ✓ » ou « ✕ ». Cela indique clairement que ces constantes définies dans le code influencent directemant le comportement des règles de placement.

Hypothèses de conception

La logique principale repose sur la méthode RuleMatch, qui détermine si une tuile adjacente satisfait ou non une condition donnée. Selon la valeur passée en paramètre (neighbor), différentes conditions peuvent être évaluées.

Les valeurs prédéfinies telles que 0 et 1 correspondent aux règles internes standards. Pour aller plus loin, il sufffit donc de redéfinir cette méthode afin d'introduire ses propres critères de correspondance.

Vérification pratique

Pour tester cette approche, voici une version modifiée du script initial :

using UnityEngine;
using UnityEngine.Tilemaps;

[CreateAssetMenu(fileName = "CustomRuleTile", menuName = "Tiles/CustomRuleTile")]
public class CustomRuleTile : RuleTile<CustomRuleTile.Adjacency> {

    // Définition des types de voisinage personnalisés
    public class Adjacency : TilingRule.Neighbor {
        public const int AnyFilled = 9;
        public const int StrictlyEmpty = 8;
    }

    public override bool RuleMatch(int neighborType, TileBase adjacentTile) {
        
        switch (neighborType) {
            case Adjacency.StrictlyEmpty:
                return adjacentTile == null;

            case Adjacency.AnyFilled:
                return adjacentTile != null;

            default:
                return base.RuleMatch(neighborType, adjacentTile);
        }
    }
}

Cette implémentation introduit deux nouveaux comportements :

  • StrictlyEmpty : Ne valide que si aucune tuile n’est présente.
  • AnyFilled : Accepte toute tuile non-nulle, sans distinction de son type.

Exemple complémentaire

Voici également un exemple tiré d’une source externe illustrant une utilisation avancée avec des propriétés spécifiques :

using System;
using UnityEngine;
using UnityEngine.Tilemaps;

[Serializable]
[CreateAssetMenu(fileName = "TerrainTile", menuName = "Tiles/TerrainTile")]
public class TerrainTile : HexagonalRuleTile<TerrainTile.Connection> {

    public bool isWater;
    public bool isMountain;

    public class Connection : TilingRule.Neighbor {
        public const int IsWaterBody = 3;
        public const int IsNotWaterBody = 4;
        public const int IsElevated = 5;
        public const int IsNotElevated = 6;
    }

    public override bool RuleMatch(int neighbor, TileBase tile) {
        var target = tile as TerrainTile;
        switch (neighbor) {
            case Connection.IsWaterBody:
                return target && target.isWater;
            case Connection.IsNotWaterBody:
                return target && !target.isWater;
            case Connection.IsElevated:
                return target && target.isMountain;
            case Connection.IsNotElevated:
                return target && !target.isMountain;
        }
        return base.RuleMatch(neighbor, tile);
    }
}

Cet exemple montre comment enrichir davantage les règles en fonction des attributs propres à chaque tuile.

Étiquettes: Unity2D Tilemap RuleTile C# GameDevelopment

Publié le 7 octobre à 10h28