我正在创建一个脚本,控制对话,并在Unity游戏中给主角任务。有一个任务列表,根据列表中变量的数量,对话可以改变。如果变量等于1主角得到了一个任务,2任务完成,3主要人物告诉NPC任务完成。当NPC碰撞器被触发时,对话图像出现,玩家看到NPC的话和2个可能的答案按钮。一个按钮关闭对话图像,另一个按钮进一步移动对话。
问题是,我找不到如何使它工作(tasks\[0\] == 3)
的方式。因为它不会改变和对话循环。我试图把它放在不同的地方,但没有什么改变。
我是一个初学者,所以可能会有一些愚蠢的错误,我没有注意到。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Dialogue : MonoBehaviour
{
[SerializeField] GameObject dialogue;
[SerializeField] Text npcText;
[SerializeField] List<Text> buttonText = new List<Text>();
public DialogueBlock[] dialogueBlock;
[SerializeField] public PlayerController playerController;
int dialogueBlockPlace = 0;
public List<int> tasks = new List<int>();
[SerializeField] List<string> taskString = new List<string>();
public void OnTriggerEnter(Collider other)
{
if(other.tag == "Player")
{
dialogue.SetActive(true);
dialogueBlockPlace = 0;
Answer(0);
}
}
public void OnTriggerExit(Collider other)
{
if(other.tag == "Player")
{
dialogue.SetActive(false);
}
}
private void Answer(int num)
{
npcText.text = dialogueBlock[num].npcText;
buttonText[0].text = dialogueBlock[num].playerAnswer[0].Text;
buttonText[1].text = dialogueBlock[num].playerAnswer[1].Text;
}
public void AnswerButtonClicked(int buttonNum)//u=mesti ant mygtuko
{
if(dialogueBlock[dialogueBlockPlace].playerAnswer[buttonNum].speakEnd)
{
dialogue.SetActive(false);
}
dialogueBlockPlace = dialogueBlock[dialogueBlockPlace].playerAnswer[buttonNum].toBlock;
TaskStarted();
if (dialogueBlock[dialogueBlockPlace].playerAnswer[buttonNum].questInt == 1)
{
if (tasks[0] == 0)
{
tasks[0] = 1;
}
else if (tasks[0] > 2)
{
tasks[1] = 1;
}
else if (tasks[1] > 2 )
{
tasks[2] = 1;
}
}
DialogueControl();
}
public void DialogueControl()
{
TaskDone();
ChangeText();
print(dialogueBlockPlace);
Answer(dialogueBlockPlace);
}
private void TaskStarted()
{
if (tasks[0] == 1 || tasks[1] == 1 || tasks[2] == 1)
{
dialogueBlockPlace = 4;
}
}
private void TaskDone()
{
if (tasks[0] == 2 || tasks[1] == 2 || tasks[2] == 2)
{
dialogueBlockPlace = 3;
tasks[0] = 3;//dont work
}
}
public void ChangeText()
{
if (tasks[0]==0)
{
dialogueBlock[2].npcText = taskString[0];
}
if (tasks[0] == 3)
{
dialogueBlock[2].npcText = taskString[1];
}
if (tasks[1] == 3)
{
dialogueBlock[2].npcText = taskString[2];
}
}
}
[System.Serializable]
public class DialogueBlock
{
public string npcText;
public PlayerAnswer[] playerAnswer;
}
[System.Serializable]
public class PlayerAnswer
{
public string Text;
public int toBlock;
public bool speakEnd;
public int questInt;
}
1条答案
按热度按时间rsaldnfx1#
40年前,用整数编码状态是可以的,但现在是一个糟糕的做法,因为我们有所有这些讨厌的对象,编程范式和智能模式。本质上,你在这里缺少的是至少两个类和枚举来正确命名和封装它们:
使用对象构建你的控制流,从代码中提取行为,将它们隔离在方法中,如果方法需要处理复杂的状态,它可以很容易地成为一个单独的对象。只是在Unity中不要把所有东西都放在自己的MonoBehavior中,你可以使用常规类,特别是对于生命周期服务:
当然,这只是一个粗略的说明,您更愿意使用舒适的ScriptableObjects来存储不同的行为实现,但您已经抓住了要点。