t1k:unity:dots-rendering:perspective-framework
| Field | Value |
|---|---|
| Module | dots-rendering |
| Version | 2.1.7 |
| Effort | high |
| Tools | — |
Keywords: DOTS, framework, perspective, rendering
How to invoke
Section titled “How to invoke”/t1k:unity:dots-rendering:perspective-frameworkDOTS Perspective Framework
Section titled “DOTS Perspective Framework”Shared foundation patterns used by all 4 perspective skills. Each perspective skill extends this with dimension-specific overrides. Does NOT handle perspective-specific logic — see per-perspective skills below.
Perspective Skills Map
Section titled “Perspective Skills Map”| Perspective | Skill | Key Overrides |
|---|---|---|
| 2D top-down | dots-perspective-2d-topdown | Ortho -Y camera, XZ-plane quads |
| 2D side-view | dots-perspective-2d-sideview | Ortho +Z camera, XY-plane quads |
| Isometric | dots-perspective-isometric | Iso projection, diamond layout |
| 3D | dots-perspective-3d | Perspective camera, world-space meshes |
Common Quad Mesh Creation
Section titled “Common Quad Mesh Creation”// Vertices (CCW winding, local space, centered at origin)var verts = new NativeArray<float3>(4, Allocator.Temp){ [0] = new float3(-0.5f, 0f, 0.5f), // TL [1] = new float3( 0.5f, 0f, 0.5f), // TR [2] = new float3( 0.5f, 0f, -0.5f), // BR [3] = new float3(-0.5f, 0f, -0.5f), // BL};// UVsvar uvs = new NativeArray<float2>(4, Allocator.Temp){ [0] = new float2(0,1), [1] = new float2(1,1), [2] = new float2(1,0), [3] = new float2(0,0),};// Normals (all up for floor quad; override per-perspective for billboards)var normals = new NativeArray<float3>(4, Allocator.Temp);for (int i = 0; i < 4; i++) normals[i] = math.up();// Trianglesvar tris = new NativeArray<int>(6, Allocator.Temp) { [0]=0,[1]=1,[2]=2,[3]=0,[4]=2,[5]=3 };Billboard quads: normals face camera — override normals in perspective skill, or use Shader Graph Vertex Normal node.
Cutout Material Setup (URP/Unlit)
Section titled “Cutout Material Setup (URP/Unlit)”- Shader:
Universal Render Pipeline/Unlitor custom Shader Graph - Surface Type:
TransparentwithAlpha Clippingenabled - Properties:
_BaseMap(sprite atlas),_Cutoff(0.5 default) - In Shader Graph: connect
Alphaoutput →Alpha Clip Thresholdnode
Per-perspective skills specify whether to use Unlit, Lit, or custom shader.
Camera Bridge Pattern (MonoBehaviour → ECS Singleton)
Section titled “Camera Bridge Pattern (MonoBehaviour → ECS Singleton)”// MonoBehaviour side — runs in managed worldpublic class CameraBridge : MonoBehaviour{ void LateUpdate() { var world = World.DefaultGameObjectInjectionWorld; if (world == null) return; // Write camera data to singleton component var em = world.EntityManager; var query = em.CreateEntityQuery(typeof(CameraData)); if (query.TryGetSingleton<CameraData>(out _)) { query.SetSingleton(new CameraData { Position = transform.position, Forward = transform.forward, }); } }}// ECS side — IComponentData singletonpublic struct CameraData : IComponentData{ public float3 Position; public float3 Forward;}Each perspective skill defines its own CameraData fields (e.g., orthoSize, isoAngle).
Sprite Animation Base Flow
Section titled “Sprite Animation Base Flow”SpriteAnimationAuthoring— exposes frame count, fps, atlas reference in Inspector- Baker bakes to
SpriteAnimationDatacomponent (frameCount, fps, currentFrame, timer) SpriteAnimationSystem(Burst) — increments timer, advances currentFrame, updates UV offset onMaterialMeshInfo
Per-perspective skills extend this with direction-based animation (8-dir top-down, 4-dir side-view).
Death Fade Pattern
Section titled “Death Fade Pattern”Component: DeathFade : IComponentData { float Timer; float Duration; }
System: increment Timer each frame, compute alpha = 1 - Timer/Duration, set material alpha via MaterialMeshInfo or property block, destroy entity when Timer >= Duration (via BeginSim ECB).
Dissolve variant: drive _Dissolve shader property instead of alpha.
Navigation Surface Setup (Common Config)
Section titled “Navigation Surface Setup (Common Config)”NavMeshSurfacecomponent:Agent Type = Humanoid,Collect Objects = Volume- Bake bounds: cover entire playable area + 5 unit margin
Use Geometry = Physics Colliders(not render mesh) for performance- Per-perspective skills specify bake plane (XZ for top-down/3D, XY for side-view).
Detection Radius Scaling
Section titled “Detection Radius Scaling”Perspective affects perceived FOV — scale detection radius:
- Top-down / Isometric:
worldRadius = designRadius(1:1, orthographic) - Side-view:
worldRadius = designRadius × 0.7(Z-depth compressed) - 3D perspective:
worldRadius = designRadiusbut apply FOV cone check
Reference Files
Section titled “Reference Files”| Cross-Reference | Content |
|---|---|
→ See dots-perspective-2d-topdown | Top-down overrides |
→ See dots-perspective-2d-sideview | Side-view overrides |
→ See dots-perspective-isometric | Isometric overrides |
→ See dots-perspective-3d | 3D perspective overrides |
→ See dots-graphics | Rendering pipeline details |
→ See unity-urp | URP material/shader config |
→ See agents-navigation | NavMesh + DOTS agent patterns |
Gotchas
Section titled “Gotchas”- Singleton CameraData lifecycle bound to active scene — replaying scene without resetting the singleton leaks last-scene’s camera transform into the next.
World.DefaultGameObjectInjectionWorldis null in editor before play-mode starts — guard withif (world == null) returnin every system that reads it.- Multi-camera (split-screen) breaks the singleton model — the framework assumes one CameraData; split-screen requires per-camera entity refactor.
LateUpdateordering across systems is not deterministic — if perspective writes after the renderer reads, frames render with last-frame data.