我在我的游戏中有一个对话系统,最近我发现如何通过协同机制一个一个地为对话添加字母。当点击屏幕时,我想跳过添加字母动画,然后立即完成对话。
这里有一个协同线,它循环遍历句子或字符串的字母,并显示在我的对话文本对象中。我找不到一个特定的关键字完成合作立即。是否有一种方法可以跳过或立即完成协同线,以便当对话被点击或屏幕被点击时,对话将立即完成?
显示对话和协同线的代码:
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++;
}
}发布于 2022-11-14 17:04:10
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);
}
}发布于 2022-11-14 19:33:02
我已经把我的方法加到协同线上了。我更喜欢将句柄保持在coroutine的末尾,并且在coroutine的末尾为空。因此,您可以重新启动这个协同线。FinishTypingSentence()会阻止它,并将全文设置在应有的位置。
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;
}https://stackoverflow.com/questions/74435109
复制相似问题