
Cibernàrium · Barcelona ActivaCibernàrium · Barcelona Activa
Curso de Unity en Barcelona: crea y publica tu videojuego en Steam con la ayuda de la IA y las nuevas tecnologíasCurs de Unity a Barcelona: crea i publica el teu videojoc a Steam amb l'ajuda de la IA i les noves tecnologies
Un curso de Unity en Barcelona para llevar un videojuego pequeño de la idea a la página de Steam en cinco sesiones. Trabajamos con Unity 6 y nos apoyamos en la IA y en las nuevas tecnologías del sector: IA generativa para modelos, texturas y sonido, agentes conectados al editor por MCP, APIs y Blender. Cada participante termina con su propio Arena Survivor 3D jugable.Un curs de Unity a Barcelona per portar un videojoc petit de la idea a la pàgina de Steam en cinc sessions. Treballem amb Unity 6 i ens recolzem en la IA i en les noves tecnologies del sector: IA generativa per a models, textures i so, agents connectats a l'editor per MCP, APIs i Blender. Cada participant acaba amb el seu propi Arena Survivor 3D jugable.
- 15 horas15 hores
- 5 sesiones de 3 h5 sessions de 3 h
- Presencial en el CibernàriumPresencial al Cibernàrium
- Clases en catalánClasses en català
- Nivel intermedioNivell intermedi
El proyecto: Arena Survivor 3DEl projecte: Arena Survivor 3D
El jugador se mueve por una arena vista desde arriba, dispara solo al enemigo más cercano y recoge experiencia. Cada vez que sube de nivel elige una de tres mejoras, mientras las oleadas de enemigos se vuelven más rápidas y densas. Es un formato que cabe en quince horas y que se puede seguir ampliando al terminar el curso.El jugador es mou per una arena vista des de dalt, dispara sol a l'enemic més proper i recull experiència. Cada cop que puja de nivell tria una de tres millores, mentre les onades d'enemics es fan més ràpides i més denses. És un format que cap en quinze hores i que es pot continuar ampliant quan acaba el curs.
Cada sesión deja una versión del juego que funciona y queda guardada en Git, de la v0.1 a la v1.0. Si una sesión se complica, siempre se puede volver a la versión anterior y seguir.Cada sessió deixa una versió del joc que funciona i queda desada a Git, de la v0.1 a la v1.0. Si una sessió es complica, sempre es pot tornar a la versió anterior i continuar.
- v0.1Arena y jugador con cámaraArena i jugador amb càmera
- v0.2Enemigos, oleadas y combateEnemics, onades i combat
- v0.3Arte, animaciones y sonido propiosArt, animacions i so propis
- v0.4Partida completa con mejoras y menúsPartida completa amb millores i menús
- v1.0Build y página de SteamBuild i pàgina de Steam
Temario del curso de UnityTemari del curs de Unity
Cinco sesiones de tres horas. Cada una combina una demostración breve, práctica guiada y tiempo para avanzar en el proyecto propio.Cinc sessions de tres hores. Cada una combina una demostració breu, pràctica guiada i temps per avançar en el projecte propi.
SesiónSessió 1
Planificación del proyecto y Unity 6Planificació del projecte i Unity 6
- Del concepto al alcance: documento de diseño de una página, vertical slice y lista de tareasDel concepte a l'abast: document de disseny d'una pàgina, llesca vertical i llista de tasques
- Unity 6 hoy: Unity 6.3 LTS y versiones Update, cuándo elegir cada una, Unity Hub y plantilla Universal 3D (URP)Unity 6 avui: Unity 6.3 LTS i versions Update, quan triar cada una, Unity Hub i plantilla Universal 3D (URP)
- Novedades de Unity 6 para proyectos independientes: Build Profiles, mejoras de URP, UI ToolkitNovetats de Unity 6 per a projectes independents: Build Profiles, millores d'URP, UI Toolkit
- Licencia Personal, cuenta de Unity y proyecto conectado a Unity CloudLlicència Personal, compte de Unity i projecte connectat a Unity Cloud
- Control de versiones con Git y GitHub DesktopControl de versions amb Git i GitHub Desktop
- Prototipo: arena con assets gratuitos, jugador con Input System y cámara con CinemachinePrototip: arena amb assets gratuïts, jugador amb Input System i càmera amb Cinemachine
Al final de la sesiónAl final de la sessió v0.1 · Arena y jugador controlable con cámarav0.1 · Arena i jugador controlable amb càmera
Documentación oficialDocumentació oficial
- Manual de Unity 6.3 LTSManual de Unity 6.3 LTS
- Instalar Unity y Unity HubInstal·lar Unity i Unity Hub
- Build ProfilesBuild Profiles
- Input System 1.20Input System 1.20
- Input System: acciones de proyectoInput System: accions de projecte
- Cinemachine 3Cinemachine 3
- GitHub DesktopGitHub Desktop
- Unity.gitignoreUnity.gitignore
SesiónSessió 2
Programar con IA: Unity AI, agentes y MCPProgramar amb IA: Unity AI, agents i MCP
- Unity AI: Assistant dentro del editor, Generators y AI Gateway; estado de la beta y créditosUnity AI: Assistant dins l'editor, Generators i AI Gateway; estat de la beta i crèdits
- Qué es MCP y cómo conecta un agente con la escena, la consola y los componentes de UnityQuè és MCP i com connecta un agent amb l'escena, la consola i els components de Unity
- Conexión de Claude Code, Codex o Cursor con Unity mediante la Unity CLI o un servidor MCP de la comunidadConnexió de Claude Code, Codex o Cursor amb Unity a través de la Unity CLI o d'un servidor MCP de la comunitat
- Trabajar con un agente: instrucciones con contexto, revisión del código y commits pequeñosTreballar amb un agent: instruccions amb context, revisió del codi i commits petits
- Enemigos que persiguen al jugador con NavMeshEnemics que persegueixen el jugador amb NavMesh
- Generador de oleadas, ataque automático, vida y dañoGenerador d'onades, atac automàtic, vida i dany
- Datos del juego con ScriptableObjectsDades del joc amb ScriptableObjects
Al final de la sesiónAl final de la sessió v0.2 · Enemigos, oleadas y combate funcionandov0.2 · Enemics, onades i combat funcionant
Documentación oficialDocumentació oficial
- Unity AI AssistantUnity AI Assistant
- Unity CLI para agentes (sustituye al servidor MCP)Unity CLI per a agents (substitueix el servidor MCP)
- Unity AI: funciones y créditosUnity AI: funcions i crèdits
- Model Context ProtocolModel Context Protocol
- Claude Code y MCPClaude Code i MCP
- mcp-unity (comunidad)mcp-unity (comunitat)
- AI Navigation (NavMesh)AI Navigation (NavMesh)
- ScriptableObjectScriptableObject
- Rigidbody.linearVelocityRigidbody.linearVelocity
SesiónSessió 3
Arte y sonido con IA generativa y BlenderArt i so amb IA generativa i Blender
- Generación de modelos 3D con IA a partir de texto o imagenGeneració de models 3D amb IA a partir de text o imatge
- Blender: limpieza de malla, reducción de polígonos, escala, pivote y exportación FBXBlender: neteja de malla, reducció de polígons, escala, pivot i exportació FBX
- Agente conectado a Blender por MCP para automatizar tareas repetitivasAgent connectat a Blender per MCP per automatitzar tasques repetitives
- Rigging y animaciones automáticas con Mixamo; Animator y estadosRigging i animacions automàtiques amb Mixamo; Animator i estats
- Texturas y materiales PBR generados con IATextures i materials PBR generats amb IA
- Efectos de sonido y música con IA; licencias y uso comercialEfectes de so i música amb IA; llicències i ús comercial
- Partículas para impactos, recogida de experiencia y mejorasPartícules per a impactes, recollida d'experiència i millores
Al final de la sesiónAl final de la sessió v0.3 · Personajes, decorado, animaciones y sonido propiosv0.3 · Personatges, decorat, animacions i so propis
Documentación oficialDocumentació oficial
- Manual de BlenderManual de Blender
- Blender: importar y exportar FBXBlender: importar i exportar FBX
- blender-mcpblender-mcp
- MixamoMixamo
- Animator ControllerAnimator Controller
- Sistema de partículasSistema de partícules
- Poly Haven: licencia CC0Poly Haven: llicència CC0
- Kenney: licencia CC0Kenney: llicència CC0
- Quaternius: licenciaQuaternius: llicència
SesiónSessió 4
Bucle de juego e interfaz de usuarioBucle de joc i interfície d'usuari
- Experiencia, niveles y menú de mejoras aleatoriasExperiència, nivells i menú de millores aleatòries
- Curva de dificultad y equilibrio de las oleadasCorba de dificultat i equilibri de les onades
- HUD, menú principal, pausa y pantalla de fin de partida con UI ToolkitHUD, menú principal, pausa i pantalla de final de partida amb UI Toolkit
- Audio Mixer y opciones de volumenAudio Mixer i opcions de volum
- Guardar récords y preferenciasDesar rècords i preferències
- Pruebas de juego entre participantes y ajustesProves de joc entre participants i ajustos
Al final de la sesiónAl final de la sessió v0.4 · Partida completa con mejoras, menús y récordsv0.4 · Partida completa amb millores, menús i rècords
Documentación oficialDocumentació oficial
SesiónSessió 5
Build y publicación en SteamBuild i publicació a Steam
- Build Profiles, optimización básica con el Profiler y build para Windows y macOSBuild Profiles, optimització bàsica amb el Profiler i build per a Windows i macOS
- Steamworks: alta de desarrollador, tasa de Steam Direct y App IDSteamworks: alta de desenvolupador, quota de Steam Direct i App ID
- Integración con Steamworks.NET: inicialización y logrosIntegració amb Steamworks.NET: inicialització i assoliments
- SteamPipe: depots y subida de la buildSteamPipe: depots i pujada de la build
- Página de tienda: cápsulas, capturas, tráiler, descripción y declaración de contenido con IAPàgina de botiga: càpsules, captures, tràiler, descripció i declaració de contingut amb IA
- Estado «Próximamente», listas de deseados y Steam Next FestEstat «Properament», llistes de desitjos i Steam Next Fest
Al final de la sesiónAl final de la sessió v1.0 · Build final y página de Steam preparadav1.0 · Build final i pàgina de Steam preparada
Documentación oficialDocumentació oficial
- Build ProfilesBuild Profiles
- ProfilerProfiler
- Documentación de SteamworksDocumentació de Steamworks
- Steam DirectSteam Direct
- Steamworks.NET: instalaciónSteamworks.NET: instal·lació
- SteamPipe: subir contenidoSteamPipe: pujar contingut
- Recursos gráficos de la tiendaRecursos gràfics de la botiga
- Página «Coming Soon»Pàgina «Coming Soon»
- Cuestionario de contenido (IA)Qüestionari de contingut (IA)
- Steam Next FestSteam Next Fest
Manual de prácticaManual de pràctica
Este manual sigue el proyecto paso a paso. Cada sesión tiene los pasos en el editor, el código C# completo, instrucciones de ejemplo para el agente conectado por MCP y un punto de control antes del commit. El código es válido para Unity 6.3 LTS con la plantilla Universal 3D.Aquest manual segueix el projecte pas a pas. Cada sessió té els passos a l'editor, el codi C# complet, instruccions d'exemple per a l'agent connectat per MCP i un punt de control abans del commit. El codi és vàlid per a Unity 6.3 LTS amb la plantilla Universal 3D.
1Planificación del proyecto y Unity 6Planificació del projecte i Unity 6
ObjetivoObjectiu. Crear el proyecto, dejarlo bajo control de versiones y tener un jugador que se mueve por la arena con la cámara detrás.Crear el projecte, deixar-lo sota control de versions i tenir un jugador que es mou per l'arena amb la càmera al darrere.
Instala Unity 6.3 LTS desde Unity Hub, con los módulos de build para Windows o macOS según tu equipo.Instal·la Unity 6.3 LTS des de Unity Hub, amb els mòduls de build per a Windows o macOS segons el teu equip.
Crea el proyecto con la plantilla Universal 3D y el nombre
ArenaSurvivor. Activa la opción de conectarlo a Unity Cloud; la necesitaremos para Unity AI.Crea el projecte amb la plantilla Universal 3D i el nomArenaSurvivor. Activa l'opció de connectar-lo a Unity Cloud; la necessitarem per a Unity AI.Escribe el documento de diseño en una sola página: bucle de juego, controles, condición de derrota, tres tipos de mejora y lo que queda fuera del alcance. Este documento es el contexto que luego daremos al agente.Escriu el document de disseny en una sola pàgina: bucle de joc, controls, condició de derrota, tres tipus de millora i el que queda fora de l'abast. Aquest document és el context que després donarem a l'agent.
Pon el proyecto en Git. En GitHub Desktop, File › Add local repository, elige la carpeta del proyecto y crea el repositorio. Añade el archivo
.gitignorede Unity en la raíz y haz el primer commit.Posa el projecte a Git. A GitHub Desktop, File › Add local repository, tria la carpeta del projecte i crea el repositori. Afegeix el fitxer.gitignorede Unity a l'arrel i fes el primer commit.Instala los paquetes desde Window › Package Manager › Unity Registry:
CinemachineyAI Navigation. El Input System ya viene con la plantilla.Instal·la els paquets des de Window › Package Manager › Unity Registry:CinemachineiAI Navigation. L'Input System ja ve amb la plantilla.Monta la arena. Crea una escena
Gamey añade un Plane llamadoGroundcon escala 4 × 1 × 4 (40 × 40 metros). Importa un paquete 3D de Kenney o de Poly Haven para decorar los bordes con rocas, columnas o vallas.Munta l'arena. Crea una escenaGamei afegeix-hi un Plane anomenatGroundamb escala 4 × 1 × 4 (40 × 40 metres). Importa un paquet 3D de Kenney o de Poly Haven per decorar les vores amb roques, columnes o tanques.Crea el jugador. Una Capsule llamada
Playercon la etiquetaPlayer, un Rigidbody con la rotación X y Z bloqueada en Constraints y este script:Crea el jugador. Una Capsule anomenadaPlayeramb l'etiquetaPlayer, un Rigidbody amb la rotació X i Z bloquejada a Constraints i aquest script:using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(Rigidbody))] public class PlayerController : MonoBehaviour { public float speed = 6f; public Animator animator; // optional, from session 3 Rigidbody rb; InputAction move; Vector3 input; void Awake() { rb = GetComponent<Rigidbody>(); move = InputSystem.actions.FindAction("Move"); } void Update() { Vector2 v = move.ReadValue<Vector2>(); input = new Vector3(v.x, 0f, v.y); if (animator) animator.SetFloat("Speed", input.magnitude); } void FixedUpdate() { Vector3 velocity = Vector3.ClampMagnitude(input, 1f) * speed; velocity.y = rb.linearVelocity.y; rb.linearVelocity = velocity; if (input.sqrMagnitude > 0.01f) rb.MoveRotation(Quaternion.LookRotation(input)); } }Comprueba la acción de movimiento. El script lee la acción
Movedel assetInputSystem_Actionsque trae el proyecto. Con WASD, flechas o el joystick de un mando ya funciona.Comprova l'acció de moviment. El script llegeix l'accióMovede l'assetInputSystem_Actionsque porta el projecte. Amb WASD, fletxes o el joystick d'un comandament ja funciona.Añade la cámara. GameObject › Cinemachine › Targeted Cameras › Follow Camera. En Tracking Target pon el
Player. En el componente Follow, elige Binding Mode: World Space y Follow Offset (0, 14, −8); en Rotation Control, elige Rotation Composer para que la cámara mire siempre al jugador desde arriba.Afegeix la càmera. GameObject › Cinemachine › Targeted Cameras › Follow Camera. A Tracking Target posa elPlayer. Al component Follow, tria Binding Mode: World Space i Follow Offset (0, 14, −8); a Rotation Control, tria Rotation Composer perquè la càmera miri sempre el jugador des de dalt.
Instrucción para el agenteInstrucció per a l'agent
Lee el documento de diseño que te pego y revisa la escena Game: lista los objetos que hay, comprueba que el Player tiene Rigidbody con la rotación X y Z bloqueada y propón tres mejoras al PlayerController sin aplicarlas.Llegeix el document de disseny que t'enganxo i revisa l'escena Game: llista els objectes que hi ha, comprova que el Player té Rigidbody amb la rotació X i Z bloquejada i proposa'm tres millores al PlayerController sense aplicar-les.
Punto de controlPunt de control
- El jugador se mueve con WASD y gira hacia donde caminaEl jugador es mou amb WASD i gira cap on camina
- La cámara lo sigue desde arriba y mantiene la orientación cuando él giraLa càmera el segueix des de dalt i manté l'orientació quan ell gira
- Commit
v0.1hecho en GitHub DesktopCommitv0.1fet a GitHub Desktop
2Programar con IA: Unity AI, agentes y MCPProgramar amb IA: Unity AI, agents i MCP
ObjetivoObjectiu. Conectar un agente al editor y programar con él el núcleo del combate: enemigos, oleadas, vida y ataque automático.Connectar un agent a l'editor i programar amb ell el nucli del combat: enemics, onades, vida i atac automàtic.
Activa Unity AI. Instala el paquete AI Assistant, abre el Assistant y activa la prueba gratuita. Hazle una primera pregunta sobre el proyecto, por ejemplo qué componentes tiene el
Player.Activa Unity AI. Instal·la el paquet AI Assistant, obre l'Assistant i activa la prova gratuïta. Fes-li una primera pregunta sobre el projecte, per exemple quins components té elPlayer.Conecta un agente externo. Unity ha sustituido su servidor MCP por la Unity CLI, que hace de puente entre el editor y agentes como Claude Code o Codex. Sigue la guía oficial; las dos órdenes principales son estas:Connecta un agent extern. Unity ha substituït el seu servidor MCP per la Unity CLI, que fa de pont entre l'editor i agents com Claude Code o Codex. Segueix la guia oficial; les dues ordres principals són aquestes:
unity pipeline install unity mcp configure claudeAlternativa de la comunidad. Si prefieres un servidor MCP clásico, añade
mcp-unitydesde Package Manager › Add package from git URL y sigue las instrucciones del repositorio para registrarlo en tu agente.Alternativa de la comunitat. Si prefereixes un servidor MCP clàssic, afegeixmcp-unitydes de Package Manager › Add package from git URL i segueix les instruccions del repositori per registrar-lo al teu agent.https://github.com/CoderGamester/mcp-unity.gitPrepara la navegación. Añade el componente NavMeshSurface al
Groundy pulsa Bake. La zona azul es donde podrán caminar los enemigos.Prepara la navegació. Afegeix el component NavMeshSurface alGroundi prem Bake. La zona blava és on podran caminar els enemics.Crea los datos de los enemigos con un ScriptableObject. Después, Create › Arena › Enemy Data genera fichas editables sin tocar código.Crea les dades dels enemics amb un ScriptableObject. Després, Create › Arena › Enemy Data genera fitxes editables sense tocar codi.
using UnityEngine; [CreateAssetMenu(menuName = "Arena/Enemy Data")] public class EnemyData : ScriptableObject { public float speed = 3.5f; public int maxHealth = 3; public int contactDamage = 1; public int xpReward = 1; }Vida y daño para el jugador y para los enemigos. El mismo componente sirve para los dos.Vida i dany per al jugador i per als enemics. El mateix component serveix per als dos.
using UnityEngine; using UnityEngine.Events; public class Health : MonoBehaviour { public int maxHealth = 5; public ParticleSystem hitEffect; // optional, from session 3 public UnityEvent<int, int> onChanged; public UnityEvent onDeath; public int Current { get; private set; } void Awake() => Current = maxHealth; public void Init(int max) { maxHealth = max; Current = max; onChanged?.Invoke(Current, maxHealth); } public void TakeDamage(int amount) { if (Current <= 0) return; Current = Mathf.Max(Current - amount, 0); if (hitEffect) Instantiate(hitEffect, transform.position + Vector3.up, Quaternion.identity); onChanged?.Invoke(Current, maxHealth); if (Current == 0) onDeath?.Invoke(); } public void IncreaseMax(int amount) { maxHealth += amount; Current += amount; onChanged?.Invoke(Current, maxHealth); } }El enemigo. Una cápsula roja con la etiqueta
Enemy, NavMeshAgent, Health y este script. Arrástrala a la carpetaPrefabspara convertirla en prefab y asígnale la fichaBasic. Añade también Health alPlayer.L'enemic. Una càpsula vermella amb l'etiquetaEnemy, NavMeshAgent, Health i aquest script. Arrossega-la a la carpetaPrefabsper convertir-la en prefab i assigna-li la fitxaBasic. Afegeix també Health alPlayer.using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; [RequireComponent(typeof(NavMeshAgent), typeof(Health))] public class Enemy : MonoBehaviour { public static readonly List<Enemy> All = new List<Enemy>(); public static event Action<int> OnEnemyKilled; public EnemyData data; NavMeshAgent agent; Transform player; float hitCooldown; void OnEnable() => All.Add(this); void OnDisable() => All.Remove(this); void Start() { agent = GetComponent<NavMeshAgent>(); agent.speed = data.speed; Health health = GetComponent<Health>(); health.Init(data.maxHealth); health.onDeath.AddListener(Die); GameObject p = GameObject.FindWithTag("Player"); if (p) player = p.transform; } void Update() { hitCooldown -= Time.deltaTime; if (player) agent.SetDestination(player.position); } void OnCollisionStay(Collision collision) { if (hitCooldown > 0f || !collision.collider.CompareTag("Player")) return; collision.collider.GetComponent<Health>().TakeDamage(data.contactDamage); hitCooldown = 1f; } void Die() { OnEnemyKilled?.Invoke(data.xpReward); Destroy(gameObject); } }Las oleadas. Un objeto vacío
Spawnercon este script. Hace aparecer enemigos en círculo alrededor del jugador y cada vez más deprisa.Les onades. Un objecte buitSpawneramb aquest script. Fa aparèixer enemics en cercle al voltant del jugador i cada cop més de pressa.using UnityEngine; using UnityEngine.AI; public class WaveSpawner : MonoBehaviour { public Enemy basicEnemy; public Enemy toughEnemy; // optional, from session 4 public float toughFromSecond = 60f; public Transform player; public float radius = 16f; public float startInterval = 2f; public float minInterval = 0.3f; public float rampPerSecond = 0.02f; float timer; float elapsed; void Update() { if (!player) return; elapsed += Time.deltaTime; timer -= Time.deltaTime; if (timer > 0f) return; timer = Mathf.Max(minInterval, startInterval - elapsed * rampPerSecond); Vector2 offset = Random.insideUnitCircle.normalized * radius; Vector3 candidate = player.position + new Vector3(offset.x, 0f, offset.y); if (!NavMesh.SamplePosition(candidate, out NavMeshHit hit, 4f, NavMesh.AllAreas)) return; bool tough = toughEnemy && elapsed > toughFromSecond && Random.value < 0.25f; Instantiate(tough ? toughEnemy : basicEnemy, hit.position, Quaternion.identity); } }El proyectil. Una esfera pequeña con el Collider marcado como Is Trigger y un Rigidbody Is Kinematic. Guárdala como prefab.El projectil. Una esfera petita amb el Collider marcat com a Is Trigger i un Rigidbody Is Kinematic. Desa-la com a prefab.
using UnityEngine; public class Projectile : MonoBehaviour { public float speed = 18f; public float lifetime = 2f; [HideInInspector] public int damage = 1; void Start() => Destroy(gameObject, lifetime); void Update() => transform.position += transform.forward * speed * Time.deltaTime; void OnTriggerEnter(Collider other) { if (!other.CompareTag("Enemy")) return; other.GetComponent<Health>().TakeDamage(damage); Destroy(gameObject); } }El ataque automático va en el
Player: busca el enemigo más cercano dentro del radio y dispara.L'atac automàtic va alPlayer: busca l'enemic més proper dins del radi i dispara.using UnityEngine; public class AutoAttack : MonoBehaviour { public Projectile projectilePrefab; public float fireRate = 1.5f; // shots per second public float range = 12f; public int damage = 1; public int projectiles = 1; public AudioClip shootSound; // optional, from session 3 AudioSource audioSource; float cooldown; void Awake() => audioSource = GetComponent<AudioSource>(); void Update() { cooldown -= Time.deltaTime; if (cooldown > 0f) return; Enemy target = FindClosest(); if (!target) return; Vector3 direction = target.transform.position - transform.position; direction.y = 0f; if (direction.sqrMagnitude < 0.01f) return; cooldown = 1f / fireRate; for (int i = 0; i < projectiles; i++) { float spread = (i - (projectiles - 1) / 2f) * 10f; Quaternion rotation = Quaternion.LookRotation(direction) * Quaternion.Euler(0f, spread, 0f); Projectile p = Instantiate(projectilePrefab, transform.position + Vector3.up * 0.5f, rotation); p.damage = damage; } if (audioSource && shootSound) audioSource.PlayOneShot(shootSound); } Enemy FindClosest() { Enemy best = null; float bestDistance = range * range; foreach (Enemy e in Enemy.All) { float d = (e.transform.position - transform.position).sqrMagnitude; if (d < bestDistance) { bestDistance = d; best = e; } } return best; } }Revisa el código del agente antes de aceptarlo: que no busque objetos cada fotograma con
Find, que las referencias se puedan asignar desde el Inspector y que no haya números mágicos repartidos por el código.Revisa el codi de l'agent abans d'acceptar-lo: que no busqui objectes cada fotograma ambFind, que les referències es puguin assignar des de l'Inspector i que no hi hagi números màgics repartits pel codi.
Instrucción para el agenteInstrucció per a l'agent
Usa las herramientas de Unity para crear un prefab Enemy: cápsula con material rojo, etiqueta Enemy, NavMeshAgent, Health y el script Enemy con el EnemyData Basic. Después crea un objeto Spawner con WaveSpawner, asígnale el prefab y el Player, ejecuta el juego 20 segundos y dime si salen errores en la consola.Fes servir les eines de Unity per crear un prefab Enemy: càpsula amb material vermell, etiqueta Enemy, NavMeshAgent, Health i el script Enemy amb l'EnemyData Basic. Després crea un objecte Spawner amb WaveSpawner, assigna-li el prefab i el Player, executa el joc 20 segons i digues-me si surten errors a la consola.
Punto de controlPunt de control
- Los enemigos aparecen y persiguen al jugadorEls enemics apareixen i persegueixen el jugador
- El jugador dispara solo y los enemigos mueren a los tres impactosEl jugador dispara sol i els enemics moren als tres impactes
- La consola no muestra erroresLa consola no mostra errors
- Commit
v0.2Commitv0.2
3Arte y sonido con IA generativa y BlenderArt i so amb IA generativa i Blender
ObjetivoObjectiu. Sustituir las cápsulas por personajes y decorado propios, con animaciones, efectos y sonido.Substituir les càpsules per personatges i decorat propis, amb animacions, efectes i so.
Genera el personaje con Unity Generators o con un generador 3D externo a partir de un texto o de una imagen de referencia. Pide una figura humanoide en posición de T, estilo low poly y con una sola textura.Genera el personatge amb Unity Generators o amb un generador 3D extern a partir d'un text o d'una imatge de referència. Demana una figura humanoide en posició de T, estil low poly i amb una sola textura.
low poly stylized arena warrior, full body, T-pose, game ready, single texture, clean topologyPrepáralo en Blender. Importa el archivo, aplica un modificador Decimate hasta unos 8.000 triángulos, pon el origen en los pies (Object › Set Origin), aplica escala y rotación con Ctrl+A y exporta en FBX con Forward: -Z, Up: Y y Apply Transform activado.Prepara'l a Blender. Importa el fitxer, aplica un modificador Decimate fins a uns 8.000 triangles, posa l'origen als peus (Object › Set Origin), aplica escala i rotació amb Ctrl+A i exporta en FBX amb Forward: -Z, Up: Y i Apply Transform activat.
Automatiza Blender con un agente. Instala el complemento de
blender-mcpsiguiendo el repositorio y registra el servidor en Claude Code:Automatitza Blender amb un agent. Instal·la el complement deblender-mcpseguint el repositori i registra el servidor a Claude Code:claude mcp add blender uvx blender-mcpInstrucción para el agenteInstrucció per a l'agent
Aplica un Decimate con ratio 0,3 a todos los objetos seleccionados, pon el origen de cada uno en la base y expórtalos en FBX separados a la carpeta Exports.Aplica un Decimate amb ràtio 0,3 a tots els objectes seleccionats, posa l'origen de cadascun a la base i exporta'ls en FBX separats a la carpeta Exports.
Rigging con Mixamo. Sube el FBX, coloca los marcadores y descarga tres animaciones: Idle, Running y Dying, en formato FBX for Unity. La primera con malla y las otras dos sin ella.Rigging amb Mixamo. Puja el FBX, col·loca els marcadors i descarrega tres animacions: Idle, Running i Dying, en format FBX for Unity. La primera amb malla i les altres dues sense.
Importa en Unity. En la pestaña Rig de cada FBX, elige Animation Type: Humanoid. En Idle y Running activa Loop Time.Importa a Unity. A la pestanya Rig de cada FBX, tria Animation Type: Humanoid. A Idle i Running activa Loop Time.
Animator. Crea un Animator Controller con un parámetro
Speed(float). Transición de Idle a Running cuandoSpeedes mayor que 0,1 y al revés cuando es menor. Pon el modelo como hijo delPlayer, oculta la cápsula y arrastra el Animator al campoanimatordelPlayerController.Animator. Crea un Animator Controller amb un paràmetreSpeed(float). Transició d'Idle a Running quanSpeedés més gran que 0,1 i al revés quan és més petit. Posa el model com a fill delPlayer, amaga la càpsula i arrossega l'Animator al campanimatordelPlayerController.Materiales. Genera una textura para el suelo con Unity Generators o descarga una de Poly Haven y crea un material URP/Lit con el mapa de color, el normal y el de rugosidad.Materials. Genera una textura per al terra amb Unity Generators o descarrega'n una de Poly Haven i crea un material URP/Lit amb el mapa de color, el normal i el de rugositat.
Efecto de impacto. Un Particle System con Duration 0,3, sin Looping, una ráfaga de 15 partículas y Stop Action: Destroy. Guárdalo como prefab y asígnalo al campo
hitEffectde Health en los enemigos.Efecte d'impacte. Un Particle System amb Duration 0,3, sense Looping, una ràfega de 15 partícules i Stop Action: Destroy. Desa'l com a prefab i assigna'l al camphitEffectde Health als enemics.Sonido. Genera un efecto de disparo y uno de impacto con un generador de audio con IA, y una pista de música en bucle. Añade un AudioSource al
Playery asigna el sonido al camposhootSounddel AutoAttack. Antes de publicar, revisa que el plan de cada herramienta permita el uso comercial.So. Genera un efecte de tret i un d'impacte amb un generador d'àudio amb IA, i una pista de música en bucle. Afegeix un AudioSource alPlayeri assigna el so al campshootSoundde l'AutoAttack. Abans de publicar, revisa que el pla de cada eina permeti l'ús comercial.
Instrucción para el agenteInstrucció per a l'agent
Revisa los imports de la carpeta Art: dime qué FBX no tienen el Rig en Humanoid, qué animaciones de movimiento no tienen Loop Time y qué texturas superan los 2048 píxeles. Corrígelo y hazme un resumen de los cambios.Revisa els imports de la carpeta Art: indica'm quins FBX no tenen el Rig en Humanoid, quines animacions de moviment no tenen Loop Time i quines textures superen els 2048 píxels. Corregeix-ho i fes-me un resum dels canvis.
Punto de controlPunt de control
- El personaje camina y reposa con las animaciones correctasEl personatge camina i reposa amb les animacions correctes
- Los impactos muestran partículas y se oyenEls impactes mostren partícules i se senten
- Ningún modelo pasa de 10.000 triángulosCap model passa de 10.000 triangles
- Commit
v0.3Commitv0.3
4Bucle de juego e interfaz de usuarioBucle de joc i interfície d'usuari
ObjetivoObjectiu. Cerrar una partida completa: progresión, mejoras, interfaz, sonido configurable y récord guardado.Tancar una partida completa: progressió, millores, interfície, so configurable i rècord desat.
Experiencia y niveles. Este componente va en el
Playery escucha el evento que lanza cada enemigo al morir.Experiència i nivells. Aquest component va alPlayeri escolta l'esdeveniment que llança cada enemic en morir.using UnityEngine; using UnityEngine.Events; public class PlayerExperience : MonoBehaviour { public int level = 1; public int xp; public int xpToNext = 5; public UnityEvent<int> onLevelUp; public UnityEvent<int, int> onXpChanged; void OnEnable() => Enemy.OnEnemyKilled += Add; void OnDisable() => Enemy.OnEnemyKilled -= Add; void Add(int amount) { xp += amount; if (xp >= xpToNext) { xp -= xpToNext; level++; xpToNext = Mathf.RoundToInt(xpToNext * 1.4f); onLevelUp?.Invoke(level); } onXpChanged?.Invoke(xp, xpToNext); } }Las mejoras como datos. Crea cinco fichas con Create › Arena › Upgrade: cadencia +0,5, daño +1, proyectiles +1, velocidad +1 y vida máxima +2.Les millores com a dades. Crea cinc fitxes amb Create › Arena › Upgrade: cadència +0,5, dany +1, projectils +1, velocitat +1 i vida màxima +2.
using UnityEngine; public enum UpgradeType { FireRate, Damage, Projectiles, MoveSpeed, MaxHealth } [CreateAssetMenu(menuName = "Arena/Upgrade")] public class UpgradeData : ScriptableObject { public string title; [TextArea] public string description; public UpgradeType type; public float amount = 1f; }Diseña la interfaz con UI Builder. Crea
GameUI.uxmlcon estos nombres de elemento:hp-label,level-label,time-label, la barraxp-bar(ProgressBar), el panelupgrade-panelcon los botonesoption-0,option-1yoption-2, y el panelgameover-panelconresult-labelyretry-button. Añade a la escena un objetoUIcon el componente UIDocument apuntando a este archivo.Dissenya la interfície amb UI Builder. CreaGameUI.uxmlamb aquests noms d'element:hp-label,level-label,time-label, la barraxp-bar(ProgressBar), el panellupgrade-panelamb els botonsoption-0,option-1ioption-2, i el panellgameover-panelambresult-labeliretry-button. Afegeix a l'escena un objecteUIamb el component UIDocument apuntant a aquest fitxer.El menú de mejoras pausa el juego, ofrece tres opciones distintas y aplica la elegida.El menú de millores pausa el joc, ofereix tres opcions diferents i aplica la triada.
using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; public class UpgradeMenu : MonoBehaviour { public UIDocument document; public List<UpgradeData> pool; public AutoAttack attack; public PlayerController controller; public Health playerHealth; VisualElement panel; readonly Button[] buttons = new Button[3]; readonly UpgradeData[] offered = new UpgradeData[3]; void Start() { VisualElement root = document.rootVisualElement; panel = root.Q<VisualElement>("upgrade-panel"); for (int i = 0; i < 3; i++) { int index = i; buttons[i] = root.Q<Button>($"option-{i}"); buttons[i].clicked += () => Choose(index); } panel.style.display = DisplayStyle.None; } public void Show(int level) { List<UpgradeData> bag = new List<UpgradeData>(pool); for (int i = 0; i < 3; i++) { int pick = Random.Range(0, bag.Count); offered[i] = bag[pick]; if (bag.Count > 1) bag.RemoveAt(pick); buttons[i].text = $"{offered[i].title}\n{offered[i].description}"; } panel.style.display = DisplayStyle.Flex; Time.timeScale = 0f; } void Choose(int index) { UpgradeData u = offered[index]; switch (u.type) { case UpgradeType.FireRate: attack.fireRate += u.amount; break; case UpgradeType.Damage: attack.damage += Mathf.RoundToInt(u.amount); break; case UpgradeType.Projectiles: attack.projectiles += Mathf.RoundToInt(u.amount); break; case UpgradeType.MoveSpeed: controller.speed += u.amount; break; case UpgradeType.MaxHealth: playerHealth.IncreaseMax(Mathf.RoundToInt(u.amount)); break; } panel.style.display = DisplayStyle.None; Time.timeScale = 1f; } }El HUD muestra vida, nivel, experiencia y tiempo sobreviviendo.El HUD mostra vida, nivell, experiència i temps sobrevivint.
using UnityEngine; using UnityEngine.UIElements; public class Hud : MonoBehaviour { public UIDocument document; Label healthLabel, levelLabel, timeLabel; ProgressBar xpBar; public float Elapsed { get; private set; } void Start() { VisualElement root = document.rootVisualElement; healthLabel = root.Q<Label>("hp-label"); levelLabel = root.Q<Label>("level-label"); timeLabel = root.Q<Label>("time-label"); xpBar = root.Q<ProgressBar>("xp-bar"); } void Update() { Elapsed += Time.deltaTime; int s = (int)Elapsed; timeLabel.text = $"{s / 60:00}:{s % 60:00}"; } public void SetHealth(int current, int max) => healthLabel.text = $"HP {current}/{max}"; public void SetLevel(int level) => levelLabel.text = $"LV {level}"; public void SetXp(int xp, int next) { xpBar.highValue = next; xpBar.value = xp; } }Fin de partida y récord. Guarda el mejor tiempo con
PlayerPrefsy reinicia la escena.Final de partida i rècord. Desa el millor temps ambPlayerPrefsi reinicia l'escena.using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UIElements; public class GameManager : MonoBehaviour { public UIDocument document; public Hud hud; VisualElement gameOverPanel; Label resultLabel; void Start() { Time.timeScale = 1f; VisualElement root = document.rootVisualElement; gameOverPanel = root.Q<VisualElement>("gameover-panel"); resultLabel = root.Q<Label>("result-label"); root.Q<Button>("retry-button").clicked += Retry; gameOverPanel.style.display = DisplayStyle.None; } public void GameOver() { Time.timeScale = 0f; float best = PlayerPrefs.GetFloat("best_time", 0f); if (hud.Elapsed > best) { best = hud.Elapsed; PlayerPrefs.SetFloat("best_time", best); PlayerPrefs.Save(); } resultLabel.text = $"{hud.Elapsed:0} s · REC {best:0} s"; gameOverPanel.style.display = DisplayStyle.Flex; } void Retry() => SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); }Conecta los eventos en el Inspector. En el Health del jugador:
onChanged→Hud.SetHealthyonDeath→GameManager.GameOver. En el PlayerExperience:onLevelUp→UpgradeMenu.ShowyHud.SetLevel, yonXpChanged→Hud.SetXp.Connecta els esdeveniments a l'Inspector. Al Health del jugador:onChanged→Hud.SetHealthionDeath→GameManager.GameOver. Al PlayerExperience:onLevelUp→UpgradeMenu.ShowiHud.SetLevel, ionXpChanged→Hud.SetXp.Menú principal. Una escena
MainMenucon su propio UIDocument (botonesplay-buttonyquit-button, etiquetabest-label). Añade las dos escenas a la lista de escenas del Build Profile, conMainMenula primera.Menú principal. Una escenaMainMenuamb el seu propi UIDocument (botonsplay-buttoniquit-button, etiquetabest-label). Afegeix les dues escenes a la llista d'escenes del Build Profile, ambMainMenula primera.using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UIElements; public class MainMenu : MonoBehaviour { public UIDocument document; public string gameScene = "Game"; void Start() { VisualElement root = document.rootVisualElement; root.Q<Button>("play-button").clicked += () => SceneManager.LoadScene(gameScene); root.Q<Button>("quit-button").clicked += Application.Quit; root.Q<Label>("best-label").text = $"REC {PlayerPrefs.GetFloat("best_time", 0f):0} s"; } }Volumen. Crea un Audio Mixer con los grupos
MusicySFX, expón el volumen de cada uno comoMusicVolumeySfxVolumey enruta los AudioSource. Conecta dos Slider de 0 a 1 a este script.Volum. Crea un Audio Mixer amb els grupsMusiciSFX, exposa el volum de cadascun com aMusicVolumeiSfxVolumei enruta-hi els AudioSource. Connecta dos Slider de 0 a 1 a aquest script.using UnityEngine; using UnityEngine.Audio; public class VolumeSettings : MonoBehaviour { public AudioMixer mixer; // value from 0 to 1, e.g. from a UI Toolkit Slider public void SetMusic(float value) => mixer.SetFloat("MusicVolume", ToDecibels(value)); public void SetSfx(float value) => mixer.SetFloat("SfxVolume", ToDecibels(value)); static float ToDecibels(float value) => Mathf.Log10(Mathf.Max(value, 0.0001f)) * 20f; }Curva de dificultad. Crea una segunda ficha de enemigo
Tough(más vida, más lento, más experiencia) y un segundo prefab. Asígnalo al campotoughEnemydelWaveSpawner: a partir del minuto 1, uno de cada cuatro enemigos será resistente.Corba de dificultat. Crea una segona fitxa d'enemicTough(més vida, més lent, més experiència) i un segon prefab. Assigna'l al camptoughEnemydelWaveSpawner: a partir del minut 1, un de cada quatre enemics serà resistent.Pruebas de juego cruzadas. Cada participante juega tres partidas al proyecto de otra persona y anota el tiempo, en qué momento se aburrió y en qué momento murió sin entender por qué. Con estas notas se ajustan los valores de las fichas.Proves de joc creuades. Cada participant juga tres partides al projecte d'una altra persona i n'anota el temps, en quin moment es va avorrir i en quin moment va morir sense entendre per què. Amb aquestes notes s'ajusten els valors de les fitxes.
Instrucción para el agenteInstrucció per a l'agent
Revisa la conexión entre Health, PlayerExperience, Hud, UpgradeMenu y GameManager en la escena Game. Dime qué eventos del Inspector están vacíos, conéctalos y juega una partida de prueba hasta que aparezca el menú de mejoras.Revisa la connexió entre Health, PlayerExperience, Hud, UpgradeMenu i GameManager a l'escena Game. Digues-me quins esdeveniments de l'Inspector estan buits, connecta'ls i juga una partida de prova fins que aparegui el menú de millores.
Punto de controlPunt de control
- Desde el menú principal se puede jugar una partida entera y volver a empezarDel menú principal es pot jugar una partida sencera i tornar a començar
- El menú de mejoras pausa el juego y las mejoras se notanEl menú de millores pausa el joc i les millores es noten
- El récord se mantiene al cerrar y abrir el juegoEl rècord es manté en tancar i obrir el joc
- Commit
v0.4Commitv0.4
5Build y publicación en SteamBuild i publicació a Steam
ObjetivoObjectiu. Empaquetar el juego, conectarlo con Steam y dejar la página de tienda preparada.Empaquetar el joc, connectar-lo amb Steam i deixar la pàgina de botiga preparada.
Build Profiles. File › Build Profiles, elige Windows o macOS, revisa la lista de escenas y, en Player Settings, pon el nombre de la empresa, el del producto, el icono y la resolución por defecto. Genera la build en una carpeta
Buildsfuera deAssets.Build Profiles. File › Build Profiles, tria Windows o macOS, revisa la llista d'escenes i, a Player Settings, posa el nom de l'empresa, el del producte, la icona i la resolució per defecte. Genera la build a una carpetaBuildsfora d'Assets.Profiler. Abre Window › Analysis › Profiler, juega dos minutos y busca picos de CPU y memoria. La lista
Enemy.Allque usamos en el AutoAttack evita recorrer toda la escena en cada disparo; compáralo cambiando temporalmente aFindObjectsByType.Profiler. Obre Window › Analysis › Profiler, juga dos minuts i busca pics de CPU i memòria. La llistaEnemy.Allque fem servir a l'AutoAttack evita recórrer tota l'escena a cada tret; compara-ho canviant temporalment aFindObjectsByType.Prueba la build en un equipo limpio, sin Unity instalado, y comprueba menús, sonido, resolución y salida del juego.Prova la build en un equip net, sense Unity instal·lat, i comprova menús, so, resolució i sortida del joc.
Steamworks.NET. En Package Manager › Add package from git URL, pega la dirección del paquete. Para practicar sin pagar Steam Direct usamos el App ID 480 (SpaceWar), el juego de prueba de Valve: comprueba que en la raíz del proyecto hay un archivo
steam_appid.txtcon el número 480 y abre el cliente de Steam.Steamworks.NET. A Package Manager › Add package from git URL, enganxa l'adreça del paquet. Per practicar sense pagar Steam Direct fem servir l'App ID 480 (SpaceWar), el joc de prova de Valve: comprova que a l'arrel del projecte hi ha un fitxersteam_appid.txtamb el número 480 i obre el client de Steam.https://github.com/rlabrecque/Steamworks.NET.git?path=/com.rlabrecque.steamworks.netInicializa Steam con un objeto
Steamen la primera escena.Inicialitza Steam amb un objecteSteama la primera escena.using UnityEngine; using Steamworks; public class SteamBootstrap : MonoBehaviour { public static bool Ready { get; private set; } void Awake() { DontDestroyOnLoad(gameObject); try { Ready = SteamAPI.Init(); } catch (System.DllNotFoundException e) { Debug.LogWarning(e); } if (!Ready) Debug.LogWarning("Steam not initialised: open the Steam client."); } void Update() { if (Ready) SteamAPI.RunCallbacks(); } void OnApplicationQuit() { if (Ready) SteamAPI.Shutdown(); } public static void Unlock(string achievementId) { if (!Ready) return; SteamUserStats.SetAchievement(achievementId); SteamUserStats.StoreStats(); } }Primer logro. Al sobrevivir un minuto, el juego desbloquea
ACH_WIN_ONE_GAME, uno de los logros de SpaceWar. Con tu App ID propio, aquí irán los identificadores que definas en Steamworks.Primer assoliment. En sobreviure un minut, el joc desbloquejaACH_WIN_ONE_GAME, un dels assoliments de SpaceWar. Amb el teu App ID propi, aquí hi aniran els identificadors que defineixis a Steamworks.using UnityEngine; public class SurvivalAchievement : MonoBehaviour { public Hud hud; public float seconds = 60f; public string achievementId = "ACH_WIN_ONE_GAME"; // SpaceWar (App ID 480) bool unlocked; void Update() { if (unlocked || hud.Elapsed < seconds) return; unlocked = true; SteamBootstrap.Unlock(achievementId); } }SteamPipe. Cuando tengas App ID propio, la build se sube con SteamCMD y un script de configuración. Este es el esquema de un
app_build; los números 1000000 y 1000001 son de ejemplo y se sustituyen por el App ID y el Depot ID que te da Steamworks.SteamPipe. Quan tinguis App ID propi, la build es puja amb SteamCMD i un script de configuració. Aquest és l'esquema d'unapp_build; els números 1000000 i 1000001 són d'exemple i se substitueixen per l'App ID i el Depot ID que et dona Steamworks."AppBuild" { "AppID" "1000000" "Desc" "Arena Survivor v1.0" "ContentRoot" "..\Builds\Windows\" "BuildOutput" "..\output\" "Depots" { "1000001" { "FileMapping" { "LocalPath" "*" "DepotPath" "." "recursive" "1" } } } }Página de tienda. Prepara las cápsulas (cabecera 920 × 430, pequeña 462 × 174, principal 1232 × 706, vertical 748 × 896 y biblioteca 600 × 900), al menos cinco capturas de 1920 × 1080 que enseñen juego real, un tráiler de 60 a 90 segundos y la descripción corta y larga. La IA ayuda con los borradores; el texto final tiene que sonar a tu juego.Pàgina de botiga. Prepara les càpsules (capçalera 920 × 430, petita 462 × 174, principal 1232 × 706, vertical 748 × 896 i biblioteca 600 × 900), almenys cinc captures de 1920 × 1080 que ensenyin joc real, un tràiler de 60 a 90 segons i la descripció curta i llarga. La IA ajuda amb els esborranys; el text final ha de sonar al teu joc.
Declaración de contenido. En el cuestionario de contenido de Steamworks se indica qué recursos se han generado con IA, tanto los que van dentro del juego como los de la página.Declaració de contingut. Al qüestionari de contingut de Steamworks s'indica quins recursos s'han generat amb IA, tant els que van dins del joc com els de la pàgina.
«Próximamente» y Next Fest. La página tiene que estar publicada como mínimo dos semanas antes del lanzamiento, y cuanto antes se publica, más listas de deseados acumula. Las ediciones de Steam Next Fest piden la demo unas semanas antes; consulta las fechas en la documentación.«Properament» i Next Fest. La pàgina ha d'estar publicada com a mínim dues setmanes abans del llançament, i com més aviat es publica, més llistes de desitjos acumula. Les edicions de Steam Next Fest demanen la demo unes setmanes abans; consulta les dates a la documentació.
Instrucción para el agenteInstrucció per a l'agent
Revisa el proyecto antes de la build final: lista los warnings de la consola, comprueba que todas las escenas están en el Build Profile, que el Player Settings tiene nombre de empresa, de producto e icono, y que no hay ningún Debug.Log dentro de un Update. Propón los cambios antes de aplicarlos.Revisa el projecte abans de la build final: llista els warnings de la consola, comprova que totes les escenes són al Build Profile, que el Player Settings té nom d'empresa, de producte i icona, i que no hi ha cap Debug.Log dins d'un Update. Proposa els canvis abans d'aplicar-los.
Punto de controlPunt de control
- La build funciona en un equipo sin UnityLa build funciona en un equip sense Unity
- Steam muestra «Jugando a SpaceWar» y el logro se desbloqueaSteam mostra «Jugant a SpaceWar» i l'assoliment es desbloqueja
- Cápsulas, capturas y textos de la página preparadosCàpsules, captures i textos de la pàgina preparats
- Commit y etiqueta
v1.0Commit i etiquetav1.0
Recursos y licenciasRecursos i llicències
Todas las herramientas tienen una opción gratuita suficiente para seguir el curso. Los planes de pago se explican para quien quiera comercializar el juego.Totes les eines tenen una opció gratuïta suficient per seguir el curs. Els plans de pagament s'expliquen per a qui vulgui comercialitzar el joc.
| RecursoRecurs | Para qué lo usamosPer a què el fem servir | Coste y licenciaCost i llicència |
|---|---|---|
| Unity 6 | Motor del juegoMotor del joc | Licencia Personal gratuitaLlicència Personal gratuïta |
| Unity AI | Assistant, Generators y acceso para agentesAssistant, Generators i accés per a agents | Prueba de 14 días; incluido en los planes ProProva de 14 dies; inclòs als plans Pro |
| Claude Code · Codex · Cursor | Agente de código conectado a UnityAgent de codi connectat a Unity | Plan gratuito o de pago según la herramientaPla gratuït o de pagament segons l'eina |
| Blender | Preparación de modelosPreparació de models | Gratuito y de código abiertoGratuït i de codi obert |
| Mixamo | Rigging y animacionesRigging i animacions | Gratuito con cuenta de AdobeGratuït amb compte d'Adobe |
| Kenney | Modelos, sprites y sonidosModels, sprites i sons | Gratuito, CC0Gratuït, CC0 |
| Poly Haven | Texturas, modelos y HDRITextures, models i HDRI | Gratuito, CC0Gratuït, CC0 |
| Quaternius | Modelos low polyModels low poly | Gratuito para uso comercial con licencia propiaGratuït per a ús comercial amb llicència pròpia |
| Unity Asset Store | Paquetes para UnityPaquets per a Unity | Gratuitos y de pagoGratuïts i de pagament |
| Fab | Paquetes para Unity y otros motoresPaquets per a Unity i altres motors | Gratuitos y de pagoGratuïts i de pagament |
| Steamworks | Publicación en SteamPublicació a Steam | 100 USD por título, que Valve devuelve cuando el juego supera 1.000 USD de ventas100 USD per títol, que Valve retorna quan el joc supera 1.000 USD de vendes |
Los generadores 3D y de audio con IA tienen planes gratuitos limitados; el uso comercial depende del plan de cada herramienta.Els generadors 3D i d'àudio amb IA tenen plans gratuïts limitats; l'ús comercial depèn del pla de cada eina.
FormadorFormador
Daniel Martín Casas. Formador en Barcelona Activa desde hace más de diez años, desarrollador full stack y máster en Inteligencia Artificial y Big Data. Es el propietario de ThinkingLiteSoft, estudio de videojuegos de Barcelona que lanza Precinct 2099 en Steam en noviembre de 2026.Daniel Martín Casas. Formador a Barcelona Activa des de fa més de deu anys, desenvolupador full stack i màster en Intel·ligència Artificial i Big Data. És el propietari de ThinkingLiteSoft, estudi de videojocs de Barcelona que llança Precinct 2099 a Steam el novembre de 2026.
Preguntas frecuentesPreguntes freqüents
¿Qué nivel hace falta para hacer el curso?Quin nivell cal per fer el curs?
Conocimientos básicos de C# o de otro lenguaje de programación. Si ya has abierto Unity alguna vez irás más cómodo, pero el curso empieza desde el proyecto vacío.Coneixements bàsics de C# o d'un altre llenguatge de programació. Si ja has obert Unity alguna vegada, aniràs més còmode, però el curs comença des del projecte buit.
¿En qué idioma son las clases?En quin idioma són les classes?
Las clases son en catalán. El manual de práctica y esta página están en catalán y en castellano.Les classes són en català. El manual de pràctica i aquesta pàgina estan en català i en castellà.
¿Tengo que traer ordenador?He de portar ordinador?
Puedes usar los ordenadores del Cibernàrium o traer tu portátil con Unity 6 instalado. Para un portátil propio se recomiendan 16 GB de RAM, tarjeta gráfica dedicada y unos 30 GB libres.Pots fer servir els ordinadors del Cibernàrium o portar el teu portàtil amb Unity 6 instal·lat. Per a un portàtil propi es recomanen 16 GB de RAM, targeta gràfica dedicada i uns 30 GB lliures.
¿Tengo que pagar alguna herramienta o la tasa de Steam?He de pagar alguna eina o la quota de Steam?
No. Todas las herramientas tienen opción gratuita para seguir el curso y la integración con Steam se practica con el App ID de prueba de Valve. El alta en Steam Direct se muestra paso a paso y cada persona decide si la hace por su cuenta.No. Totes les eines tenen opció gratuïta per seguir el curs i la integració amb Steam es practica amb l'App ID de prova de Valve. L'alta a Steam Direct es mostra pas a pas i cadascú decideix si la fa pel seu compte.
¿Qué diferencia hay con el curso de certificación de Unity?Quina diferència hi ha amb el curs de certificació de Unity?
El Cibernàrium tiene un curso específico de preparación para la certificación Unity Certified User: Programmer. Este curso se centra en terminar y publicar un juego con las herramientas actuales, y es una buena continuación para quien ya conoce el editor.El Cibernàrium té un curs específic de preparació per a la certificació Unity Certified User: Programmer. Aquest curs se centra a acabar i publicar un joc amb les eines actuals, i és una bona continuació per a qui ja coneix l'editor.
¿Qué versión de Unity usamos?Quina versió de Unity fem servir?
Unity 6.3 LTS, la versión con soporte de larga duración hasta diciembre de 2027. También explicamos cuándo conviene pasar a una versión Update.Unity 6.3 LTS, la versió amb suport de llarga durada fins al desembre de 2027. També expliquem quan convé passar a una versió Update.
Actualizado en octubre de 2026 · Unity 6.3 LTSActualitzat a l'octubre de 2026 · Unity 6.3 LTS