EnergyEfficiencyManagement/Assets/Zion/Scripts/UIView/StandardExpressionView.cs

372 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();*/
}
}