用Unity做个游戏(三) - 游戏运行日志

本文首发自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上找到

转载于:https://juejin.im/post/58d13b9061ff4b006ca9d49f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值