首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何跳过/立即完成协同线?

如何跳过/立即完成协同线?
EN

Stack Overflow用户
提问于 2022-11-14 16:49:06
回答 2查看 30关注 0票数 0

我在我的游戏中有一个对话系统,最近我发现如何通过协同机制一个一个地为对话添加字母。当点击屏幕时,我想跳过添加字母动画,然后立即完成对话。

这里有一个协同线,它循环遍历句子或字符串的字母,并显示在我的对话文本对象中。我找不到一个特定的关键字完成合作立即。是否有一种方法可以跳过或立即完成协同线,以便当对话被点击或屏幕被点击时,对话将立即完成?

显示对话和协同线的代码:

代码语言:javascript
运行
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System;

public class InformantDialogue : MonoBehaviour
{
    // NPC DATA
    private Informant informantJson;
    [SerializeField] TextAsset characterData;

    // DIALOG UI
    [SerializeField] GameObject dialogBox, article;
    [SerializeField] TextMeshProUGUI dialogue;

    // DIALOG CYCLE VARIABLES
    private bool clickEnable;
    private int dialogId, multiDialogCycle;
    public int progress;
    string[] multiDialog;

    private void OnEnable()
    {
        setJSON();
        loadCharacterData();
    }

    void Start()
    {
        dialogId = 1;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0) && clickEnable == true)
        {
            Debug.Log(dialogId);    
            if (multiDialog.Length > 1)
            {
                if (multiDialogCycle == multiDialog.Length - 1)
                {
                    closeDialog();
                    progressDialog();
                }
                else
                {
                    multiDialogCycle++;
                    loadCharacterData();
                }
            }
            else
            {
                closeDialog();
                progressDialog();
            }
        }
    }

    public void loadCharacterData()
    {
        // DIALOGUE
        multiDialog = getIDialog(dialogId).dialog_message.Split('#');

        if (multiDialogCycle == 4)
        {
            article.SetActive(true);
        }

        if (multiDialog.Length == 1)
        {
            //dialogue.text = getIDialog(dialogId).dialog_message;
            StopAllCoroutines();
            StartCoroutine(TypeSentence(getIDialog(dialogId).dialog_message));
        }
        else if (multiDialogCycle < multiDialog.Length)
        {
            //dialogue.text = multiDialog[multiDialogCycle];
            StopAllCoroutines();
            StartCoroutine(TypeSentence(multiDialog[multiDialogCycle]));
            clickEnable = true;
        }
    }

    // INFORMANT DIALOGUE GETTER
    public InformantDialog getIDialog(int dialogId)
    {
        foreach (InformantDialog dialog in informantJson.informant_dialogs)
        {
            if (dialog.id == dialogId)
            {
                return dialog;
            }
        }
        return informantJson.informant_dialogs[0];
    }

    IEnumerator TypeSentence(string sentence)
    {
        dialogue.text = "";
        foreach(char letter in sentence.ToCharArray())
        {
            dialogue.text += letter;
            //yield return null;
            yield return new WaitForSeconds(0.01f);
        }
    }

    private void showDialogue()
    {
        dialogBox.SetActive(true);
    }

    private void closeDialog()
    {
        dialogBox.SetActive(false);
        clickEnable = false;
        multiDialogCycle = 0;
    }

    private void setJSON()
    {
        if (progress == 0)
        {
            characterData = Resources.Load<TextAsset>("JSON/Informant");
        }else if (progress == 1)
        {
            characterData = Resources.Load<TextAsset>("JSON/Informant1");
        }
        else if (progress == 2)
        {
            characterData = Resources.Load<TextAsset>("JSON/Informant2");
        } else
        {
            clickEnable = false;
        }
        informantJson = JsonUtility.FromJson<Informant>(characterData.text);
    }

    private void progressDialog()
    {
        if (dialogId == informantJson.informant_dialogs.Length)
        {
            dialogId = 0;
            progress++;
        }
        dialogId++;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-14 17:04:10

代码语言:javascript
运行
复制
IEnumerator TypeSentence(string sentence)
{
    boolThatStartFalseAndWillBeTrueWhenPlayerClickOnScreen = false;
    dialogue.text = "";
    foreach(char letter in sentence.ToCharArray())
    {
        if (boolThatStartFalseAndWillBeTrueWhenPlayerClickOnScreen)
        {
            dialogue.text = sentence;
            break;
        }
        dialogue.text += letter;
        //yield return null;
        yield return new WaitForSeconds(0.01f);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-11-14 19:33:02

我已经把我的方法加到协同线上了。我更喜欢将句柄保持在coroutine的末尾,并且在coroutine的末尾为空。因此,您可以重新启动这个协同线。FinishTypingSentence()会阻止它,并将全文设置在应有的位置。

代码语言:javascript
运行
复制
string typedSentence;
private IEnumerator _typeSentenceCoroutine;

//Caching this will save some memory allocation.
WaitForSeconds waitFor01Seconds = new WaitForSeconds(0.01f);

void StartTypingSentence()
{
    if (_typeSentenceCoroutine != null) StopCoroutine(_typeSentenceCoroutine);
    _typeSentenceCoroutine = TypeSentence();
    StartCoroutine(_typeSentenceCoroutine);
}
public void FinishTypingSentence()
{
    if (_typeSentenceCoroutine != null) StopCoroutine(_typeSentenceCoroutine);
    _typeSentenceCoroutine = null;
    dialogue.text = typedSentence;
}

IEnumerator TypeSentence()
{
    dialogue.text = "";
    foreach (char letter in typedSentence.ToCharArray())
    {
        dialogue.text += letter;
        yield return waitFor01Seconds;
    }
    _typeSentenceCoroutine = null;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74435109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档