Notice: La función wp_enqueue_script ha sido llamada de forma incorrecta. Los scripts y estilos no se deberían registrar o poner en cola hasta que se carguen los ganchos wp_enqueue_scripts, admin_enqueue_scripts y login_enqueue_scripts. Este aviso ha sido activado por la gestión de nfd_wpnavbar_setting. Por favor, ve depuración en WordPress para más información. (Este mensaje fue añadido en la versión 3.3.0). in /home1/spotsail/public_html/martra/wp-includes/functions.php on line 6078
Como crear un sistema de dialogos para Unity – Pere Martra
No se han encontrado widgets en la barra lateral

Un sistema de diálogos que sea sencillo de usar, parametrizable y que nos sirva para todos nuestros juegos es algo tan complicado de hacer, que quizás vamos a tener que escribir unas cincuenta líneas de C#…. es decir, lo tenemos en nada.

Así que veamos primero un ejemplo de escena con un diálogo gestionado con el plugin que crearemos.

Ejemplo de dialogo (absurdo) para UNITY

Vale, perfecto, pero ¿como de configurable es? Lo mejor es que veamos como se ha configura el diálogo, que, en parte, aparece el el .gif superior.

Para poder ver cómo se configura el cuadro de diálogo lo mejor es hacerlo en este vídeo de youtube, donde también se explica el script y cómo configurar una escena de 0.

El Script!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//Incoporamos Text Mesh Pro
using TMPro;

public class DialogManager : MonoBehaviour
{
    /*
     * El _dialogBox es opcional, es una caja
     * que rodea al texto, el script solo
     * la activa y desactiva. 
     */
    [System.Serializable]
    public struct _dialogBox
    {
        public int _character; //Personaje al que pertenece. 
        public GameObject _box; //Objeto a activar / desacticar 
    }
    private float _timeNextWrite, _timeLastWrite; 
    /*
     * _sentence. El dialogo se construye en base a un array
     * de esta estructura
     */
    [System.Serializable]
    public struct _sentence
    {
        public int _character; //Caracter al que pertence la frase. 
        public string[] _2say; //Lo que tiene que decir. 
        public bool _active; //Indica si se tiene que activar el marco de dialogo. 
        public bool _deactive; //Se desactivara el marco de dialogo en la siguiente frase.
        public float _timeActive; //Tiempo maximo que esta cada frase activa
        public GameObject _o2ActiveEnd; 
    }
    
    public TextMeshPro[] _textContainers; //Array de TextMeshPro en los que se muestra el texto 
    public _sentence[] _sentences; //Array de frases que diran nuestros protagonistas
    public _dialogBox[] _dialogBoxes; //El marco que puede mostrarse rodeando las frases. 

    [SerializeField]
    private float _speedWrite; //Tiempo que pasa entre que se escribe una letra y la otra. 

    //private bool _enableDisableBox = false; 
    private int _index = 0; //Contador interno para saber por que frase vamos. 


    private void Start()
    {
        CleanText(); //Limpiamos el texto que se pueda encontrar en los textmeshpro
        if (_sentences[_index]._active == true)
        {
            //En el caso de que la primera frase lo indique activamos el dialogbox. 
            EnableDisableBox(true);
        }
        //Empezamos la conversacion. 
        StartCoroutine(Talk());
        if (_sentences[_index]._timeActive > 0)
        {
            Invoke("ContinueDialog", _sentences[_index]._timeActive);
        }
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0) && _timeNextWrite <= Time.time)
        {
            /*En el caso de que se detecte una pulsacion
            de mouse se continua el dialogo. */
            
            _timeLastWrite = Time.time;
            _timeNextWrite = Time.time + ContinueDialog();
        }
    }

    public void CleanText()
    {
        //Eliminamos el texto de todos los TextMeshPro
        for (int i = 0; i < _textContainers.Length; i++)
        {
            _textContainers[i].text = "";
        }
    }

    /*
     * Esta funcion se ejecuta en paralelo.
     * Escribe las frases letra por letra. 
     * */
    IEnumerator Talk()
    {
        //Elimina el texto previo. 
        _textContainers[_sentences[_index]._character].text = "";
        foreach (char letra in _sentences[_index]._2say[GameManager._gm._language].ToCharArray())
         {
            //Suma cada letra al TextMeshPro
             _textContainers[_sentences[_index]._character].text += letra;
            //La funcion se espera el tiempo indicado.
            yield return new WaitForSeconds(_speedWrite);
         }

    }
    /*
     * Activa o desactiva el elemento que puede contener el texto
     * y que se lo indicamos en el editor
     * */
    public void EnableDisableBox(bool enable)
    {
        _dialogBoxes[_sentences[_index]._character]._box.SetActive(enable);
    }
    /*
     * Continua con la siguente frase del dialogo
     */
    public float ContinueDialog()
    {
        float tiempoEspera = 0; 
        if (_index < _sentences.Length)
        {
            if (_sentences[_index]._deactive == true)
            {
                //Si la frase anterios tenia que ser desactivada llamamos a
                //la funcion que desactiva su globo 
                EnableDisableBox(false);
            }
            //Aumentamos en 1 el _index con lo que pasamos a la siguiente frase. 
            _index += 1;
        }

        //Comprobamos que tenemos otra sentencia que escribir
        if (_index < _sentences.Length)
        {
            if (_sentences[_index]._active == true)
            {
                //Si es necesario activamos su dialog box
                EnableDisableBox(true);
            }
            tiempoEspera = _sentences[_index]._2say.Length * (_speedWrite * 10);
            StartCoroutine(Talk());
            if (_sentences[_index]._o2ActiveEnd != null)
            {
                //Si es necesario activamos su dialog box
                _sentences[_index]._o2ActiveEnd.SetActive(true); 
            }
            if (_sentences[_index]._timeActive > 0)
            {
                Invoke("ContinueDialog", _sentences[_index]._timeActive);
            }
        }
        else
        {
            //si es la ultima frase, limpiamos el texto. 
            CleanText();
        }
        return tiempoEspera;
    }
}

El script está autoexplicado! en los comentarios. Solo voy a comentar un poco mas su estructura.

Se basa en un array de frases, cada frase es de un struct definido que he llamado _sentence. Cada _sentence esta compuesta por el texto, el personaje al que pertenece y si tiene que activar o desactivar el bocadillo que rodea al texto.

¿Que como se sabe que numero es cada personaje? Pues cuando informamos el textmeshpro desde el editor, a cada uno le asigna un numero. Así el textmeshpro llamado Element 0, mostrará las frases que indiquemos que són del personaje 0.

La verdad….. mirad el vídeo que explicar esto por escrito es muy complicado.

Como crear un efecto Parallax en Unity, de una forma acojonantemente sencilla.

Lo primero es explicar qué es el efecto Parallax. Se trata de cuando las imágenes del fondo se mueven a Read more

Creación de nuestra primera aplicación en Unity!
Ejemplo de la aplicación Unity con los tres planetas creados

Todo esta listo, ya no hay excusas! Tenemos Unity instalado, el IDE configurado y todos los Assets que necesitamos en Read more

Como crear transiciones entre escenas para Unity

Veremos como crear transiciones entre escenas en Unity de una forma muy sencilla y elegante para usar en nuestros juegos. Read more

Desarrollo de videojuegos con Unity.

Empieza el tutorial de desarrollo de videojuegos con Unity! Si siempre has querido hacer un videojuego, si te llama la Read more

Por Martra

Un comentario en «Como crear un sistema de dialogos para Unity»

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *