Skip to content

t1k:unity:dots-rendering:perspective-3d

FieldValue
Moduledots-rendering
Version2.1.7
Efforthigh
Tools

Keywords: 3D, DOTS, perspective, rendering

/t1k:unity:dots-rendering:perspective-3d

  • 3D mesh rendering, LODGroup, skeletal animation, impostor billboard
  • Third-person camera, orbit camera, perspective projection
  • URP/Lit materials, shadow casting, light probes
  • Simulation: XZ plane (always). Standard 3D NavMesh pathfinding on XZ ground
  • Presentation: Perspective camera. 3D meshes (primitives or skeletal). LOD for performance
  • No coordinate remapping — what you see is what the simulation computes
  • Perspective camera with orbit/spring-arm or fixed angle
  • Adjust position based on battle AABB and FOV (same math as isometric)
  • Can use Cinemachine for production cameras -> See references/camera-3d-guide.md
  • Meshes: Unity primitives (Capsule, Cylinder, Sphere) or Synty Polygon skeletal models
  • Shader: Universal Render Pipeline/Lit with per-unit color and smoothness
  • LODGroup: LOD0 = full 3D mesh, LOD1 = Amplify Impostor billboard
  • Shadows: Full shadow casting enabled (unlike 2D perspectives) -> See references/rendering-3d-guide.md
  • NavigationAuthoring.EnableGrounding = true (default) — DOTSGroundingSystem applies Y
  • RangedAttackAuthoring.ArcHeight = 5f — parabolic arc projectiles
  • Standard NavMeshSurface with PhysicsColliders geometry
  • Full SonarAvoidance enabled (viable at 3D unit counts, typically < 500)
  • Skeletal: Animator + AnimatorController on mesh child (not DOTS-native yet)
  • Impostor: static billboard at LOD1 (no animation at distance)
  • Death: DeathAnimationSystem handles scale shrink (no alpha fade needed for 3D)
UnitPrefab (root — authoring components here)
├── Mesh (child — MeshFilter + MeshRenderer + LOD0)
│ └── Primitive mesh with URP/Lit material
├── LOD1_Impostor (child — MeshFilter + MeshRenderer)
│ └── Amplify Impostor mesh + tinted material
└── LODGroup (on root)
├── LOD0: transition at 0.15 → Mesh renderer
└── LOD1: transition at 0.0 (never cull) → Impostor renderer
var lodGroup = root.AddComponent<LODGroup>();
lodGroup.SetLODs(new[] {
new LOD(0.15f, new[] { lod0Renderer }), // LOD0 = 3D mesh
new LOD(0f, new[] { impostorRenderer }), // LOD1 = impostor (never cull)
});
lodGroup.RecalculateBounds();
// Per-unit material instance (don't modify shared atlas)
var tintedMat = new Material(baseMat);
tintedMat.SetColor("_BaseColor", teamColor);
AssetDatabase.CreateAsset(tintedMat, folder + name + "_Tinted.mat");
impostorRenderer.sharedMaterial = tintedMat;
#IssueFix
1Synty models: 5 SMRs + 50 bones per unit = 0.9 FPS at 100 unitsUse Amplify Impostor LOD1 at distance
2Impostor atlas shared across units — team tint modifies allCreate per-unit material instance with _BaseColor override
3Animator on source model captures dynamic pose during impostor bakeDisable Animator before baking impostors
4Lightmap baking corrupts ChunkWorldRenderBounds with NaNDo NOT bake lightmaps for DOTS entities. Use realtime lighting
5Mesh pivot at center, not feet — authoring offset neededChild mesh at (0, halfHeight, 0), root at feet
  • dots-ecs — ECS fundamentals
  • dots-rpg — Combat, stats, navigation authoring components
  • dots-graphics — RenderMeshArray, MaterialMeshInfo, LOD in ECS
  • amplify-impostors — Impostor baking workflow, atlas config, URP shader
  • dots-battlefield — ArenaConfig, tree LOD with impostors
  • unity-urp — URP/Lit shader, shadow settings, pipeline config
  • unity-shadow-optimization — Shadow cascades, light probes
  • agents-navigation — NavMesh pathfinding with grounding
  • dots-performance — Draw call reduction, chunk utilization
FileCoverage
references/rendering-3d-guide.mdLOD setup, impostor integration, mesh rendering, materials
references/camera-3d-guide.mdPerspective camera, orbit patterns, FOV-based framing