[资源管理器]之前资源加载的纠错

前言

这篇文章是为了之前在做资源依赖的时候关于Asset->Assetbundle依赖加载之中错误的一个纠正

正文

在之前的文章我说了一种依赖加载的方案,就是记录用Asset资源对于它所依赖的assetbundle的依赖关系,然后通过这种的依赖关系来进行资源加载,这种方案的好处就是,当我Asset不在依赖Assetbundle的时候就可以卸载这个Assetbundle的,而不需要因为我Asset所在的assetbundle没有卸载就不去卸载依赖的Assetbundle。但是今天在和大佬在聊天的时候,他和我说了一种情况,我们选确定一个依赖关系AB1依赖AB2,然后我们先加载AB2在加载AB1然后卸载AB2再加载AB2然后去实例化AB1中的资源。是不是看起来很绕,其实很简单,就是去确定一点,在Unity中的AB包之间的依赖关系,会不会因为多次加载他们的唯一标识会修改,导致AB1中所记录到的AB2的标识没有更新,导致找不到AB2。通过测试,我发现如果第一次走这样的情况,其实AB1的资源是不会丢失的。loadAB1->instanceAB1(丢失资源)->loadAB2(资源被自动赋值上去,正常现实)。但是第二次加载了就会出现问题loadAB1->instanceAB1(丢失资源)->loadAB2(自动赋值)->DestroyAB1->unloadAB2->loadAB2->instaceAB1(丢失资源)。在这种情况下资源就不会赋值上去了。

结束

因为我在之前的测试不研究,也因为对AB的加载过程没有那么熟悉,导致得到了一个错误的结论。现在特出一篇文章作为纠错。之后我会很严谨的测试不同的情况。

[技巧]表情输入的特殊处理

前言

在和前同事聊天的时候,他因为在接入翻译,所以问了我一个问题,关于在聊天中加入了表情的翻译处理。这个问题的点在哪里呢?是因为我们一般做聊天表情包的时候,绝大多数的处理都是加入一个特殊字符表示表情的起始关键字符,然后通过一个特殊的规则来匹配表情。但是在翻译的时候,很有可能会把这个表情给翻译成一个单词。通过他的讲解,我发现了其实通过一个小处理就能完美的解决掉它。

正文

转义字符

在接触字符的时候,我们肯定知道字符里有个特殊的字符,它叫转义字符。在ASCII码都可以用“\”加数字来标识的,那这个特殊字符就是“\”。它的含义就是用它来做一个关键字,然后它和后接的数字来表示一个特殊的含义。通过“\”这个字符把它后接的字符的含义给改变了。我们就可以通过定义一个特殊的字符来表示我们的表情。可能会有人问了,这个不就是一个简单的关键字标识嘛,有啥好讲的。

特定环境出现的问题

那后面我就讲一个特殊的环境。如果我们定义\1代表的是一个笑脸。我们在输入的时候,肯定是玩家选择了一个笑脸然后在发给服务器的时候,我们把笑脸替换成\1来发送的,这个是一个简单的表情发送,但是如果玩家输入了一个\1怎么办呢?是不是我们还把它翻译成笑脸呢?微信里就是这样处理的,你发送一个特殊格式的字符它就给你转换成特定的表情了。那如果我们在游戏里表情是到达一个等级或者一个条件开放的。那玩家是不是就这样卡了一个bug。那我们就思考下怎么处理吧。

一种简单的处理

其实处理起来很简单的。我们在玩家输入的"\"之前在加入一个"\"。那玩家在输入的时候就变成了“\1”那我们在做处理的时候,通过"\"后接"\"就翻译成反斜杠的特殊含义,我们就把这个当一个正常的"\"输出,最后在另外一端看到的玩家输出就是"\1"了。这样的处理就正常表示了玩家的输入。

测试代码

