这个是我第一篇关于u3d(unity3d)的学习心得,因为我发现最近开始老忘记事,估计是老了吧,所以还是好记忆不如烂笔头。作为一个酷毕的玛侬,也就只能这样了。
本文不是从起步写起的,以后有空的话,可能会写点之前基础学习心得,今天是心血来潮,那就只能从今天的事说起吧。
很多时候,我们的程序都需要一些灵活性(领导们的最爱),为此我们必须曝露一些变量到外部来给使用者来进行修改或者说是控制,随便吧,反正就是那个意思。喔,首先说明一下,我是在windows下编程的,所以说的都是针对windows的,其他平台的朋友也不要喷我,因为我还没习惯或者说深入了解其他的平台下的编程。言归正传,我们都知道在windows下有一种配置文件,格式是ini,这是一种易读的文件,所以我们就用他来保存我们的变量吧。当然你也可以使用xml,但是对我来说太复杂,因为我打开它来看,眼花缭乱。好的,ini文件,windows系统本身也是使用这种文件来配置某些东西,并且在windowsAPI中微软也为我们提供了操作他的函数,也就是GetPrivateProfileXXX之类的函数,他们被封装在kernel32.dll中,这个dll是个核心的dll,所以windows系统都有他的身影。好了,既然,什么都有了,那就让我们开始我们的编程之旅吧。
欲练神功,必先自宫。先建一个文件"TestIni.cs"然后把下面的代码直接拷贝到该文件内,保存。
using UnityEngine; //系统自动生成
using System.Collections; //系统自动生成
//首先为了导入dll,我们需要在文件的开始添加下面一行代码
using System.Runtime.InteropServices;
//为了使用ASCIIEncoding而添加下面一行代码
using System.Text;
public class TestIni : MonoBehaviour
{
#region 下面开始导入我们需的函数--该段直到#endregion
[DllImport("kernel32.dll")]
public extern static int GetPrivateProfileString (string segName, string keyName, string sDefault, byte[] buffer, int nSize, string fileName);
[DllImport("kernel32.dll")]
public extern static int GetPrivateProfileSection (string segName, byte[] buffer, int nSize, string fileName);
[DllImport("kernel32.dll")]
public extern static int WritePrivateProfileSection (string segName, string sValue, string fileName);
[DllImport("kernel32.dll")]
public extern static int WritePrivateProfileString (string segName, string keyName, string sValue, string fileName);
[DllImport("kernel32.dll")]
public extern static int GetPrivateProfileSectionNames(byte[] buffer, int iLen, string fileName);
#endregion
//为了保存文件全路径添加一个变量,其实不应该起这个名字的,这个是历史遗留问题,因为这个文件我改了好多次了,但是变量名一直没变
string sPath;
//为了能遍历完所有的键我引用了网上的代码,也就是下面的两个函数
/// 返回该配置文件中所有Section名称的集合
public ArrayList ReadSections ()
{
byte[] buffer = new byte[65535];
int rel = GetPrivateProfileSectionNames (buffer, buffer.GetUpperBound (0), sPath);
int iCnt, iPos;
ArrayList arrayList = new ArrayList ();
string tmp;
if (rel > 0)
{
iCnt = 0;
iPos = 0;
for (iCnt = 0; iCnt < rel; iCnt++)
{
if (buffer [iCnt] == 0x00)
{
tmp = ASCIIEncoding.Default.GetString (buffer, iPos, iCnt - iPos).Trim ();
iPos = iCnt + 1;
if (tmp != "")
arrayList.Add (tmp);
}
}
}
return arrayList;
}
// 获取节点的所有KEY值
public ArrayList ReadKeys (string sectionName)
{
byte[] buffer = new byte[5120];
int rel = GetPrivateProfileString (sectionName, null, "", buffer, buffer.GetUpperBound (0), sPath);
int iCnt, iPos;
ArrayList arrayList = new ArrayList ();
string tmp;
if (rel > 0)
{
iCnt = 0;
iPos = 0;
for (iCnt = 0; iCnt < rel; iCnt++)
{
if (buffer [iCnt] == 0x00)
{
tmp = ASCIIEncoding.Default.GetString (buffer, iPos, iCnt - iPos).Trim ();
iPos = iCnt + 1;
if (tmp != "")
arrayList.Add (tmp);
}
}
}
return arrayList;
}
// Use this for initialization
void Start ()
{
//在Assets文件内先建一个"a.ini"文件,若是其他的名字,那你就改下面的代码好了
//上面一句是操作不是代码的解释,下面的代码是保存文件的全路径
sPath = Application.dataPath + "/a.ini";
//获取所有的Section名称
ArrayList al = ReadSections();
//新建一个list准备保存Key
ArrayList alKeys = new ArrayList();
//尝试读取含有中文的Section
ReadKeys("sd的地方");
//下面是读取Key
for(int i=0 ; i < al.Count; i++)
{
alKeys.Add(ReadKeys(al[i] as string));
for(int r=0; r<((ArrayList)alKeys[i]).Count; r++)
Debug.Log(((ArrayList)alKeys[i])[r].ToString());
}
}
}
好了,代码写完了,那就测试吧。
若已自宫,未必成功!
很明显,我们要的效果没有达到,居然识别了不了中文。当然假如只是英文的话就没问题。