Unity—对话系统&&GalGame游戏文字对话制作

每日一句:人间总有一两,填我十万八千梦

目录

对话系统

文本逐字打印功能

GalGame游戏(美少女游戏)文字对话


对话系统

被触发物体(挂载脚本)下UI,先不激活

public class TalkButton : MonoBehaviour

{

    public GameObject tipshow;//提示UI

    public GameObject talkUI;//对话UI

    private void OnTriggerEnter(Collider other)

    {

        Debug.Log("aaa");

        tipshow.SetActive(true);

    }

    private void OnTriggerExit(Collider other)

    {

        tipshow.SetActive(false);

    }

private void Update()

    {

        if(tipshow.activeSelf&&Input.GetKeyDown(KeyCode.R))

        {

            talkUI.SetActive(true);

        }

    }

}

TextAsset文档文件

 

(用记事本另存为txt文本文件,导入Unity中)

DialogSystem类

public class DialogSystem : MonoBehaviour

{

    public Text textLabel;//文字组件

    public Image faceImage;//头像图片

    public TextAsset textFile;

    public int index;//文本内容索引+

    public Sprite face01, face02;

    public float textSpeed;

    bool textFinished;//判断是否输出完了当前行的内容

    List<string> textList = new List<string>();

    bool cancelTyping;//取消逐字打印

    private void Awake()

    {

        GetTextFormFile(textFile);//从文本文件中得到文本内容

    }

    private void OnEnable()

    {

        textFinished = true;//当前文本没有输出完

        StartCoroutine(SetTextUI());//获得这一行长度的每一个文字,累加输出

    }

    private void Update()

    {

        if(Input.GetKeyDown(KeyCode.R)&&index==textList.Count)//如果按下R键,并且当前文本索引等于文本总长度

        {

            gameObject.SetActive(false);//销毁当前对话框

            index = 0;//索引归零

            return;

        }

        if (Input.GetKeyDown(KeyCode.R))//按下R键

        {

            if (textFinished && !cancelTyping)//如果上一行文本输入完,并没有取消逐字打印

            {

                StartCoroutine(SetTextUI());//开启逐字打印

            }

            else if (!textFinished && !cancelTyping)//如果上一行文本没有输入完,并没有取消逐字打印

            {

                cancelTyping = true;//取消逐字打印

            }

        }

    }

    /// <summary>

    /// 把整片文件分成每一行,输出到一个列表中,再转换成文本

    /// </summary>

    /// <param name="file"></param>

    void GetTextFormFile(TextAsset file)

    {

        textList.Clear();

        index = 0;

        var lineData = file.text.Split("\n");

        foreach(var line in lineData)

        {

            textList.Add(line);

        }

    }

    /// <summary>

    /// 获得这一行长度的每一个文字,累加输出

    /// </summary>

    /// <returns></returns>

    IEnumerator SetTextUI()

    {

        textLabel.text = "";

        textFinished = false;//文本内容正在输出

        switch (textList[index].Trim().ToString())

        {

            case "A":

                faceImage.sprite = face01;

                Debug.Log("aaa");

                index++;

                break;

            case "B":

                faceImage.sprite = face02;

                index++;

                Debug.Log("bbb");

                break;

        }

        int letter = 0;

        while(!cancelTyping&&letter<textList[index].Length-1)

        {

            Debug.Log("逐字打印");

            textLabel.text += textList[index][letter];

            letter++;

            yield return new WaitForSeconds(textSpeed);

        }

        cancelTyping = false;

        textFinished = true;

        index++;

    }

}

文本逐字打印功能

public class TypewriterEffect : MonoBehaviour

{

    public float charsPerSecond = 0.2f;//打字时间间隔

    private string words;//保存需要显示的文字

    private bool isActive = false;

    private float timer;//计时器

    private Text myText;

    private int currentPos = 0;//当前打字位置

    // Use this for initialization

    void Start()

