/// <summary> /// 判断指定的节点是否存在指定的任务 /// </summary> /// <param name="target">查找的顶层节点</param> /// <param name="taskID">查找任务id</param> /// <param name="taskPoint">查找到的节点</param> /// <returns></returns> private bool DialoguePointHasThisTask(DialoguePoint target, string taskID, out DialoguePoint taskPoint) { taskPoint = null; if (string.IsNullOrEmpty(taskID)) { return(false); } DialogueValue dialogueValue = dialogueStructData.SearchDialogueValueByID(target.dialogueID); if (!string.IsNullOrEmpty(dialogueValue.otherValue) && string.Equals(dialogueValue.otherValue.Trim(), taskID.Trim())) { taskPoint = target; return(true); } else { if (target.childDialoguePoints != null && target.childDialoguePoints.Length > 0)//如果存在子节点 { foreach (DialoguePoint child in target.childDialoguePoints) { bool result = DialoguePointHasThisTask(child, taskID, out taskPoint); if (result) { return(true); } } } return(false); } }
/// <summary> /// 展示对话 /// </summary> private void ShowTalk() { //通过npc的id获取显示的图片 Sprite showImage = null; DialogueValue nowDialogueValue = dialogueStructData.SearchDialogueValueByID(nowDialoguePoint.dialogueID); string showText = nowDialogueValue.showValue; if (lastNPCID != nowDialogueValue.npcID)//本次的NPCid和上次的不一致则左右显示切换 { showLeftOrRight = !showLeftOrRight; } lastNPCID = nowDialogueValue.npcID; showImage = iNPCSpriteState.GetSprite(nowDialogueValue.npcID); if (showLeftOrRight) { rightImage.gameObject.SetActive(false); leftImage.gameObject.SetActive(true); leftImage.sprite = showImage; leftImage.enabled = showImage != null; leftText.text = showText; } else { rightImage.gameObject.SetActive(true); leftImage.gameObject.SetActive(false); rightImage.sprite = showImage; rightImage.enabled = showImage != null; rightText.text = showText; } }
/// <summary> /// 将任务id push到队列中 /// </summary> /// <param name="source"></param> /// <param name="targetTaskIDs"></param> /// <param name="targetTaskPoints"></param> private void PushDialoguePointTask(DialoguePoint source, Queue <int> targetTaskIDs = null, Queue <DialoguePoint> targetTaskPoints = null) { DialogueValue dialogueValue = dialogueStructData.SearchDialogueValueByID(source.dialogueID); if (targetTaskPoints != null && !targetTaskPoints.Contains(source)) { targetTaskPoints.Enqueue(source); } int taskID; if (!string.IsNullOrEmpty(dialogueValue.otherValue) && int.TryParse(dialogueValue.otherValue, out taskID)) { if (targetTaskIDs != null && !targetTaskIDs.Contains(taskID)) { targetTaskIDs.Enqueue(taskID); } } if (source.childDialoguePoints != null && source.childDialoguePoints.Length > 0)//如果存在子节点 { foreach (DialoguePoint childPoint in source.childDialoguePoints) { PushDialoguePointTask(childPoint, targetTaskIDs, targetTaskPoints); } } }
/// <summary> /// 检测对话 /// </summary> private void CheckTalk() { //创建新的 var touchIDs = npcIDToTalkShowStructDic.Keys.OfType <int>().ToArray(); foreach (int touchID in touchIDs) { TalkShowStruct talkShowStruct = npcIDToTalkShowStructDic[touchID]; float nextTime = talkShowStruct.nowTime + Time.deltaTime; var selectCreates = talkShowStruct.pointToCreateTime.Where(temp => temp.Value >= talkShowStruct.nowTime && temp.Value < nextTime).ToArray(); talkShowStruct.nowTime = nextTime; foreach (var selectCreate in selectCreates) { DialogueValue dialogueValue = dialogueStructData.SearchDialogueValueByID(selectCreate.Key.dialogueID); if (dialogueValue == null) { continue; } int thisDialogueNPCID = dialogueValue.npcID; //在哪个npc头顶显示 string thisDialogueValue = dialogueValue.showValue; //显示的文字 float intervalTime = talkShowStruct.pointToIntervalTime[selectCreate.Key]; //显示的持续时间 if (!npcIDToShowObjDic.ContainsKey(thisDialogueNPCID)) { GameObject createObj = GameObject.Instantiate <GameObject>(talkShowExplanObj);//这是一个UI面板(这个面板一经创建就不会消失了,但是正常情况下是隐藏的,只有当存在显示文字的时候才会显示) npcIDToShowObjDic.Add(thisDialogueNPCID, createObj); //设置位置 NPCDataInfo npcDataInfo = npcData.GetNPCDataInfo(iGameState.SceneName, thisDialogueNPCID); npcDataInfo.Load(); if (npcDataInfo != null) { createObj.transform.position = npcDataInfo.NPCObj.transform.position + npcDataInfo.TalkShowOffset; } } GameObject talkUIObj = npcIDToShowObjDic[thisDialogueNPCID];//取出用于显示文字的ui面板 UITalkShowControl uiTalkShowControl = talkUIObj.GetComponent <UITalkShowControl>(); if (uiTalkShowControl != null) { uiTalkShowControl.AddNewTalk(thisDialogueValue, intervalTime); } } if (talkShowStruct.nowTime > talkShowStruct.maxTime) { npcIDToTalkShowStructDic.Remove(touchID); } } if (npcIDToTalkShowStructDic.Count <= 0) { runTaskStruct.StopTask(); } }
/// <summary> /// 根据现有数据创建控件 /// </summary> /// <param name="parent">父控件</param> /// <param name="dialoguePoints">节点关系对象</param> private void CreateControlByData(IDialoguePointID parent, params DialoguePoint[] dialoguePoints) { foreach (DialoguePoint dialoguePoint in dialoguePoints) { DialogueValue dialogueValue = dialogueAnalysisData.GetDialoguePointByID(dialoguePoint.dialogueID); if (dialogueValue == null) { continue; } DialoguePointControl dialoguePointControl = AddNewChildNode(parent as ISelectedControl, dialogueValue, false);//添加一个子节点 if (dialoguePoint.childDialoguePoints != null && dialoguePoint.childDialoguePoints.Length > 0) { CreateControlByData(dialoguePointControl, dialoguePoint.childDialoguePoints); } } }
public DialoguePointControl(DialogueValue dialogueValue) { InitializeComponent(); childIDList = new List <IDialoguePointID>(); if (dialogueValue == null) { this.dialogueValue = new DialogueValue(); this.dialogueValue.dialogueID = IDCreator.Instance.GetNextID(); this.dialogueValue.npcID = -1; this.dialogueValue.voiceID = -1; this.dialogueValue.titleValue = ""; this.dialogueValue.showValue = ""; this.dialogueValue.otherValue = ""; } else { this.dialogueValue = dialogueValue; } Init(); }
/// <summary> /// 显示对话 /// </summary> /// <param name="dialogueCondition">对话的文本</param> private void ShowTalk(DialogueCondition dialogueCondition) { TalkShowStruct talkShowStruct = new TalkShowStruct(); Queue <int> targetTaskIDs = new Queue <int>(); Queue <DialoguePoint> targetTaskPoints = new Queue <DialoguePoint>(); PushDialoguePointTask(dialogueCondition.topPoint, targetTaskIDs, targetTaskPoints); float maxTime = 0; foreach (DialoguePoint targetTaskPoint in targetTaskPoints) { DialogueValue dialogueValue = dialogueStructData.SearchDialogueValueByID(targetTaskPoint.dialogueID); if (dialogueValue == null) { continue; } string otherValue = dialogueValue.otherValue; if (string.IsNullOrEmpty(otherValue)) { continue; } string[] splitsValue = otherValue.Split(','); if (splitsValue.Length == 2) { float startTime = 0; //开始时间 float intervalTime = 0; //持续时间 if (!(float.TryParse(splitsValue[0], out startTime) && float.TryParse(splitsValue[1], out intervalTime))) { continue; } float endTime = startTime + intervalTime; maxTime = maxTime > endTime ? maxTime : endTime; talkShowStruct.pointToCreateTime.Add(targetTaskPoint, startTime); talkShowStruct.pointToIntervalTime.Add(targetTaskPoint, intervalTime); } } talkShowStruct.maxTime = maxTime; npcIDToTalkShowStructDic.Add(dialogueCondition.touchNPCID, talkShowStruct); }
/// <summary> /// 将controls的数据设置到TreeNode中 /// </summary> /// <param name="treeNode"></param> /// <param name="controls"></param> private void SetControlToTreeNode(TreeNode treeNode, params Control[] controls) { foreach (Control control in controls) { DialoguePointControl dialoguePointControl = control as DialoguePointControl; if (dialoguePointControl != null) { DialogueValue dialogueValue = dialoguePointControl.GetDialogueValue(); TreeNode childTreeNode = new TreeNode(); treeNode.Nodes.Add(childTreeNode); childTreeNode.Tag = dialogueValue; childTreeNode.Text = "ID:[" + dialogueValue.dialogueID + "];NPC ID:[" + dialogueValue.npcID + "];Title:[" + dialogueValue.titleValue + "];Value:[" + dialogueValue.showValue + "]"; if (dialoguePointControl.Tag != null && (dialoguePointControl.Tag as List <Control>) != null && (dialoguePointControl.Tag as List <Control>).Count > 0) { SetControlToTreeNode(childTreeNode, (dialoguePointControl.Tag as List <Control>).ToArray()); } } } }
/// <summary> /// 展示对话 /// </summary> private void ShowTalk() { DialogueValue dialogueValue = dialogueStructData.SearchDialogueValueByID(nowDialoguePoint.dialogueID); titleText.text = dialogueValue.showValue; int childCount = selectItemBackTrans.childCount; Transform[] childTransfroms = new Transform[childCount]; for (int i = 0; i < childCount; i++) { childTransfroms[i] = selectItemBackTrans.GetChild(i); } for (int i = 0; i < childCount; i++) { if (!Transform.Equals(childTransfroms[i], exampleItemObj.transform))//如果不是例子对象则销毁 { GameObject.DestroyImmediate(childTransfroms[i].gameObject); } } showItemList.Clear(); //添加 Action <string, Action <Transform> > AddItemAction = (showValue, ClickCallback) => { GameObject createItemObj = GameObject.Instantiate <GameObject>(exampleItemObj); createItemObj.transform.SetParent(selectItemBackTrans); createItemObj.SetActive(true); Transform itemTextTrans = createItemObj.transform.GetChild(0); Text itemText = itemTextTrans.GetComponent <Text>(); itemText.text = showValue; showItemList.Add(createItemObj.transform); //添加事件 EventTrigger eventTrigger = createItemObj.AddComponent <EventTrigger>(); eventTrigger.triggers = new List <EventTrigger.Entry>(); //点击事件 EventTrigger.Entry entry_Click = new EventTrigger.Entry(); entry_Click.eventID = EventTriggerType.PointerClick; entry_Click.callback = new EventTrigger.TriggerEvent(); entry_Click.callback.AddListener(temp => ClickCallback(createItemObj.transform)); eventTrigger.triggers.Add(entry_Click); //鼠标进入事件 EventTrigger.Entry entry_Enter = new EventTrigger.Entry(); entry_Enter.eventID = EventTriggerType.PointerEnter; entry_Enter.callback = new EventTrigger.TriggerEvent(); entry_Enter.callback.AddListener(temp => { createItemObj.GetComponent <Image>().color = new Color(1, 1, 1, 0.4f); selectItemIndex = showItemList.IndexOf(createItemObj.transform); }); eventTrigger.triggers.Add(entry_Enter); //鼠标离开事件 EventTrigger.Entry entry_Leave = new EventTrigger.Entry(); entry_Leave.eventID = EventTriggerType.PointerExit; entry_Leave.callback = new EventTrigger.TriggerEvent(); entry_Leave.callback.AddListener(temp => createItemObj.GetComponent <Image>().color = new Color(1, 1, 1, 0)); eventTrigger.triggers.Add(entry_Leave); }; DialoguePoint[] childPoints = nowDialoguePoint.childDialoguePoints; foreach (DialoguePoint dialoguePoint in childPoints) //便利添加子选项 { if (dontShowDialoguePointList.Contains(dialoguePoint)) //不显示的不添加 { continue; } DialogueValue childDialogueValue = dialogueStructData.SearchDialogueValueByID(dialoguePoint.dialogueID); AddItemAction(childDialogueValue.titleValue, temp => { int index = showItemList.IndexOf(temp); DialoguePoint[] nowShowChildsPoints = nowDialoguePoint.childDialoguePoints.Where(point => !dontShowDialoguePointList.Contains(point)).ToArray(); if (index < 0 || index >= nowShowChildsPoints.Length) { return; } DialoguePoint clickPoint = nowShowChildsPoints[index]; if (clickPoint.childDialoguePoints == null || clickPoint.childDialoguePoints.Length == 0) //如果有任务则接取,如果没有则不做处理 { DialogueValue clickValue = dialogueStructData.SearchDialogueValueByID(clickPoint.dialogueID); if (!string.IsNullOrEmpty(clickValue.otherValue)) { int taskID = -1; if (int.TryParse(clickValue.otherValue, out taskID)) { TaskMap.RunTimeTaskInfo runTimeTaskInfo = runtimeTasksData.GetTasksWithID(taskID); if (runTimeTaskInfo != null && runTimeTaskInfo.IsOver == false && runTimeTaskInfo.IsStart == false) { iNowTaskState.StartTask = runTimeTaskInfo.ID; gameObject.SetActive(false); } } } } else //继续进入下面节点 { nowDialoguePoint = clickPoint; ShowTalk(); } }); } //最后添加一个返回选项 AddItemAction("返回", temp => { if (nowDialoguePoint.parentDialoguePoint != null) { nowDialoguePoint = nowDialoguePoint.parentDialoguePoint; ShowTalk(); } else { gameObject.SetActive(false); } }); StartCoroutine(UpdateContentSizeFitter(panelContentSizeFitter)); //选择第一个下标 selectItemIndex = 0; SetSelectItemIndex(); }
/// <summary> /// 读取数据 /// </summary> /// <param name="relationValues">关系以及条件数据</param> /// <param name="dialogueValues">对话数据</param> /// <returns>返回最大的id</returns> public int ReadData(string relationValues, string dialogueValues) { dialogueValueDic = new Dictionary <int, DialogueValue>(); dialogueConditionList = new List <DialogueCondition>(); //处理关系 byte[] relationValueBytes = Encoding.UTF8.GetBytes(relationValues); MemoryStream ms_relation = new MemoryStream(relationValueBytes); using (StreamReader sr = new StreamReader(ms_relation)) { string readLine = null; DialogueCondition dialogueCondition = null; string dialogueStr = ""; while ((readLine = sr.ReadLine()) != null) { switch (readLine.Trim()) { case StartItemFlag: dialogueCondition = new DialogueCondition(); break; case EndItemFlag: if (dialogueCondition != null) { dialogueCondition.SetData(dialogueStr); dialogueConditionList.Add(dialogueCondition); dialogueStr = ""; dialogueCondition = null; } break; default: dialogueStr += readLine + "\r\n"; break; } } } int maxID = 0; //处理对话数据 byte[] dataValueBytes = Encoding.UTF8.GetBytes(dialogueValues); MemoryStream ms_data = new MemoryStream(dataValueBytes); using (StreamReader sr = new StreamReader(ms_data)) { string readLine = null; DialogueValue dialogueValue = null; string dialogueStr = ""; while ((readLine = sr.ReadLine()) != null) { switch (readLine.Trim()) { case StartItemFlag: dialogueValue = new DialogueValue(); break; case EndItemFlag: if (dialogueValue != null) { int id = dialogueValue.SetData(dialogueStr); if (!dialogueValueDic.ContainsKey(id)) { dialogueValueDic.Add(id, dialogueValue); } maxID = maxID > id ? maxID : id; dialogueStr = ""; dialogueValue = null; } break; default: dialogueStr += readLine + "\r\n"; break; } } } return(maxID); }
/// <summary> /// 添加一个子节点 /// </summary> /// <param name="iSelectedControlNow">要添加子节点的节点</param> private DialoguePointControl AddNewChildNode(ISelectedControl iSelectedControlNow, DialogueValue dialogueValue = null, bool updateControl = true) { IDialoguePointID iDialoguePointID = iSelectedControlNow as IDialoguePointID; if (iDialoguePointID.GetType().Equals(typeof(DialogueConditionControl)))//顶层节点(关系关系)只能添加一个子节点(数据节点) { if (iDialoguePointID.GetDialogueNextPointID.Length > 0) { return(null); } } if (iDialoguePointID != null) { DialoguePointControl dialoguePointControl = new DialoguePointControl(dialogueValue); dialoguePointControl.Size = dialoguePointControl.StopSize; dialoguePointControl.SetListenControlSelected(ListenControlSelected); dialoguePointControl.SetLiestenOpenStop(AddListenOpenStop); dialoguePointControl.Tag = new List <Control>(); Control iSelectedControl = iSelectedControlNow as Control; List <Control> childControl = iSelectedControl.Tag as List <Control>; childControl.Add(dialoguePointControl); Control parentControl = iSelectedControlNow.GetParent(); parentControl.Controls.Add(dialoguePointControl); iDialoguePointID.AddNextPointID(dialoguePointControl); if (updateControl) { ResetControlRect(parentControl); } if (searchNodeForm != null) { searchNodeForm.NodeChanged = true; } return(dialoguePointControl); } return(null); }