Skip to content

t1k:unity:dots-nav:battlefield

FieldValue
Moduledots-nav
Version2.1.7
Efforthigh
Tools

Keywords: battlefield, combat, DOTS, strategy

/t1k:unity:dots-nav:battlefield

DOTS Battlefield — Arena Geometry Package

Section titled “DOTS Battlefield — Arena Geometry Package”

Render Pipeline: URP ONLY — All terrain shaders, materials, and visual effects must target URP. Never create Built-in RP or HDRP materials.

Related skills: /synty-polygon-generic + /synty-polygon-knights (prefab catalogs), /agents-navigation (NavMeshSurface, CrowdSurface), /dots-physics (PhysicsCollider, DOTS raycasts), /unity-terrain (TerrainData, heightmap).

Package: com.the1studio.dots-battlefield (embedded in Packages/) Does NOT handle: agent AI logic, combat, spawning, behavior trees.

ArenaConfig (ScriptableObject) — Runtime
├── Grid: Width, Depth, TileSize
├── Obstacles: Density, Seed, PreMadePrefabs[]
├── Spawn: CenterA, CenterB, ClearRadius
├── Elevation: Variance (0=flat, >0=hills)
├── Terrain Noise: NoiseScale, NoiseOctaves, Persistence, Lacunarity
├── Ridge/Cliff: RidgePower, CliffThreshold
├── Boundaries: WallHeight, WallThickness
└── OutputFolder → computed path helpers
Editor Tools (menu items invokable by AI via MCP execute_menu_item):
├── Tools/DOTSBattlefield/Create Prefabs
├── Tools/DOTSBattlefield/Assemble Arena
└── Tools/DOTSBattlefield/Generate Procedural Terrain
  1. Create config: Assets > Create > DOTSBattlefield > Arena Config
  2. Set OutputFolder on config (e.g. Demos/MyGame -> assets go to Assets/Demos/MyGame/...)
  3. Create prefabs: Execute Tools/DOTSBattlefield/Create Prefabs
  4. Choose approach:
    • Tile-based: Tools/DOTSBattlefield/Assemble Arena
    • Procedural mesh: Tools/DOTSBattlefield/Generate Procedural Terrain
  5. Verify navigation: Agents get DOTSGrounding (DOTS Physics raycasts) via NavigationAuthoring.EnableGrounding
  • No hardcoded values: All tunable params live on ArenaConfig; implementation details use private const
  • Config lookup: All tools use ConfigLookup.FindConfig() — finds first t:ArenaConfig in project
  • OutputFolder: All generated assets (materials, meshes, prefabs) go under Assets/{OutputFolder}/
  • Spawn zones: SpawnCenterA/SpawnCenterB with SpawnClearRadius — obstacles excluded, terrain flattened
  • NavMesh: Auto-baked with CollectObjects.Volume + PhysicsColliders — volume auto-sized to arena bounds
  • Single NavMeshSurface: Generator removes stale NavMeshSurface from old “Ground” GO to prevent conflicts
  • Pre-made assets: Assign FBX/glTF to PreMadeObstaclePrefabs[] array on config
  • Seed-based: Obstacle placement is deterministic via Seed field
  • Idempotent: Tools skip existing prefabs/materials; assembly destroys old root first

-> See references/terrain-guide.md for terrain tuning fields and VertexColorTerrain shader details.

When ElevationVariance > 0, agents need terrain-aware navigation:

ComponentPurposeSource
NavMeshPathPathfinding on baked NavMeshNavigationAuthoring.EnableNavMeshPathing
DOTSGroundingY-snap via DOTS Physics raycastsNavigationAuthoring.EnableGrounding

The original AgentGroundingSystem uses classic Unity RaycastCommand (MonoBehaviour physics). When terrain and obstacles live in a SubScene, their MeshCollider components get baked to DOTS PhysicsCollider — classic raycasts can’t see them. DOTSGroundingSystem uses CollisionWorld.CastRay() instead.

  • Component: DOTSGrounding (IComponentData + IEnableableComponent) — MaxRayDistance (default 50f) + CollisionFilter (default: collide with all)
  • System: DOTSGroundingSystem in AgentDisplacementSystemGroup — applies gravity, casts DOTS Physics ray downward, snaps Y to hit.Position.y + halfHeight
  • Baking: NavigationAuthoring.EnableGrounding = true bakes DOTSGrounding (NOT AgentGrounding)
  • asmdef: DOTSNavigation references Unity.Physics

TerrainHeightSampler provides bilinear-interpolated height sampling from the procedural heightmap. Used by PlaceObstacles() and PlaceBoundaryWalls(). When called from ProceduralTerrainGenerator, the heightmap is generated first. When called from AssembleBattlefield (tile-based), heightmap is null and Y defaults to 0.

  • CollectObjects.Children excludes root GO’s mesh — use Volume mode
  • Multiple NavMeshSurface in one scene causes erratic pathing — keep only one
  • After code changes, clear Library/EntityScenes/ to force SubScene rebake
  • Obstacles placed at Y=0 clip through elevated terrain — always pass heightmap when ElevationVariance > 0
  • NavMeshObstacle carving required (CRITICAL): (StaticEditorFlags)8 (NavigationStatic) + SetNavMeshArea(obs, 1) only marks the obstacle’s own surface as “Not Walkable”. Always use NavMeshObstacle with carving = true instead
  • HealthBarRenderer missing from scene (CRITICAL): HealthBarAuthoring only bakes ECS data — actual rendering requires HealthBarRenderer MonoBehaviour on the Camera + DOTSCore/HealthBar shader material
  • Obstacle/primitive pivot at center (CRITICAL): Unity primitives have pivot at center, not bottom. Use bounds-based offset after instantiation
  • DOTSGroundingSystem must be [BurstCompile] with IJobEntity — raycasts every frame for all agents
  • CollisionFilter on DOTSGrounding should target terrain layer only — reduces broadphase search
  • NavMesh baking: Use CollectObjects.Volume (not Children) — volume is pre-bounded, faster bake
  • Static obstacles: Baked into SubScene as static physics bodies — zero runtime cost after bake

-> See dots-performance skill for rendering optimization checklist and impostor LOD details.

  • BaseHealth and BaseHealthSystem are missing from DOTSCombat.Structures — BattlefieldDemo and several arena demos define local BaseHealth IComponentData instead of using the library struct. As of 260520-R5, this gap is tracked for extraction into DOTSCombat.Structures. Until extracted, import from the demo-local type and plan migration. Source: review-260520-round5-extraction-skills.md §B P0