static void zhuanyi(string str,List<string> strs)
        {
            if (string.IsNullOrEmpty(str))
            {
                return;
            }
            int index = str.IndexOf('a');
            if (index < 0)
            {
                strs.Add(str);
                return;
            }
            strs.Add(str.Substring(0,index+2));
            zhuanyi(str.Substring(index+2), strs);

        }
        static string zhuanyi1(List<string> strs)
        {
            string str = "";
            for(int i = 0; i < strs.Count; i++)
            {
                int index = strs[i].IndexOf('a');
                if (index > 0)
                {
                    str += strs[i].Substring(0, index);
                    string temp = strs[i].Substring(index + 1);
                    if(temp == "1")
                    {
                        str += "哈哈";
                    }
                    else
                    {
                        str += temp;
                    }
                }
                else
                {
                    string temp = strs[i].Substring(index + 1);
                    if (temp == "1")
                    {
                        str += "哈哈";
                    }
                    else
                    {
                        str += temp;
                    }
                }
            }
            return str;
        }

这就是一个简单的实现,没有优化过

结束

其实这个的处理是一个很简单的转义字符的特殊应用,我们可以在聊天呀,邮件呀,或者一些需要在文字里插入一些特殊含义内容的字符串里的应用。很多时候我们一些知道的知识点在应用的时候想不到。其实很大的一部分是我们只是把概念当成了概念,而没有转换成我们的智慧。

【基础】VO算法

前言

最近遇到了怪物在ai寻路的目标点为同一个的时候,会出现相互挤压的情况。所以开始研究群体避障算法。这片文章主要讲一下最基础的VO(Velocity Obstacle)算法。

正文

其实vo算法不是很难的,就是你得实时算它前面是不是会碰到物体,因为是简单的,所以单个物体只管自己的。我先晒一张经典的图

这张图在所以讲vo算法的文章里都会出现的,它直观的展示了vo是怎么算物品之间的碰撞。现在我就基于这个图来详细讲解下相关的知识点。

闵可夫斯基和

在这张图里我们会看到B里有一个实体圈,和一个虚线圈。然后你会发现生成的B⨁−A这个三角形实际上是从A的中心点PA为起点画的,所以可以理解那个虚拟的B圈实际上是把A圈给叠加上了。这里涉及到了一个集合知识点就是闵可夫斯基和(闵氏和)。
概念:两个图形A,B的闵氏和C={a+b|a∈A,b∈B}
其实就是从原点向着图形A内部的每一个点做向量,将图形B沿每个向量移动,最终位置的并集就是闵氏和。
我们来看一个图片吧

在这张图里a(A,B,C,D)b(A,C,E)。现在我们用它做一个闵氏和,先把b往DA向量方向移动,得到了一个(F,B,Q)这个图型,其他的向量也按这样的移动,我们最后就会得到一个并集成(F,G,I,M,L,J)这个图型。这个图形就是我们要算的a和b的闵氏和。
结合这个知识点,我们现在来看VO的那张图我们就很容易理解了,把B和A放在同一个圆心上,然后沿着圆的四周往外扩散A的半径向量。得到虚框B。

相对位移

当我们A沿着VA移动,B沿着VB移动的时候,我们要确定两个图形是否会碰撞到,因为我们是从a画的一个扇形,所以我们需要计算下A的相对于B的移动向量,这个就用向量相减就好了。算出一个VA-VB的向量,然后我们PA质点沿着VA-VB的方向画一个和B虚框相切的一个图形B⨁−A。因为实际计算不是求的相对速度,是VA的实际速度,所以我们需要加上VB。这样我们就得到了一个深色的三角形。

结论

当我们的速度不属于这个深色三角形内的时候,他们就不会发生碰撞。

补充

因为VO是把对象都当成一个独立的个体,所以它在计算的时候是实时计算的,当两个物体独立计算的时候,所以他们会单独计算自己的避障速度方向,当A,B沿着避障方向移动的时候,他们在下一次计算会发现自己不在对方的碰撞区域内,所以会修改方向沿着之前会碰撞的方向移动,再下一次计算的时候发现自己又在碰撞区域内了,又开始偏移移动,这样往复以后,就会出现抖动。后面我研究研究VO的优化算法,再讲解下怎么解决这个问题。