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.

Kurond. Una criatura ineficiente.

Kurond ha sido mi primera criatura creada para moverse con ML Agents. Es ineficiente por que su cuerpo esta MAL Read more

Guía para iniciarse en el desarrollo de juegos con Unity.

El mundo del desarrollo de videojuegos es muy complicado, no es sencillo, requiere de mucho esfuerzo y de dar un Read more

Incorporemos niveles a nuestro juego.

Ir avanzando por el juego, superando niveles, asumiendo nuevos retos y descubriendo nuevos mundos, es una de las sensaciones que Read more

Instalando Unity y mucho mas!
Primer paso del proceso de instalación de Unity.

Unity es un IDE de desarrollo de juegos. Con el se puede desarrollar para multitud de plataformas. Depende de las 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 *