    {

        timer = 0;

        isActive = true;

        charsPerSecond = Mathf.Max(0.2f, charsPerSecond);

        myText = GetComponent<Text>();

        words = myText.text;

        myText.text = "";//获取Text的文本信息,保存到words中,然后动态更新文本显示内容,实现打字机的效果

    }

    // Update is called once per frame

    void Update()

    {

        OnStartWriter();

    }

    /// <summary>

    /// 执行打字任务

    /// </summary>

    void OnStartWriter()

    {

        if (isActive)

        {

            timer += Time.deltaTime;

            if (timer >= charsPerSecond)

            { //判断计时器时间是否到达

                timer = 0;

                currentPos++;

                myText.text = words.Substring(0, currentPos);//刷新文本显示内容

                if (currentPos >= words.Length)

                {

                    OnFinish();

                }

            }

        }

    }

    /// <summary>

    /// 结束打字,初始化数据

    /// </summary>

    void OnFinish()

    {

        isActive = false;

        timer = 0;

        currentPos = 0;

        myText.text = words;

    }

}

substring()的作用就是截取父字符串的某一部分

public String substring(int beginIndex, int endIndex)

第一个参数int为开始的索引,对应String数字中的开始位置,

第二个参数是截止的索引位置,对应String中的结束位置

GalGame游戏(美少女游戏)文字对话

Galgame游戏

剧本数据类

public class GameManager_BE : MonoBehaviour

{

    public static GameManager_BE Instance { get; private set; }//单例模式

    private List<ScriptData_BE> scriptDatas_BE;

    private int scriptIndex;

private void Awake()

    {

        Instance = this;

        scriptDatas_BE = new List<ScriptData_BE>()

        { //编写剧本对话

            new ScriptData_BE()

            {

                loadType=1,BGspriteName="bg1"//背景图片名字路径

            },

            new ScriptData_BE()

            {

                loadType=2,dialogueContent="上古时期,魔神出世,颠覆六界,屠戮生灵"

            },

             new ScriptData_BE()

            {

                loadType=2,dialogueContent="诸天神尊牺牲毕生修为,献祭无上神器,才得以斩杀魔神。"

            },

              new ScriptData_BE()

            {

                loadType=2,dialogueContent="那一战,众神陨落,神器破碎,换来了,世间万年安宁。"

            },  

            new ScriptData_BE()

            {

                loadType=1,BGspriteName="bg2"//背景图片名字路径

            },

               new ScriptData_BE()

            {

                loadType=2,dialogueContent="然而万年后,第二位魔神横空出世,"

               

            },

                  new ScriptData_BE()

            {

                loadType=2,dialogueContent="他残忍嗜血,暴虐无道,比上古魔神更甚。"

            },

            new ScriptData_BE()

            {

                loadType=2,dialogueContent="各仙门拼死抵抗,修道者前赴后继。"

            },

            new ScriptData_BE()

            {

                loadType=2,dialogueContent="但,尘世已无神。"

            },

             new ScriptData_BE()

            {

                loadType=1,BGspriteName="bg4"//背景图片名字路径

            },

            new ScriptData_BE()

            {

                loadType=3,name="衡阳宗宗主",dialogueContent="自古魔王能号令天下魔物,因其天生邪骨,超脱六界。"

            },

            new ScriptData_BE()

            {

                loadType=3,name="衡阳宗宗主",dialogueContent="过去镜指出,五百年前的魔王,原身是个凡人,叫澹台烬。"

            },

             new ScriptData_BE()

            {

                loadType=3,name="衡阳宗宗主",dialogueContent="苏苏,今日子时是最佳时辰"

            },

              new ScriptData_BE()

            {

                loadType=3,name="衡阳宗宗主",dialogueContent="众位长老会用毕生修为,送你回到五百年前。"

            },

               new ScriptData_BE()

            {

                loadType=3,name="衡阳宗宗主",dialogueContent="那时的魔王还是凡人,你要抽出他邪骨,阻止他觉醒。"

            },

                new ScriptData_BE()

            {

                loadType=3,name="衡阳宗宗主",dialogueContent="想要拯救苍生,只有这个办法"

            },

                    new ScriptData_BE()

            {

                loadType=3,name="黎苏苏",dialogueContent="爹爹放心,苏苏一定全力以赴"

            },

                      new ScriptData_BE()

            {

                loadType=3,name="公治寂无",dialogueContent="师父,师妹年纪还小,让我代她吧"

            },

        };

        scriptIndex = 0;

        HandleData();

    }

