TileConfigurationRule.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using DunGen.Editor.Validation;
  2. using DunGen.Graph;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using UnityEngine;
  7. using UnityEngine.Tilemaps;
  8. namespace DunGen.Assets.DunGen.Code.Editor.Validation.Rules
  9. {
  10. sealed class TileConfigurationRule : IValidationRule
  11. {
  12. public void Validate(DungeonFlow flow, DungeonValidator validator)
  13. {
  14. var tilePrefabs = flow.GetUsedTileSets()
  15. .SelectMany(ts => ts.TileWeights.Weights.Select(w => w.Value))
  16. .Where(t => t != null)
  17. .ToArray();
  18. CheckTileComponents(flow, validator, tilePrefabs);
  19. CheckTilemaps(flow, validator, tilePrefabs);
  20. CheckTerrains(flow, validator, tilePrefabs);
  21. }
  22. // Check to see if all of our tile prefabs have a Tile component
  23. private void CheckTileComponents(DungeonFlow flow, DungeonValidator validator, GameObject[] tilePrefabs)
  24. {
  25. foreach(var tileObj in tilePrefabs)
  26. {
  27. var tile = tileObj.GetComponent<Tile>();
  28. if (tile == null)
  29. validator.AddWarning($"Tile prefab '{tileObj.name}' is missing a Tile component", tileObj);
  30. }
  31. }
  32. // Checks every tile and logs a warning if any have a Tilemap and are using automatic bounds calculations
  33. // Unity's tilemap doesn't have accurate bounds when first instantiated and so must use overridden tile bounds
  34. private void CheckTilemaps(DungeonFlow flow, DungeonValidator validator, IEnumerable<GameObject> tilePrefabs)
  35. {
  36. foreach (var tileObj in tilePrefabs)
  37. {
  38. var tile = tileObj.GetComponent<Tile>();
  39. if (tile == null || !tile.OverrideAutomaticTileBounds)
  40. {
  41. var tilemap = tileObj.GetComponentInChildren<Tilemap>();
  42. if (tilemap != null)
  43. validator.AddWarning("[Tile: {0}] Automatic tile bounds don't work correctly with Unity's tilemaps. Check 'Override Automatic Tile Bounds' on your tile component and press the 'Fit to Tile' button", tileObj, tileObj.name);
  44. }
  45. }
  46. }
  47. // Unity terrain cannot be rotated, so we have to ensure tiles containing terrains are set to disallow rotation
  48. private void CheckTerrains(DungeonFlow flow, DungeonValidator validator, IEnumerable<GameObject> tilePrefabs)
  49. {
  50. foreach (var tileObj in tilePrefabs)
  51. {
  52. if (tileObj.GetComponentInChildren<Terrain>() == null)
  53. continue;
  54. var tile = tileObj.GetComponent<Tile>();
  55. if (tile == null || tile.AllowRotation)
  56. validator.AddError("[Tile: {0}] Tile contains a Unity terrain which cannot be rotated. The tile should have 'Allow Rotation' unchecked", tileObj, tileObj.name);
  57. }
  58. }
  59. }
  60. }