脚本有部分参考于http://www.manew.com/thread-108184-1-1.html,
感兴趣的可以去这个看看。
效果图
运行后的效果
脚本部分:
我分成四部分介绍:
1.读入txt,并分章节存储
2.设置每一页的布局
3.翻页&翻章节
4.改变文字大小和类型
1.读入txt,并分章节存储
思路:读入整个txt文件,保存为string类型,在根据txt的文本分割符,将string分割成string[ ];
再遍历每个string[i];保存进已经设置好保存路径的第 i+1 章.txt中。
注意点:使用脚本读入txt的时候,为了防止中文乱码,最好加上 Encoding.GetEncoding(“gb2312”)。
读入为
StreamReader r = new StreamReader(fileAddress, Encoding.GetEncoding("gb2312"));
整个这一部分的代码为:
void CreatTxt(string BookName)
{
string BookUrl = Application.streamingAssetsPath + "/" + BookName;//弄一个文件夹,用来存放一千多个章节的txt
if (!Directory.Exists (BookUrl)) {//判断该路径是否存在,如果没有就创建路径,如果有就说明已经创建过啦
Directory.CreateDirectory(BookUrl);//创建路径
//判读需要拆解的txt是否存在,如果有就ReadToEnd,获取整本书txt全部的string
//string s = "";
var fileAddress = System.IO.Path.Combine(Application.streamingAssetsPath, BookName + ".txt");
FileInfo fInfo0 = new FileInfo(fileAddress);
if (fInfo0.Exists)
{
StreamReader r = new StreamReader(fileAddress, Encoding.GetEncoding("gb2312"));
book = r.ReadToEnd();
}
//这里是文本txt的分隔符,就是两个回车键
string[] SplitStr = { "\r\n\r\n" };
string[] ZhangJie = book.Split(SplitStr, System.StringSplitOptions.None);//把整个string拆解成一个个string最终变成数组
int num = 0;//用于记录章节数
foreach (string ZhangJieNeiRong in ZhangJie)
{
if (ZhangJieNeiRong.Length > 120)
{//实际过程中会出现空章节,用一个长度来过滤掉太短的章节,当然也不一定要是120,可以根据需要设置
num++;
string ZhangJieUrl = BookUrl + "/第" + num + "章.txt";//给每一章设置一个名字存储下来
if (!File.Exists(ZhangJieUrl))
{//把分别把每一章写进去创建成txt
FileStream fs1 = new FileStream(ZhangJieUrl, FileMode.Create, FileAccess.Write);//创建写入文件
StreamWriter sw = new StreamWriter(fs1);
sw.WriteLine(ZhangJieNeiRong);//开始写入值
sw.Close();
fs1.Close();
}
}
}
}
}
2.设置每一页的布局。
思路:在已给的背景中,我们背景的大小是已经设置好的,我们要根据已给的背景长宽和文字的大小,设置每一行,每一列可以显示多少个字。
Width = bg.GetComponent<RectTransform>().rect.width;
Height = bg.GetComponent<RectTransform>().rect.height;
Debug.Log(Width);
Debug.Log(Height);
text_size.text = Sfont.ToString(); //Sfont为设置了的字体大小
//获取每一行能显示多少字
HangZiShu = (int)(Width - (Math.Abs(text.rectTransform.offsetMax.x) + Math.Abs(text.rectTransform.offsetMin.x))) / Sfont;
//获取每一页能显示多少行
YeHangShu = (int)((Height - (Math.Abs(text.rectTransform.offsetMax.y) + Math.Abs(text.rectTransform.offsetMin.y))) / Sfont / 1.1f);
3.翻页&翻章。
这一部分是重头戏。
我们先从翻章开始讲起,上面说了,我们把每一章都存储为了一个txt。我们取出这一章的txt,根据‘
回车符,将这一章的内容的每一段存为一个string[];遍历每一段,计算一段分成多少行。遍历每一
行,存入TempYe[ i ](这个表示每一页所存的数据,若存入的行数大于等于已经计算好的每一页的容量,就i+1)。
string[] TempYe = new string[40];
int TempYeNum = 0;
int TempYeLine = 0;
void FanZhang()
{
ClearTempYe();//清空TempYe数组
var fileAddress = System.IO.Path.Combine(Application.streamingAssetsPath, bname + "/第" + (CurrentZhangJie + 1) + "章.txt");
FileInfo fInfo0 = new FileInfo(fileAddress);
///string s = "";
if (fInfo0.Exists)
{
StreamReader r = new StreamReader(fileAddress);
book = r.ReadToEnd();
}
string[] SplitStr = { "\n" };
string[] Line = book.Split(SplitStr, System.StringSplitOptions.None);
TempYeNum = 0;
TempYeLine = 0;
for (int i = 0; i < Line.Length; i++)
{
//获取这一段可以在显示端分为多少行
int lineih = (int)Math.Ceiling((double)Line[i].Length / HangZiShu);
for (int j = 0; j < lineih; j++)
{
//逐行赋值,该页一共能赋值HangZiShu行,HangZiShu满后赋值下一个TempYe
if (j < lineih - 1)
TempYe[TempYeNum] += Line[i].Substring(j * HangZiShu, HangZiShu);
else
TempYe[TempYeNum] += Line[i].Substring(j * HangZiShu);
TempYeLine++;
if (TempYeLine >= YeHangShu - 1)
{
TempYeNum++;
TempYeLine = 0;
}
}
if (TempYeLine != 0)
TempYe[TempYeNum] += "\r\n";
}
PlayerPrefs.SetInt("CurrentZhangJie", CurrentZhangJie);
}
翻页的话,我们分成了向左翻和向右翻,向右翻需要注意翻到一章的末尾的时候的情况,
向左翻需要注意翻到这一章首页的时候的情况和翻到第一章的第一页的情况:
void FanYe()
{
//翻页对text进行赋值,然后保存一下
text.text = TempYe[CurrentYeShu];
PlayerPrefs.SetInt("CurrentYeShu", CurrentYeShu);
}
public void Btn_right()
{
CurrentYeShu++;
if (TempYe[CurrentYeShu] == "")
{
CurrentZhangJie++;
FanZhang();
CurrentYeShu = 0;
}
FanYe();
}
public void Btn_left()
{
CurrentYeShu--;
if (CurrentYeShu < 0)
{
/ if (CurrentZhangJie == 0)
{
CurrentYeShu = 0;
return;
}
else
{
CurrentZhangJie--;
FanZhang();
CurrentYeShu = TempYeNum;
}
}
FanYe();
}
4.改变文字大小和类型
字体变大变小的原理是一样的,我们就只讲以下文字变大的方式;
我们想要文字变大,一定要重新计算一页的行数和列数,重新计算TempYe[ i ](这个表示每一页所存的数据)。
public void Add_size()
{
if (Sfont < 60)
{
Sfont++; //字体大小
//获取每一行能显示多少字
HangZiShu = (int)(Width - (Math.Abs(text.rectTransform.offsetMax.x) + Math.Abs(text.rectTransform.offsetMin.x))) / Sfont;
//获取每一页能显示多少行
YeHangShu = (int)((Height - (Math.Abs(text.rectTransform.offsetMax.y) + Math.Abs(text.rectTransform.offsetMin.y))) / Sfont / 1.1f);
text_size.text = Sfont.ToString();
FanZhang();
text.fontSize = Sfont;
// FanYe();
Debug.Log(TempYe[CurrentYeShu]);
text.text = TempYe[CurrentYeShu];
}
}
改变字体类型,这个整体思路比较简单,但是实现起来挺麻烦的。
我们可以注意到,每一个按钮,名字和他自己本身的字体类型是一一对应的。所有我们可以根据
按钮的文字类型,设置整个小说内容的字体类型。
难点在于批量管理按钮,获取按钮的text的字体类型对小说内容字体类型改变。
我们使用Button[ ],数组的方式批量管理。为按钮赋予点击事件
for (int i = 0; i < font_style.Length; i++)
{
font_style[i].onClick.AddListener(Font_style);
}
获取按钮的text的字体类型对小说内容字体类型改变
text_font = EventSystem.current.currentSelectedGameObject.GetComponent<Button>().transform.Find("Text").GetComponent<UnityEngine.UI.Text>();
text.font = text_font.font;
需要注意 text_font(类型为Text)最好设置为全局变量,不然会报错。
最后,完结撒花。