    /// <summary>

    /// 处理每一条剧情数据

    /// </summary>

    private void HandleData()

    {

        if (scriptIndex >= scriptDatas_BE.Count)

        {

            Debug.Log("游戏结束");

            return;

        }

        

        if (scriptDatas_BE[scriptIndex].loadType == 1)

        {

            //设置一下背景图片

            SetBGImageSprite(scriptDatas_BE[scriptIndex].BGspriteName);

            //加载下一条剧情数据

            LoadNextScript();

        }

        if (scriptDatas_BE[scriptIndex].loadType == 2)//旁白对话

        {

            

            //更新对话框文本

            UpdateTalkLineText(scriptDatas_BE[scriptIndex].dialogueContent);

        }

        if (scriptDatas_BE[scriptIndex].loadType == 3)//人物对话

        {

            

            //显示人物

            ShowCharacter(scriptDatas_BE[scriptIndex].name);

            //更新对话框文本

            UpdateTalkLineText(scriptDatas_BE[scriptIndex].dialogueContent);

        }

    }

    //设置一下背景图片

    private void SetBGImageSprite(string spriteName)

    {

        UIManager_BE.Instance.SetBGImageSprite(spriteName);

    }

    //加载下一条剧情数据

    public void LoadNextScript()

    {

        Debug.Log("加载下一条剧情");

        scriptIndex++;

        HandleData();

    }

    //显示人物

    private void ShowCharacter(string name)

    {

        UIManager_BE.Instance.ShowCharacter(name);

    }

    //更新对话框文本

    private void UpdateTalkLineText(string dialogueContent)

    {

        UIManager_BE.Instance.UpdateTalkLineText(dialogueContent);

    }

}

/// <summary>

/// 剧本数据

/// </summary>

public class ScriptData_BE

{

    public int loadType;//载入资源类型 1.更换背景 2.旁白对话

    public string name;//角色名称

    public string BGspriteName;//图片资源路径

    public string dialogueContent;//对话内容

}

UIManager_BE

public class UIManager_BE : MonoBehaviour

{

    public static UIManager_BE Instance { get; private set; }

    public Image imgBG;//背景图片组件

    public Image imgCharacter;//人物图片组件

    public Text textName;//人物名称文字组件

    public Text textTalkLine;//人物对话文字组件

    public GameObject talkLineGo;//对话框父对象游戏物体

    private void Awake()

    {

        Instance = this;

    }

    /// <summary>

    /// 设置背景图片

    /// </summary>

    /// <param name="spriteName"></param>

    public void SetBGImageSprite(string spriteName)

    {

        imgBG.sprite = Resources.Load<Sprite>("Sprite_BE/" + spriteName);

    }

    /// <summary>

    /// 显示人物

    /// </summary>

    /// <param name="name"></param>

    public void ShowCharacter(string name)

    {

        talkLineGo.SetActive(true);

        imgCharacter.sprite = Resources.Load<Sprite>("Sprite_BE/" + name);

        imgCharacter.gameObject.SetActive(true);

        textName.text = name;

    }

    /// <summary>

    /// 更新对话内容

    /// </summary>

    /// <param name="dialogueContent"></param>

    public void UpdateTalkLineText(string dialogueContent)

    {

        textTalkLine.text = dialogueContent;

    }

}

通过按钮点击对话框,推动人物进行

【仅当学习笔记,特别感谢:M_Studio 我是Trigger呀 UP主,】

猜你喜欢

转载自blog.csdn.net/m0_63330263/article/details/128921627