Componentes abstractos
Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 3 de 50.
Algunas clases base describen un tipo de cosa que nunca existe por sí sola. Todas las armas disparan, pero un arma que no es ni una pistola ni una escopeta no tiene forma de disparar. Marca una clase así como abstract y declara cada paso que sus subclases deben escribir como un método abstracto, sin cuerpo:
public abstract class Weapon : MonoBehaviour
{
public int shots;
public void Pull()
{
shots++;
Fire();
}
protected abstract void Fire();
}public class Shotgun : Weapon
{
public GameObject pelletPrefab;
protected override void Fire()
{
for (int i = -1; i <= 1; i++)
{
Instantiate(pelletPrefab, transform.position + transform.right * i * 0.3f, transform.rotation);
}
}
}Una subclase que no escriba Fire no compila: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. Unity tampoco permite añadir un script abstracto a un objeto. Arrastra Weapon a un objeto y aparecerá Can't add script behaviour 'Weapon'. The script class can't be abstract!, ya que Unity no podría crear un arma sin Fire.
Otros scripts siguen funcionando con el tipo base. GetComponent<Weapon>() devuelve la subclase que haya en el objeto, y Pull() ejecuta el Fire de esa subclase:
// Player.cs
private Weapon weapon;
void Start()
{
weapon = GetComponent<Weapon>();
}
void Update()
{
if (Mouse.current.leftButton.wasPressedThisFrame)
{
weapon.Pull();
}
}Reemplaza el componente Shotgun por uno Pistol y el script Player seguirá igual.
Desafío
FácilLa torre del mago lanza descargas a los monstruos del campo. Monster.cs contiene lo que todos los monstruos comparten: hp (3) y Zap(), que resta 1 hp, destruye al monstruo al llegar a 0 y, de lo contrario, llama a React(). Slime.cs reacciona encogiéndose. Imp.cs no tiene reacción, y Monster le proporciona un React vacío, así que nada te indica que falta.
- Haz que Monster sea abstract y que React sea un método abstracto, para que un monstruo que no especifique cómo reacciona no compile. El compilador señalará entonces a Imp.
- Escribe el React de Imp: salta 2 unidades hacia atrás, alejándose de la torre (a lo largo de +z).
- En Tower.cs, cuando se pulsa Space, obtén el componente Monster de cada objeto etiquetado como Monster, sea cual sea su tipo, y aplica
Zap().
Pulsa Play y lanza descargas a los monstruos; después, pulsa Check.
Pruébalo tú mismo
using UnityEngine;
// Lo que todos los monstruos tienen en común.
public class Monster : MonoBehaviour
{
public int hp = 3;
public void Zap()
{
hp--;
if (hp <= 0)
{
Destroy(gameObject);
}
else
{
React();
}
}
// Cómo reacciona este tipo de monstruo a una descarga que sobrevive.
protected virtual void React()
{
}
}
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 objetos