前言
对话面板属于剧情系统中的一环,单独做成一个prefab,放在resource文件下,在用到的时候,读取。
简单界面
首先创建类,对话要有人,要显示对话人的信息,对话要有内容,同时和对话人联系上,简单说就是哪个人说了哪句话,下面改哪个人说哪句话
//存放对话中出现的人物的信息
public class TalkRoleData
{
public List<TalkRoleDataEntity> datas = new List<TalkRoleDataEntity>();
}
public class TalkRoleDataEntity
{
public int Id; //id
public string icon;//人物图标
public string name;//人物名称
//可继续添加信息,取决于需求
}
//存放对话
public class TalkData {
public List<TalkDataEntity> datas = new List<TalkDataEntity>();
}
//说话的内容
public class TalkDataEntity
{
/// <summary> 对话id,</summary>
public int talkId = 0;
/// <summary> 0:对话时位于左边,1:右边</summary>
public int talkSide = 0;
/// <summary> 对话内容 </summary>
public string talkText = "";
/// <summary> 对话人物的ID <span style="font-family: Arial, Helvetica, sans-serif;">和对话人联系起来</span> </summary>
public int talkRoleid = 0;
/// <summary> 对话时的效果 </summary>
public string talkeffect="";
//后续可继续扩展
}
下面是对话脚本,常规的流程是: 面板上,文字渐渐的出现,当点击时,全部出现,(面板上出现继续点击的提示),再次点击后,进行接下来的对话,(会有跳过对话的功能)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using JsonDotNet;
public class UIPanelTalk : MonoBehaviour {
public UISprite roleIcon0, roleIcon1;
public UILabel text,name0,name1;
public int talkId = 0;
public int talkIndex = 0;
public List<int> talkSide;
public List<string> talkText;
public List<TalkRoleDataEntity> talkRole;
public List<string> talkIcon;
public List<string> talkName;
public List<string> talkEffe;
public float textProc = 0;
string texttotal;
public float textspeed = 0.5f;
int tempProc;//上一次字到达的位置
// Use this for initialization
void Start () {
if (talkId > -1) ReseTalkData();
ChangeTalk(0);
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonUp(0))//点击的时候有两种效果,一种是话没说完加速,一种是话说完了,说下一句
{
if (text.text.Length < texttotal.Length)//没有说完
{
textProc += 9999;
}
else
{
if (talkIndex >= talkText.Count - 1)//对话结束
{
Hide();//对话消失
return;
}
else ChangeTalk(talkIndex + 1);//继续下一句对话
}
}
showOneChar();
}
//逐渐显示文字
void showOneChar()
{
if (text.text.Length < texttotal.Length)//没有显示完
{
textProc += textspeed;
int nowProc = (int)Mathf.Min(textProc, texttotal.Length - 1);
while (nowProc >= tempProc)
{
if (tempProc >= texttotal.Length) break;
string tempc = texttotal.Substring(tempProc, 1);
switch (tempc)
{
//对于NGUI设置文字颜色字符的处理 [ff0000][-]
case "[":
int lenc = texttotal.IndexOf("]", tempProc + 1);
text.text += texttotal.Substring(tempProc, lenc - tempProc);
nowProc += (lenc - tempProc);
textProc += (lenc - tempProc);
tempProc += (lenc - tempProc);
showOneChar();
break;
//对于转义符\n 等的处理
case @"\":
if (texttotal.Substring(tempProc, 2) == @"\n") text.text += "\n";
nowProc += 2;
textProc += 2;
tempProc += 2;
showOneChar();
break;
default:
text.text += texttotal.Substring(tempProc, 1);
tempProc += 1;
break;
}
}
}
}
//初始化对话
void ReseTalkData()
{
talkSide = new List<int>();
talkText = new List<string>();
talkRole = new List< TalkRoleDataEntity>();
talkIcon = new List<string>();
talkName = new List<string>();
talkEffe = new List<string>();
//读取这次对话的内容
TalkData TalkData = JsonConvert.DeserializeObject< TalkData>( Resources.GetText("TalkData.txt"));
TalkRoleData roledata = JsonConvert.DeserializeObject< TalkRoleData>( Resources.GetText("TalkRoleData.txt"));
for (int i = 0;i< TalkData.datas.Count;i++){
if ( TalkData.datas[i].talkId == talkId){
talkSide.Add ( TalkData.datas[i].talkSide);
talkText.Add ( TalkData.datas[i].talkText);
talkRole.Add (GetTalkRoleById( TalkData.datas[i].talkRoleid, roledata));
if (talkRole[i]!=null) talkIcon.Add (talkRole[i].icon);
if (talkRole[i]!=null)talkName.Add (talkRole[i].name);
talkEffe.Add ( TalkData.datas[i].talkeffect);
}
}
}
TalkRoleDataEntity GetTalkRoleById(int id, TalkRoleData data)
{
for (int i = 0; i < data.datas.Count; i++)
{
if (data.datas[i].Id == id) return data.datas[i];
}
return null;
}
//改变对话
void ChangeTalk(int talkindex)
{
talkIndex = talkindex;
if (talkindex < talkSide.Count)
{
if (talkSide[talkindex] == 0)
{
roleIcon0.gameObject.SetActive(true);
name0.gameObject.SetActive(true);
roleIcon1.gameObject.SetActive(false);
name1.gameObject.SetActive(false);
}
else
{
roleIcon0.gameObject.SetActive(false);
name0.gameObject.SetActive(false);
roleIcon1.gameObject.SetActive(true);
name1.gameObject.SetActive(true);
}
}
if (talkindex < talkIcon.Count)
{
roleIcon0.spriteName = talkIcon[talkindex];
roleIcon1.spriteName = talkIcon[talkindex];
name0.text = talkName[talkindex];
name1.text = talkName[talkindex];
}
if (talkindex < talkText.Count)
{
texttotal = talkText[talkindex];
textProc = tempProc = 0;
text.text = "";
}
}
void Hide()
{
GetComponent<Animator>().Play("hide", 0, 0);
if (WorldMgr.instance != null) WorldMgr.instance.timeScale = 1;
this.enabled = false;
Destroy(gameObject, 1f);
}
}
总结
基于NGUI的简单的对话系统