using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
using System;
/// <summary>
/// csv的读取抢答
/// </summary>
public class ReadCSV : MonoBehaviour
{
public static ReadCSV instance;
private static char _csvSeparator = ',';
private static bool _trimColumns = false;
public List<List<string>> lists;
public static string GetCSVFormat(string str)
{
string tempStr = str;
if (str.Contains(","))
{
if (str.Contains("\""))
{
tempStr = str.Replace("\"", "\"\"");
}
tempStr = "\"" + tempStr + "\"";
}
return tempStr;
}
//获取一行的写入格式
public static string GetCSVFormatLine(List<string> strList)
{
string tempStr = "";
for (int i = 0; i < strList.Count - 1; i++)
{
string str = strList[i];
tempStr = tempStr + GetCSVFormat(str) + ",";
}
tempStr = tempStr + GetCSVFormat(strList[strList.Count - 1]) + "\r\n";
return tempStr;
}
//解析一行
public static List<string> ParseLine(string line)
{
StringBuilder _columnBuilder = new StringBuilder();
List<string> Fields = new List<string>();
bool inColum = false;//是否是在一个列元素里
bool inQuotes = false;//是否需要转义
bool isNotEnd = false;//读取完毕未结束转义
_columnBuilder.Remove(0, _columnBuilder.Length);
//空行也是一个空元素,一个逗号是2个空元素
if (line == "")
{
Fields.Add("");
}
// Iterate through every character in the line 遍历行中的每个字符
for (int i = 0; i < line.Length; i++)
{
char character = line[i];
//If we are not currently inside a column 如果我们现在不在一列中
if (!inColum)
{
inColum = true;
if (character == '"')
{
inQuotes = true;
continue;
}
}
if (inQuotes)
{
if ((i + 1) == line.Length)
{
if (character == '"')//正常转义结束,且该行已经结束
{
inQuotes = false;
continue;
}
else//异常结束,转义未收尾
{
isNotEnd = true;
}
}
else if (character == '"' && line[i + 1] == _csvSeparator)//结束转义,且后面有可能还有数据
{
inQuotes = false;
inColum = false;
i++;//跳过下一个字符
}
else if (character == '"' && line[i + 1] == '"')//双引号转义
{
i++;//跳过下一个字符
}
else if (character == '"')//双引号单独出现(这种情况实际上已经是格式错误,为了兼容暂时不处理)
{
throw new System.Exception("格式错误,错误的双引号转义");
}
//其他情况直接跳出,后面正常添加
}
else if (character == _csvSeparator)
{
inColum = false;
}
// If we are no longer in the column clear the builder and add the columns to the list
//结束该元素时inColumn置为false,并且不处理当前字符,直接进行Add
if (!inColum)
{
Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
_columnBuilder.Remove(0, _columnBuilder.Length);
}
else//追加当前列
{
_columnBuilder.Append(character);
}
}
// If we are still inside a column add a new one (标准格式一行结尾不需要逗号结尾,而上面for是遇到逗号才添加的,为了兼容最后还要添加一次)
if (inColum)
{
if (isNotEnd)
{
_columnBuilder.Append("\r\n");
}
Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
}
else //如果inColumn为false,说明已经添加,因为最后一个字符为分隔符,所以后面要加上一个空元素
{
Fields.Add("");
}
return Fields;
}
//读取文件
public static List<List<string>> Read(string filePath, Encoding encoding)
{
List<List<string>> result = new List<List<string>>();
string content = File.ReadAllText(filePath, encoding);//读取csv所有的文本内容
string[] lines = content.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
//以换行回车拆分字符串,去除空格
//注:回车换行可能对某些csv不适用,这里如果我们出现读取不正常,可以改用 \n (换行)试试
for (int i = 0; i < lines.Length; i++)
{
List<string> line = ParseLine(lines[i]);
result.Add(line);
}
return result;
}
// Use this for initialization
void Start()
{
instance = this;
}
public void ReadTrainee()
{
lists = Read(Application.streamingAssetsPath + "/trainee.csv", Encoding.UTF8);//打包完地址
}
public void ReadBank()
{
lists = Read(Application.streamingAssetsPath + "/bank.csv", Encoding.UTF8);//打包完地址
}
}
这里以两个CSV为例,使用那个调用哪一个的方法,进行题库的加载。存在lists里边,然后对list进行遍历使用
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AnswerAnalysisImage : MonoBehaviour
{
public static AnswerAnalysisImage instance;
/// <summary>
/// 序号
/// </summary>
public Text orderNumber;
/// <summary>
/// 类型
/// </summary>
public Text type;
/// <summary>
/// 题目
/// </summary>
public Text title;
/// <summary>
/// 选项A,B,C,D
/// </summary>
public Text optionA,optionB,optionC,optionD;
public Button[] optionBtn;
/// <summary>
/// 题库总数
/// </summary>
public int sum;
/// <summary>
/// 确认选择按钮
/// </summary>
public Button confirm;
/// <summary>
/// 对题目进行加运算
/// </summary>
public int currCount = 1;
/// <summary>
/// 答题正确的答题数量
/// </summary>
public int rightCount = 0;
/// <summary>
/// 正确答案
/// </summary>
public string rightAns;
private void Awake()
{
instance = this;
}
void Start()
{
//确认按钮
confirm.onClick.AddListener(() =>
{
ResetGame();
currCount++;
if (currCount>=ReadCSV.instance.lists.Count)
{
Debug.Log("结束了面板");
if (rightCount>=6)
{
Debug.Log("通过成功");
}
else
{
Debug.Log("通过失败");
}
}
else
{
Analysis(ReadCSV.instance.lists, currCount);
}
});
}
/// <summary>
/// 判断选择的按钮
/// 进行判断对错
/// </summary>
public void OnOptionMethod( string name)
{
switch (name)
{
case "1":
Debug.Log("当前的题是选择题");
if (rightAns == "1")
{
rightCount++;
RightOption(optionA);
}
else
{
WrongOption(optionA);
RightOption(optionBtn[int.Parse(rightAns) -1].gameObject.GetComponent<Text>());
}
break;
case "2":
if (rightAns == "2")
{
rightCount++;
RightOption(optionB);
}
else
{
WrongOption(optionB);
RightOption(optionBtn[int.Parse(rightAns) - 1].gameObject.GetComponent<Text>());
}
break;
case "3":
if (rightAns == "3")
{
rightCount++;
RightOption(optionC);
}
else
{
WrongOption(optionC);
RightOption(optionBtn[int.Parse(rightAns) - 1].gameObject.GetComponent<Text>());
}
break;
case "4":
if (rightAns == "4")
{
rightCount++;
RightOption(optionD);
}
else
{
WrongOption(optionD);
RightOption(optionBtn[int.Parse(rightAns) - 1].gameObject.GetComponent<Text>());
}
break;
default:
break;
}
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
Analysis(ReadCSV.instance.lists,1);
}
}
/// <summary>
/// 传入csv说一句和取值
/// </summary>
/// <param name="list">csv行列数据</param>
/// <param name="count">取值行</param>
public void Analysis(List<List<string>> list,int count)
{
ClearText();
rightAns = list[count][9];
sum = ReadCSV.instance.lists.Count-1;
type.text = list[count][1];
orderNumber.text = count.ToString() + "/" + sum.ToString();
title.text = list[count][2];
if (type.text=="选择题")
{
optionA.text ="A."+ list[count][3];
optionB.text = "B." + list[count][4];
optionC.text = "C." + list[count][5];
optionD.text = "D." + list[count][6];
}
else
{
optionA.text = list[count][7];
optionB.text = list[count][8];
}
}
/// <summary>
/// 清理选项得答案
/// </summary>
public void ClearText()
{
optionA.text = "";
optionB.text = "" ;
optionC.text = "" ;
optionD.text = "" ;
}
/// <summary>
/// 正确的颜色
/// </summary>
public void RightOption(Text text)
{
text.color = new Color(0.9f, 0.5f, 0.3f, 1f);
}
/// <summary>
/// 错误的的颜色
/// </summary>
public void WrongOption(Text text)
{
text.color = new Color(0.5f, 0.7f, 0.5f, 1f);
}
/// <summary>
/// 恢复原来的颜色
/// </summary>
public void ResetColor(Text text)
{
text.color = new Color(0.38f, 0.13f, 0f, 1f);
}
public void ResetGame()
{
ResetColor(optionA);
ResetColor(optionB);
ResetColor(optionC);
ResetColor(optionD);
for (int i = 0; i <optionBtn.Length; i++)
{
optionBtn[i].interactable = true;
}
}
}
申明更新的文本,通过每一行进行更新。然后就完成了。写的不够简洁,有哪位大神看到可以指点一下,我在进行优化