Funciones auxiliares genéricas
Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 35 de 50.
Algunos métodos auxiliares son iguales para todos los tipos: obtener un componente o añadirlo, elegir una entrada aleatoria de una matriz. Un método genérico los escribe una sola vez, con el tipo como parámetro T que cada llamada completa:
public static class Helpers
{
public static T GetOrAdd<T>(this GameObject go) where T : Component
{
if (!go.TryGetComponent(out T found)) found = go.AddComponent<T>();
return found;
}
public static T RandomItem<T>(T[] items)
{
return items[Random.Range(0, items.Length)];
}
}Rigidbody body = crate.GetOrAdd<Rigidbody>();
Color paint = Helpers.RandomItem(colors);
GameObject enemy = Helpers.RandomItem(enemyPrefabs);where T : Component es una garantía sobre T y determina qué puede hacer el método con él. AddComponent solo acepta componentes, así que, sin la restricción, el compilador rechaza go.AddComponent<T>(); con ella, funciona cualquier componente, ya sea el Rigidbody de Unity o tus propios scripts. La restricción también te da acceso a todos los miembros de Component en un T, como .transform y .gameObject. Si una caja ya tiene un Rigidbody, se obtiene ese mismo y no se añade nada.
RandomItem no tiene restricciones porque nunca interactúa con T: funciona igual con colores, cadenas y prefabs. Casi nunca escribes el tipo en la llamada: a partir de colors, un Color[], el compilador deduce que T es Color. Un método que acepta IEnumerable<T> en lugar de T[] acepta tanto matrices como Lists, incluidas las matrices que devuelve FindObjectsByType<T>.
Desafío
IntermedioHay una torre de choque en el patio. Al pulsar Space, emite un pulso: las cajas que estén a una distancia de 4 o menos salen disparadas hacia arriba, y las lámparas que estén a una distancia de 4 o menos se encienden. Lamp.cs está lista, con TurnOn(). Escribe un asistente que encuentre ambas cosas:
- En
Helpers.cs, escribe una clase estáticaHelperscon un método genéricoInRange<T>(IEnumerable<T> items, Vector3 center, float range)para cualquier tipo de componente. Devuelve unList<T>con los elementos cuya posición esté a una distancia derangeo menos decenter. - En
Pulse.cs, al pulsar Space: todos los Rigidbody de la escena que estén a una distancia derangeo menos de la torre reciben un impulso hacia arriba delift, y todas las Lamp que estén a una distancia derangeo menos se encienden. Usa InRange para ambos casos, con los arrays que te proporcionaFindObjectsByType.
Pulsa Play, pulsa Space y después Check.
Pruébalo tú mismo
using System.Collections.Generic;
using UnityEngine;
// Helpers.InRange<T>: los elementos dentro del alcance de un punto
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Arquitectura de juegos en Unity
1Componentes, no jerarquías
Componentes pequeñosUn script base para enemigosComponentes abstractosComponentes que trabajan juntosRepaso: torreta modular4Datos serializados
Clases serializablesListas en el InspectorEnumeraciones en el InspectorRepaso: tabla de botín7Máquinas de estados
Estados como clasesUna máquina de estadosTransicionesCerebros de enemigosRepaso: estados de puertas10Proyecto: Superviviente de la arena
El héroeTipos de enemigos2Interfaces en Unity
IDamageableInterfaces y TryGetComponentGetComponentsRepaso: tecla de interacción5ScriptableObjects
Recursos de datosEstadísticas de armasConfiguración compartidaOleadas como datosRepaso: base de datos de objetos8Código reutilizable
Métodos de extensiónUn singleton genéricoFunciones auxiliares genéricasRepaso: FindNearest