372 lines
11 KiB
C#
372 lines
11 KiB
C#
using SK.Framework;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
/// <summary>
|
||
/// 标准用语仿真界面
|
||
/// </summary>
|
||
public class StandardExpressionView : UIView
|
||
{
|
||
public Variables variables;
|
||
private Text dialogueText;
|
||
private float typingSpeed = 0.05f;
|
||
private bool isTyping = false;
|
||
private Coroutine typingCoroutine;
|
||
private DialogueData currentDialogueData;
|
||
private int currentEntryIndex = 0;
|
||
private int currentLineIndex = 0;
|
||
private List<GameObject> activeChoiceButtons = new List<GameObject>();
|
||
|
||
private bool isLoadedDialogueData = false;
|
||
|
||
public GameObject role_manager;
|
||
public GameObject role_customer;
|
||
|
||
|
||
protected override void OnInit(IViewData data)
|
||
{
|
||
base.OnInit(data);
|
||
variables.Set<StandardExpressionView>("my_StandardExpression", this);
|
||
dialogueText = variables.Get<Text>("对话内容");
|
||
variables.Get<GameObject>("对话").GetComponent<Button>().onClick.AddListener(OnContinueClicked);
|
||
|
||
role_customer.Deactivate();
|
||
role_manager.Deactivate();
|
||
|
||
LoadDialogueData();
|
||
|
||
variables.Get<Button>("服务经理").onClick.AddListener(delegate { StartAsManager(); });
|
||
variables.Get<Button>("客户").onClick.AddListener(delegate { StartAsManager(false); });
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载对话数据,这里用的是ExcelCSVParser解析器
|
||
/// </summary>
|
||
private void LoadDialogueData()
|
||
{
|
||
//使用新的解析器
|
||
ExcelCSVParser parser = new ExcelCSVParser();
|
||
//这里用的是StreamingAssets文件夹下的CSV文件路径,可以根据实际情况调整路径
|
||
string csvPath = Application.streamingAssetsPath + "/Dialogues.csv";
|
||
//假设顾客对话数据,同理可以加载服务经理对话数据等
|
||
//string csvPath_Custom = Application.streamingAssetsPath + "/Dialogues_Custom.csv";
|
||
//检查文件是否存在,如果不存在则报错并返回
|
||
if (!parser.CheckFileExist(csvPath))
|
||
{
|
||
Debug.LogError("对话数据文件不存在!");
|
||
return;
|
||
}
|
||
|
||
DialogueData dialogueData = parser.ParseExcelCSV(csvPath);
|
||
|
||
StartDialogue(dialogueData);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始对话
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
public void StartDialogue(DialogueData data)
|
||
{
|
||
|
||
Debug.Log($"对话数据加载完成_{data == null}");
|
||
|
||
currentDialogueData = data;
|
||
currentEntryIndex = 0;
|
||
currentLineIndex = 0;
|
||
variables.Get<GameObject>("选项").Deactivate();
|
||
|
||
isLoadedDialogueData = true;
|
||
|
||
}
|
||
|
||
void StartAsManager(bool isManagerEnter = true)
|
||
{
|
||
if (!isLoadedDialogueData) return;
|
||
|
||
variables.Get<Button>("服务经理").interactable = false;
|
||
variables.Get<Button>("客户").interactable = false;
|
||
variables.Get<GameObject>("对话").Activate();
|
||
|
||
ShowCurrentDialogue();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回高能耗界面
|
||
/// </summary>
|
||
public void BackToTECESView()
|
||
{
|
||
base.Unload();
|
||
Load<HighEnergyConsumptionSTView>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 点击继续按钮事件处理函数
|
||
/// </summary>
|
||
private void OnContinueClicked()
|
||
{
|
||
if (isTyping)
|
||
{
|
||
// 快速完成打字
|
||
if (typingCoroutine != null)
|
||
StopCoroutine(typingCoroutine);
|
||
|
||
DialogueEntry entry = currentDialogueData.entries[currentEntryIndex];
|
||
if (currentLineIndex > 0 && currentLineIndex <= entry.dialogues.Count)
|
||
{
|
||
dialogueText.text = entry.dialogues[currentLineIndex - 1];
|
||
}
|
||
isTyping = false;
|
||
currentLineIndex++;
|
||
}
|
||
|
||
ShowCurrentDialogue();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 显示当前对话条目
|
||
/// </summary>
|
||
void ShowCurrentDialogue()
|
||
{
|
||
if (currentDialogueData == null || currentEntryIndex >= currentDialogueData.entries.Count)
|
||
{
|
||
Debug.Log($"对话结束_{currentDialogueData == null}_{currentEntryIndex >= currentDialogueData.entries.Count}");
|
||
//如果是currentEntryIndex >= currentDialogueData.entries.Count为True,并且输出乱码
|
||
//检查csv文件保存的编码格式是否正确,确保其为UTF-8
|
||
EndDialogue();
|
||
return;
|
||
}
|
||
|
||
DialogueEntry entry = currentDialogueData.entries[currentEntryIndex];
|
||
|
||
// 检查是否是事件条目
|
||
if (entry.hasEvent && entry.eventChoices.Count > 0)
|
||
{
|
||
Debug.Log("显示事件对话");
|
||
|
||
ShowEventDialogue(entry);
|
||
return;
|
||
}
|
||
|
||
// 显示普通对话
|
||
ShowNormalDialogue(entry);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 显示普通对话条目,并处理打字效果和事件触发逻辑。
|
||
/// </summary>
|
||
/// <param name="entry"></param>
|
||
void ShowNormalDialogue(DialogueEntry entry)
|
||
{
|
||
|
||
Debug.Log($"显示普通对话:当前角色-{entry.role},事件角色-{entry.eventRole},对话整体数据-{entry}");
|
||
|
||
switch (entry.role)
|
||
{
|
||
case "服务经理":
|
||
Debug.Log("1");
|
||
|
||
role_customer.Deactivate();
|
||
role_manager.Activate();
|
||
|
||
break;
|
||
case "客户":
|
||
Debug.Log("2");
|
||
|
||
role_manager.Deactivate();
|
||
role_customer.Activate();
|
||
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// 显示对话内容,检测打字协程状态并开始打字
|
||
if (currentLineIndex < entry.dialogues.Count)
|
||
{
|
||
string dialogue = entry.dialogues[currentLineIndex];
|
||
if (typingCoroutine != null)
|
||
StopCoroutine(typingCoroutine);
|
||
//开启打字效果
|
||
typingCoroutine = StartCoroutine(TypeText(dialogue));
|
||
}
|
||
else
|
||
{
|
||
// 对话显示完毕,检查是否有事件
|
||
if (entry.hasEvent)
|
||
{
|
||
// 触发事件,但不立即显示选项(等待玩家点击继续)
|
||
currentLineIndex = 0;
|
||
currentEntryIndex++;
|
||
ShowCurrentDialogue();
|
||
}
|
||
else
|
||
{
|
||
MoveToNextEntry();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打字效果协程,逐个字符显示文本。
|
||
/// </summary>
|
||
/// <param name="text"></param>
|
||
/// <returns></returns>
|
||
IEnumerator TypeText(string text)
|
||
{
|
||
isTyping = true;
|
||
dialogueText.text = "";
|
||
//dialogueText.color = Color.black;
|
||
|
||
|
||
Debug.Log($"打字开始_{text}");
|
||
|
||
foreach (char letter in text.ToCharArray())
|
||
{
|
||
dialogueText.text += letter;
|
||
yield return new WaitForSeconds(typingSpeed);
|
||
}
|
||
|
||
isTyping = false;
|
||
currentLineIndex++;
|
||
|
||
|
||
Debug.Log("打字完成");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 显示事件对话条目,并处理事件选项的显示。
|
||
/// </summary>
|
||
/// <param name="entry"></param>
|
||
void ShowEventDialogue(DialogueEntry entry)
|
||
{
|
||
variables.Get<GameObject>("选项").Activate();
|
||
|
||
// 显示事件描述
|
||
if (entry.dialogues.Count > 0)
|
||
{
|
||
dialogueText.text = entry.dialogues[0];
|
||
//dialogueText.color = Color.black;
|
||
}
|
||
else
|
||
{
|
||
dialogueText.text = "请做出选择:";
|
||
//dialogueText.color = Color.black;
|
||
}
|
||
|
||
// 生成选项按钮
|
||
CreateChoiceButtons(entry);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成选项按钮,并根据事件选择创建对应的UI元素。
|
||
/// </summary>
|
||
/// <param name="entry"></param>
|
||
void CreateChoiceButtons(DialogueEntry entry)
|
||
{
|
||
ClearChoiceButtons();
|
||
|
||
Debug.Log($"事件对话条目,选项数量:{entry.eventChoices.Count}");
|
||
|
||
for (int i = 0; i < entry.eventChoices.Count; i++)
|
||
{
|
||
if (string.IsNullOrEmpty(entry.eventChoices[i])) continue;
|
||
|
||
GameObject buttonObj = Instantiate(variables.Get<GameObject>("预制体"), variables.Get<GameObject>("选项Trans").transform);
|
||
Debug.Log($"创建选项按钮:{buttonObj.name},{entry.eventChoices[i].ToString()}");
|
||
|
||
buttonObj.Activate();
|
||
|
||
Text buttonText = buttonObj.GetComponentInChildren<Text>();
|
||
buttonText.text = entry.eventChoices[i];
|
||
|
||
int choiceIndex = i;
|
||
|
||
buttonObj.GetComponent<Button>().onClick.AddListener(() => OnChoiceSelected(choiceIndex, entry));
|
||
|
||
activeChoiceButtons.Add(buttonObj);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 选项按钮点击事件处理函数,根据选择执行相应操作。
|
||
/// </summary>
|
||
/// <param name="choiceIndex"></param>
|
||
/// <param name="entry"></param>
|
||
void OnChoiceSelected(int choiceIndex, DialogueEntry entry)
|
||
{
|
||
switch (choiceIndex)
|
||
{
|
||
case 0:
|
||
Debug.Log("选择了选项1");
|
||
break;
|
||
case 1:
|
||
Debug.Log("选择了选项2");
|
||
break;
|
||
case 2:
|
||
Debug.Log("选择了选项3");
|
||
break;
|
||
case 3:
|
||
Debug.Log("选择了选项4");
|
||
break;
|
||
}
|
||
variables.Get<GameObject>("选项").Deactivate();
|
||
MoveToNextEntry();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清除所有选项按钮,重置界面。
|
||
/// </summary>
|
||
void ClearChoiceButtons()
|
||
{
|
||
foreach (GameObject button in activeChoiceButtons)
|
||
{
|
||
Destroy(button);
|
||
}
|
||
activeChoiceButtons.Clear();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移动到下一个对话条目,并处理事件跳转逻辑。
|
||
/// </summary>
|
||
void MoveToNextEntry()
|
||
{
|
||
currentEntryIndex++;
|
||
currentLineIndex = 0;
|
||
|
||
// 检查是否需要跳转到特定事件
|
||
if (currentEntryIndex < currentDialogueData.entries.Count)
|
||
{
|
||
DialogueEntry nextEntry = currentDialogueData.entries[currentEntryIndex];
|
||
if (nextEntry.hasEvent && nextEntry.nextEntryIndex != -1)
|
||
{
|
||
currentEntryIndex = nextEntry.nextEntryIndex;
|
||
}
|
||
}
|
||
|
||
ShowCurrentDialogue();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 结束对话,清理界面并触发事件。
|
||
/// </summary>
|
||
void EndDialogue()
|
||
{
|
||
variables.Get<GameObject>("选项").Deactivate();
|
||
variables.Get<GameObject>("对话").Deactivate();
|
||
|
||
variables.Get<GameObject>("对话结束").Activate();
|
||
//roleText.gameObject.Deactivate();
|
||
|
||
/*
|
||
dialoguePanel.SetActive(false);
|
||
eventPanel.SetActive(false);
|
||
Debug.Log("对话系统: 所有对话已结束");
|
||
|
||
// 触发对话结束事件
|
||
OnDialogueEnded?.Invoke();*/
|
||
}
|
||
}
|