jueves, 3 de abril de 2025

ECS en Unity: componiendo juegos que escalan



Por qué te importa: el modelo Entidad-Componente-Sistema separa datos, comportamiento y procesamiento, reduciendo dependencias y haciendo fácil añadir/quitar habilidades.

Qué significa ECS en Unity

  • Entidad: un ID o GameObject que “agrega cosas”.

  • Componente (datos): trocitos de estado (salud, velocidad…).

  • Sistema (lógica): procesa lotes de entidades con ciertos componentes.

Nota: Puedes aplicar la filosofía ECS con MonoBehaviour (composición clásica) o con Unity Entities (DOTS).

Te irá bien cuando tengas muchos objetos similares (bullets, partículas con lógica, enjambres) y cuando necesites rendimiento y sistemas desacoplados.

Aquí va un enfoque práctico con MonoBehaviour + un ejemplo mínimo en DOTS.

Enfoque práctico con MonoBehaviour

Componentes de datos (POCOs)

// Datos puros (no heredan de MonoBehaviour) [System.Serializable] public class HealthData { public int Max = 100; public int Current = 100; } [System.Serializable] public class MoveData { public float Speed = 5f; }

Bridges en GameObjects

using UnityEngine; public class Health : MonoBehaviour { public HealthData Data = new HealthData(); public bool IsDead => Data.Current <= 0; } public class Mover : MonoBehaviour { public MoveData Data = new MoveData(); public Vector3 Direction; }

Sistema (procesa muchos)

using UnityEngine; public class MovementSystem : MonoBehaviour { Mover[] movers; void Awake() => movers = FindObjectsOfType<Mover>(); void Update() { float dt = Time.deltaTime; foreach (var m in movers) { if (!m.enabled) continue; m.transform.position += m.Data.Speed * dt * m.Direction.normalized; } } }

Añadir/quitar comportamiento

// Convertir un NPC en volador: añade un componente "Fly" public class Fly : MonoBehaviour { public float HoverAmplitude = 0.25f; public float HoverSpeed = 3f; float t; void Update() { t += Time.deltaTime * HoverSpeed; transform.position += Vector3.up * Mathf.Sin(t) * HoverAmplitude * Time.deltaTime; } 


Variante mínima con Unity Entities (DOTS)

(requieres el package Entities; nombres pueden variar según versión)

// Components (IComponentData) using Unity.Entities; using Unity.Mathematics; public struct MoveSpeed : IComponentData { public float Value; } public struct Direction : IComponentData { public float3 Value; }

// System (ISystem / SystemBase) using Unity.Burst; using Unity.Entities; using Unity.Transforms; using Unity.Mathematics; [BurstCompile] public partial struct MovementSystem : ISystem { public void OnUpdate(ref SystemState state) { float dt = SystemAPI.Time.DeltaTime; foreach (var (speed, dir, transform) in SystemAPI.Query<RefRO<MoveSpeed>, RefRO<Direction>, RefRW<LocalTransform>>()) { var t = transform.ValueRO; t.Position += dir.ValueRO.Value * speed.ValueRO.Value * dt; transform.ValueRW = t; } } }

No hay comentarios:

Publicar un comentario