微信小游戏禁用eval问题

微信小游戏因为安全问题,禁用了eval与new Function等可以动态加载执行代码的接口。这导致本来只要执行一些简单的算术表达式都不行了。
所以,只能自己动手丰衣足食,徒手撸了一个支持四则运算和括号的算术表达式计算。
测试用例:
测试用例

源码放在这里,有需要自行下载,TypeScript的

(205) 774-7205

定义了一个值类型

struct A{}

并且重写了

==, !=, GetHashCode,Equals

当把这个类型对象作为Dictionary的key时,在查找的时候会调用bool Equals(bool obj)来比对。这时候就会发生装箱,拆箱而产生GC分配。

解决方案是:实现接口 public bool  IEquatable<A>:: Equals(A other)这样就没有装箱拆箱了,Dictionary也会调用这个。

9074213622

unity+lua开发多年,一直苦于没有好的IDE。lua代码写起来非常痛苦,弱类型,代码量一大,维护起来成本非常高。

有些简单的BUG如果打断点能很快就知道原因,但因为基本没有工具能支持unity的断点,一直只能通过打日志调试。非常浪费时间。尝试各种工具后,总结如下:

  1. luastudio 收费,能断点,智能提示一般。
  2. visual code +  luaide 收费,能断点(我没有成功),智能提示较好
  3. 这就是本文的主角了 IntelliJ IDEA + EmmyLua 插件 免费,智能提示非常好。

首先,安装IntelliJ IDEA : /www.jetbrains.com/idea/download/

安装这个开源免费版本就好了。

然后,安装完成后,启动,到这个界面,选择Conifgure -> Plugins

在弹出的Plugins管理界面中搜索 EmmyLua,点击 Search in repositories,然后会显示搜索结果,点击Install按钮,安装就好。

安装完成后,点击按钮,

重启IntelliJ IDEA

启动之后在欢迎界面 点击

/TODO:未完

Lua中使用and or 模拟三目运算的一个坑

Lua中没有三目运算。为了代码简洁,我们经常使用and,or来模拟达到三目运算的效果:

local ret = a and b or c;

大多数情况下,这是没有问题的, a为true时返回b值,否则返回c。

但是,当a==ture时,而b==false,则不会按我们想要的返回b了,这时候会返回c。

 

Unity编辑器中Animator动画的预览驱动

为了节省性能,我们模型在导入的时候都会选上: Optimize Game Objects ,只导出我们游戏中需要用到的一些节点。但这会导致一个问题,就是Unity自带的Animation编辑器无法再预览动画了。逐帧查看和编辑事件都非常不方便。应策划要求,写了一个动画预览工具,可以支持逐帧浏览及编辑事件。技术要点主要有Animator的驱动:

只要每帧调用Animator的方法

Animator:Play(int stateNameHash, int layer, float normalizedTime);

Animator:Update(float deltaTime);

就可以了,两个都需要调用,不然驱动不了,原因不明。

_anim.Play(Animator.StringToHash(_Clip.name), -1, animTime / _Clip.length);
_anim.Update(delta);

事件编辑

有空再写,有人急需的话,请留言。

3158240809

游戏中弹道路径计算一般有很多种情况,这里我们只介绍下述情况下的解决办法。其它情况应该也是类似的。
1. 炮口角度确定
2. 击中位置确定
3. 要求计算炮弹路径

为了方面计算,我们将三维世界的抛物线计算,简化成二维来考虑。且拆分成垂直方向和水平方向单独计算。
1. 已知重力加速度:g
2. 已知炮弹出射角度:θ
3. 已知三维世界中弹道起始坐标from, 终点坐标 to
4. 设炮弹出射速度 水平量为a, 垂直量为b
5. 设炮弹飞行时间为:t

那么根据抛物运动的相关知识我们可以得到以下等式:
1. 由起始和终点坐标我们可以得到垂直位移:h 水平位移:s
2. at = s
3. bt + 0.5 * (-g) * t * t = h
4. b / a = tan(θ)

由此,可以推导出水平速度a的计算公式:

用这个公式就可以得到对应的水平速度a,然后分别可以算出:

垂直速度:b=a * tan(θ)

运动时间:t = s / a

有了这些数据,就可以计算出完整的抛物线轨迹了。(注:当起始点到终点的连线斜率大于θ时,是无解的)

 

代码示例:

 

Android安装包安装失败问题排查

项目一上线,就会遇到一些玩家说安装不了,安装失败什么的。这个问题一直都很头疼,因为你接触不到设备,而且安卓系统又不会在安装界面上给出安装失败的原因,所以就没法直接确认问题。

经历了两个项目的上线测试,总结一下,基本都是以下几个问题导致的:

  1. 安装包的安装选项问题。在AndroidManifest.xml里有一个选项:android:installLocation=”auto”,这个值一定要填 auto,不要填 “internalOnly”和”preferExternal”。后两个值在很多手机上,特别是一些比较低端的手机,很容易导致安装不上,原因不明。
  2. 手机容量不足。很多用户容量可能就剩一点点了,就比安装包大不了多少,这也很容易失败。可以让用户清理一下手机,把容量留大点再安装试试。
  3. 安装包本身下载有问题。下载下来的包是坏的。让用户重新下载,或者比对一下 md5码确认下。
  4. 安装成功过,现在又安装不上了。让用户把老包删除后再尝试。若还不行一般是以下几个原因:

a.  系统问题,删除不干净。一般重启可以解决

b. 系统多用户导致。如果用户手机上启用了多用户,然后还在多个用户账号下运行过。那么当他在一个账号下删除应用时,会导致实际上没有删除。只是在当前这个账号下看不到了。这个时候需要到 设置-应用程序管理器 内找一下,看看是不是还在,还在的话就在这里再删除一下。这个问题在华为手机上遇到过。

AssetBundle循环引用(依赖)检测

如果AssetBundle打包使用的是自动分类,而不是手工设置的方式,几乎不可避免的是导致打出来的包会有循环引用。即使我们给美术制定了一系列的标准用来避免这种情况,但你懂的…
若AssetBundle有循环引用,在加载的时候会很麻烦。那么我们就需要在制作阶段能够自动检测到AssetBundle的循环引用。并且给出提示,方便人工把循环引用给断掉。

研究下AssetBundle的正常引用 关系和循环引用关系我们就能发现:

在一个正常的AssetBundle引用关系中:

  1. 1. 从任何一个AssetBundle出发,往下走,任何方向都是一条断头路
  2. 2. 从任何一个AssetBudnle出发,往上走,任何方向都是一条断头路

有这两条,就可以得到推论:

遍历所有AssetBundle,删除掉没有引用或没有被引用的节点,最终将一个不剩。而如果有剩下,那么这些剩下的AssetBundle一定是陷在循环中的,或者是与循环中的AssetBundle有关联的。

这里只是想把我的思考过程写一下。最终其实就是:模拟一次AssetBundle的加载,如果都能加载完,那就不存在循环引用

  1. 1. 删除没有引用的节点,就是模拟加载过程
  2. 2. 删除没有被引用的节点,只是为了减少不在循环中,但是被循环中的节点关联的节点的数量

将剩余的AssetBundle输出,就可以知道哪些是陷在环里了。