Scripting con C# en Unity
Transcripción
Scripting con C# en Unity
VIDEOJUEGOS 2 Scripting con C# en Unity Scripting con C# en Unity V2 Puntos a tratar • • • • • • • Scripting con C# Eventos de entrada Patrones en Unity Gestión de eventos Invocación con retardo Corrutinas Adaptación a dispositivos móviles Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 2 V2 Scripting con C# en Unity Creación de scripts • Se crean como assets de tipo script • Podemos editarlos con la herramienta integrada MonoDevelop • La herramienta a utilizar se puede configurar en Preferences … > External Tools Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 3 V2 Scripting con C# en Unity Añadir un script a un objeto • Una vez creado un script, podemos añadirlo como componente a un Game Object • Tras esto, lo veremos en la lista de componentes del Game Object Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 4 V2 Scripting con C# en Unity Estructura de un script • La estructura básica de un script C# de Unity es public class EsferaScript : MonoBehaviour { void Start () { Todos los scripts heredan de MonoBehaviour } void Update () { } } • Start() nos permite inicializar el nodo • Awake() se ejecuta justo antes (útil para dependencias) • Update() actualiza el nodo (su frecuencia depende del framerate) • LateUpdate() se ejecuta justo después (para dependencias) Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 5 V2 Scripting con C# en Unity Ciclo del juego • El elemento principal de la arquitectura del motor es el ciclo del juego • Dibuja los objetos de la escena actual • Actualiza los objetos de la escena actual En Unity actualizamos cada objeto en Update() • Sólo se dibujará y se actualizará la escena actualmente activa • Delta time • Nos indica el tiempo transcurrido desde la iteración anterior Lo utilizaremos para actualizar la escena adecuadamente posicion = posicion + velocidad * Time.deltaTime; Accedemos con Time.deltaTime Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 6 V2 Scripting con C# en Unity Acceso a las propiedades el objeto • Desde el código del script se accede a propiedades del Game Object al que pertenece • Podemos acceder a los componentes con GetComponent() • Si el objeto no dispone del componente correspondiente, este método devolverá null Transform Renderer AudioSource Camera Light Transformación del nodo en la escena Permite cambiar el material del objeto Acceso al componente Audio Source Permite configurar la cámara Permite configurar una fuente de luz Inicializa el nodo en una posición void Start () { GetComponent<Transform>().position = new Vector3(0,0,5); } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 7 V2 Scripting con C# en Unity Interfaz del script • Podemos definir variables globales en el script public Vector3 posicionInicial; void Start () { GetComponent<Transform>().position = posicionInicial; } • Estas variables aparecen como parámetros en el entorno • Hacen el script reutilizable Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 8 V2 Scripting con C# en Unity Polimorfismo en Unity • Si creamos una variable cuyo tipo corresponde a un componente, podremos asignar a ella cualquier Game Object que incorpore dicho componente • Por ejemplo, creamos una variable pública target de tipo Transform public Transform target; • Podremos asignar a ella cualquier Game Object con un componente Transform Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 9 V2 Scripting con C# en Unity Acceso a los componentes • Nuestros propios scripts serán considerados también componentes, al igual que los que incorpora el motor • Podemos acceder a ellos con GetComponent(TipoComponente) Transform t; t = GetComponent<Transform>(); OtroScript s; s = GetComponent<OtroScript>(); Equivalente a utilizar la variable implícita transform Nuestros scripts son considerados componentes • Atributos @script • Permiten definir cómo se utilizará el script en el entorno [RequireComponent(typeof(OtroScript))] Obliga a añadir OtroScript al objeto [AddComponentMenu("Controladores/Cubo")] Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 10 V2 Scripting con C# en Unity Buscar objetos • Los objetos tienen nombre y etiqueta • Propiedades name y tag • Podemos realizar búsquedas de objetos • Búsqueda por nombre GameObject techo = GameObject.Find("Techo"); • Búsqueda por etiqueta GameObject enemigo = GameObject.FindWithTag("Enemigo"); GameObject [] enemigos = GameObject.FindGameObjectsWithTag("Enemigo"); foreach(GameObject enemigo in enemigos) { … } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 11 V2 Scripting con C# en Unity Creación y destrucción de objetos • Podemos instanciar un nuevo objeto • Se instancia mediante la clonación del objeto proporcionado • Útil para la creación de proyectiles podría ser una variable pública a la que hemos asignado un prefab desde el entorno proyectil Proyectil clone = Instantiate(proyectil) as Proyectil; Proyectil clone = Instantiate(proyectil, posicion, Quaternion.identity) as Proyectil; • Destrucción de objetos • El objeto se destruye y se elimina de la escena Destroy(gameObject); Destroy(proyectil, 5); Destruye transcurridos los segundos indicados Destroy(this); • Puede aplicarte a cualquier tipo de objetos (Game Objects, componentes, etc) Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 12 V2 Scripting con C# en Unity Eventos de entrada (I) • El objeto Input nos permite acceder a la entrada • Está preparado para entrada en dispositivos móviles • En Input Manager definimos controles virtuales • Se accede mediante Edit > Project Settings > Input • Cada control tiene una tecla por defecto • El usuario podrá configurarlo if(Input.GetButton("Fire1")) { // ¡Disparar! } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 13 V2 Scripting con C# en Unity Eventos de entrada (II) • Podemos leer un eje y actualizar la posición del personaje void Update () { float delta = Input.GetAxis("Horizontal") * Time.deltaTime; GetComponent<Transform>().Translate(new Vector3(0,delta,0)); } • Posición del ratón Input.mousePosition • Botones del ratón Input.GetMouseButton(0 | 1 | 2) • Teclado Input.GetKey(KeyCode.LeftArrow) Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 14 V2 Scripting con C# en Unity Controlador de la escena • Cada estado se representa mediante una escena en Unity • Una práctica habitual consiste en tener un script controlador • El controlador se encarga de • Coordinar distintos elementos de la escena • Gestionar marcadores y otros datos del juego • Gestionar el estado dentro de la escena • Posibles objetos en los que definir este controlador general son • Un game object vacío específico para él • La cámara principal de la escena Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 15 V2 Scripting con C# en Unity Comunicación entre componentes • Será necesario comunicar controlador y objetos de la escena • El controlador puede tener variables que apunten a los objetos • Comunicación controlador ➜ objeto • Basta con que el controlador llame a un método del objeto • Comunicación objeto ➜ controlador • El objeto no debería necesitar una variable apuntando al controlador • Utilizaremos callbacks Mover() MonedaEncontrada() Player Game Controller PublicarMonedas() Videojuegos II Marcador © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 16 V2 Scripting con C# en Unity Callbacks y patrón delegado • Para implementar callbacks en C# utilizamos patrón delegado • Un componente delega en otro para realizar una determinada tarea • El segundo componente no es conocido a priori por el primero • Al definir un delegado creamos un nuevo tipo de datos • El tipo de datos representa un tipo de función • Podemos declarar una variable de ese tipo, y asignarle una función public delegate void MonedaRecogida(int valor); public MonedaRecogida onMonedaRecogida; Player player.onMonedaRecogida = IncrementaMonedas; … void IncrementaMonedas(int valor) { monedas += valor; } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Controller Scripting 17 V2 Scripting con C# en Unity Gestión de estado con delegados • Normalmente según el estado cambia la forma de actualizar • Conviene evitar el uso de bloques switch • Es más limpio utilizar un delegado public delegate void ActualizaEscena(); public ActualizaEscena actualizaEscena; void Start () { actualizaEscena = ActualizaEscenaPatrulla; } void Update () { if(actualizaEscena != null) { actualizaEscena(); } } void ActualizaEscenaPatrulla () { ActualizaPosicionRuta(); if(LocalizaPlayer()) { actualizaEscena = ActualizaEscenaPersecucion; } void ActualizaEscenaPersecucion () { PersiguePlayer(); if(!LocalizaPlayer()) { actualizaEscena = ActualizaEscenaPatrulla; } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 18 Scripting con C# en Unity V2 Sistema de eventos • Una variable de tipo evento nos permite tener varios delegados • Útil para enviar mensajes a todos los objetos interesados • Crea una estructura menos acoplada • Cualquier objeto puede registrarse como oyente del evento public class EventManager : MonoBehaviour { public delegate void GameOver(); public static event GameOver OnGameOver; public static void SetGameOver() { if(OnGameOver != null) { OnGameOver(); } } } Videojuegos II void OnEnable() { EventManager.OnGameOver += Detener; } void OnDisable() { EventManager.OnGameOver -= Detener; } void Detener() { … } © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 19 V2 Scripting con C# en Unity Patrón singleton • Podemos implementar el patrón singleton con variables estáticas public class SocialManager : MonoBehaviour { public static SocialManager manager; void Awake () { if(manager == null) { DontDestroyOnLoad(gameObject); manager = this; } else if(manager != this) { Destroy(gameObject); } } Hace que el objeto se mantenga al cambiar de escena } • Utilizar DontDestroyOnLoad() es útil para • Datos globales del juego (estadísticas y datos de la partida) • Elementos de transición entre escenas Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 20 V2 Scripting con C# en Unity Invocación con retardo • Podemos programar la ejecución de un método con retardo Invoke("DisparaProyectil",2); • Podemos hacer que se ejecute de forma cíclica InvokeRepeating("DisparaProyectil", 2, 2); • Podemos comprobar si hay programada una ejecución if(IsInvoking("DisparaProyectil")) { … } • Cancelar todas las ejecuciones pendientes en la clase CancelInvoke(); Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 21 V2 Scripting con C# en Unity Corrutinas • Las corrutinas nos permiten ejecutar código durante varios ciclos • Debemos indicar en qué momento esperamos al siguiente ciclo IEnumerator DisparaProyectilCoroutine() { while(true) { DisparaProyectil(); yield return new WaitForSeconds(2.0f); } } Seguirá ejecutándose dentro de 2 segundos • Lanzamos la corrutina con StartCoroutine(DisparaProyectilCoroutine()); StartCoroutine("DisparaProyectilCoroutine"); • Podemos detenerla con StopAllCoroutines(); StopCoroutine("DisparaProyectilCoroutine"); Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 22 V2 Scripting con C# en Unity Otras opciones de bloqueo de corrutinas • Podemos hacer que continue en el siguiente ciclo IEnumerator MueveCoroutine() { float tiempo = 0; while(tiempo < 1) { GetComponent<Transform>().position = Vector3.Lerp(posicionInicial, target.position, tiempo); tiempo += Time.deltaTime; yield return null; } GetComponent<Transform>().position = target.position; } • También podemos bloquear hasta que termine otra corrutina yield return MueveCoroutine(); Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 23 V2 Scripting con C# en Unity Dispositivos móviles • Unity permite desplegar el juego en plataformas móviles • Deberemos adaptar la interfaz a estos dispositivos • Detectamos el tipo de dispositivo utilizado if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.BB10Player || Application.platform == RuntimePlatform.WP8Player) { // Activar controles táctiles } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 24 V2 Scripting con C# en Unity Entrada de usuario en móviles • Podemos añadir entrada de la pantalla táctil y acelerómetro Aceleración en (x,y,z) Input.acceleration Lista de contactos en la pantalla Input.touches • Podemos recorrer la lista de contactos • Comprobar su estado • Leer sus coordenadas foreach (Touch touch in Input.touches) { if (touch.phase != TouchPhase.Began) { Vector2 pos = touch.position; } } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 25 V2 Scripting con C# en Unity Controles en pantalla • Importamos el paquete Standard Assets (Mobile) • Añadimos el prefab Dual Joysticks a la escena • Se trata de objetos GUITexture vinculados a un script (tipo Joystick) • Definiremos una variable de entrada Joystick en el script de nuestro personaje Joystick moveJoystick; • Vinculamos uno de los joysticks con dicha variable • Leemos la entrada de él al actualizar la escena void Update () { float delta = moveJoystick.position.y * Time.deltaTime; GetComponent<Transform>().Translate(new Vector3(0,delta,0)); } Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 26 V2 Scripting con C# en Unity Desplegar en móvil • Abrimos la pantalla Build Settings • File > Build Settings • Seleccionamos la plataforma y pulsamos Switch Platform • Añadimos las escenas que queramos desplegar en el cuadro superior • Pulsamos Build para generar el proyecto Videojuegos II Necesitaremos abrir el proyecto en el entorno correspondiente (Xcode, Eclipse, …) © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 27 V2 Scripting con C# en Unity Unity Remote • La aplicación Unity Remote nos permite probar en móviles vía streaming de forma cómoda • Podemos descargarla de forma gratuita en cualquier plataforma • El móvil deberá estar en la misma red que el ordenador con Unity • Cargamos la aplicación Unity Remote en el móvil • Detectará los ordenadores con Unity activo • Seleccionamos el ordenador al que conectar • En ese ordenador pulsamos Play para reproducir el juego en el móvil Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 28 V2 Scripting con C# en Unity ¿Preguntas...? Videojuegos II © 2014-2015 Depto. Ciencia de la Computación e IA Scripting 29