本文首发自inspoy的杂七杂八 | 菜鸡inspoy的学习记录
前言
本来是想接着写UI相关的东西的,不过上一篇提到了SFUtils
这个类,干脆就先介绍下有关于日志方面的封装
目的
这个游戏目前的目标平台是PC和Mac,移动平台有网络同步效果方面的顾虑,之后再考虑。
当然这不是主要问题,主要问题是Unity日志实在是太难用了,直接使用Debug.Log()
是最常用的方式,然而这样做只会把日志输出到UnityEditor的Console里,实在是有点难看,唯一的好处是双击某一行可以直接跳转到响应的代码行。不过作为外貌协会成员,还是想办法把这个尽量弄的优雅吧。
想法是统一把info,warning,error这些统一为一种日志,全部记录到文件里,这样的话我们翻之前的日志也比较方便,不会丢失。如果配合实时日志查看器的话(之前还开了个坑,不过最近估计没时间填了orz),就简直完美了~
设计
游戏中所有需要输出日志的地方全部使用SFUtils
提供的方法。
方法 | 说明 |
---|---|
log(string[, int]) | 输出日志,可选日志等级,数字越小越重要,默认为0 |
logWarning(string) | 记录一个警告,效果和Debug.LogWarning()相同 |
logError(string) | 记录一个错误,效果和Debug.LogError()相同 |
assert(bool[, string]) | 提供和Debug.Assert()相同的功能,提示信息也会写到文件里 |
logWarning()
相当于等级为-1的普通log,而logError()
相当于等级为-2的普通log。
之后log方法会根据日志级别输出到Console(和默认的一样),并格式化输出到文件
logStr = " [INFO-" + level.ToString() + "] - " + logStr;复制代码
接下来,关键的一步,把上面的logStr
追加到日志文件中
static void logToFile(string msg)
{
DateTime dt = DateTime.Now;
string output = dt.ToString("HH:mm:ss.ff ") + msg;
if (sm_logFileInfo != null && sm_logFileInfo.Exists)
{
var sw = sm_logFileInfo.AppendText();
sw.WriteLine(output);
sw.Close();
}
}复制代码
这样的话,我们每次输出日志都会写到同一个文件里了,所以我们要在每次游戏启动的时候新建一个日志文件,把每次运行区分开,以当前时间命名
static public void clearLogFile()
{
DateTime dt = DateTime.Now;
string path = Application.persistentDataPath + "/GameLog" + dt.ToString("yyyyMMddHHmmss") + ".txt";
sm_logFileInfo = new FileInfo(path);
var sw = sm_logFileInfo.CreateText();
sw.WriteLine("[BounceArena] - " + dt.ToString("G"));
sw.Close();
}复制代码
杂项
嗯,其实下面这些和日志没啥太大关系了,不过既然都在SFUtils
这个类里面,那就顺便都介绍一下吧
获取Unix时间戳
Unity/C#默认连获取当前Unix时间戳的接口都没有0.0只能丰衣足食自己实现一套了
static public long getTimeStampNow()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds);
}复制代码
查找某GameObject下的子物体
根据给出的父节点和子物体的名字,找到这个子物体。需要注意的是,这个方法会消耗相当多的时间,最好不要在update里调用。如果有多个同名的子物体,只会返回第一个找到的结果。
static public GameObject findChildWithParent(GameObject parent, string childName)
{
Transform parentTrans = parent.transform;
foreach (Transform trans in parentTrans.GetComponentInChildren<Transform>())
{
if (trans.name == childName)
{
return trans.gameObject;
}
else
{
var child = SFUtils.findChildWithParent(trans.gameObject, childName);
if (child != null)
{
return child;
}
}
}
return null;
}复制代码
完整代码
上面贴出的代码片段由于篇幅限制只保留了关键部分,完整的代码可在我的github上找到