首页 微博实时号养成文章正文

游戏脚本怎么制作(游戏脚本怎么制作赚钱)

微博实时号养成 2022年08月17日 05:21 122 admin

实现

下面是一个对比,一个使用了实例化,一个使用对象池。

当然,对于一个庞大复杂的游戏,你需要制作适用所有预制体的解决方案。

另一个例子:硬币派对!

Hundreds of rotating, dynamically lit, collectable coinsonscreen at once”的例子,在ing Methods部门将被用来演示脚本中代码,Unity组件像粒子系统,自定义着色器可以用来创建惊人的效果,而不消耗微弱的移动端硬件。

想象一下,这个效果在2D横向游戏中,大量的硬币下落,反弹,旋转。硬币通过点光源动态发光。我们想捕获硬币的光,使得游戏印象更深刻。

如果我们硬件很强大,我们可以使用标准的方法来解决这个问题。使每个硬币成一个对象,使用顶点照明,向前,或者延迟照明来遮住物体,然后添加光晕作为图像效果,以获得明亮地反射硬币,将光照射到周围区域。

但是很多对象会卡住移动端硬件,发光效果就是这个问题,那么我们该怎么办?

动态的精灵粒子系统

如果你需要显示很多沿着相似路径移动的物体,不用小心地监视,你可能无需使用粒子系统,渲染大量的物体。下面是这种技术应用的原型应用:

收藏品或硬币

飞行碎片

部落或简单敌人

欢呼人群

有一个免费的编辑器扩展器,是Sprite Packer,有助于创建动态精灵粒子系统。它将对象的框架渲染到一个贴图上,然后可以作为动态精灵图使用在离子系统中。对于我们的用例,我们可以在旋转的硬币上使用它。

参考实施

Sprite Packer项目中的工程是一个展示了这个具体问题解决方法的例子。

它使用不同类型的资产,用较低的计算预算,达到令人眼花缭乱的效果。

控制脚本

SpritePacker输出创建的特定的纹理

特定的着色器,紧密地连接控制脚本和材质。

例子中包含一个自述文件,尝试解释系统工作的原理,强调用来用来决定哪些功能需要的进程,它们是怎样实现的。折就是文件:

问题被定义为“Hundreds of rotating, dynamically lit,collectable coins onscreen at once”。

天真的方法是实例化一堆硬币预制体的复制,而不是使用粒子来渲染我们的硬币。但这会导致我们面对很多的挑战。

观察角度是一个问题,因为粒子没有它们。

游戏脚本怎么制作(游戏脚本怎么制作赚钱)

假设相机待位于正右方,硬币沿着Y轴旋转。

使用SpritePacker打包的动画纹理创建硬币旋转的幻觉。

这引入新的问题:所有的硬币都单调地沿着一样的方向以相同的速度旋转。

游戏脚本怎么制作(游戏脚本怎么制作赚钱)

我们跟踪旋转和生命周期,并用脚本“渲染”旋转到粒子生命周期来解决这个问题。

法线是一个问题,因为粒子没有法线,而我们需要实时光照。

在由Sprite Packer 生成的每帧动画上,为每个硬币生成单个法向量。

脚本中为每个粒子使用Blinn-Phonge光照,基于上面列表中法向量。

将上面的结果作为颜色应用于粒子。

着色器处理硬币的面和单个硬币的边缘。引入新的问题:着色器怎么知道边缘在哪儿以及边缘部分。

不能用UV吗,UV已经用于动画。

使用问题贴图。

需要硬币相对于Y轴的位置。

需要二进制“面”还是“边缘”。

我们不需要引入另一张贴图,读入越多的贴图,需要越多的纹理内存。

合并所需的信息到一个通道并用它替换纹理的颜色通道。

现在硬币是错误的颜色,我们该做什么!

使用着色器重建丢失的通道,组合这两个通道。

想要硬币闪烁发光。后期处理对于移动端设备消耗太高。

创建另一个例子系统,并给它一个发光的动画。

只有当硬币的颜色超亮时,才发出光晕。

不能保证每个硬币每帧都渲染光晕—填充率杀手。

每帧重置发光,只需要设置brightness>0。

物理是一个问题,收集硬币是一个问题—栗子也不会碰撞。

可以使用内置的粒子碰撞吗?

相反的,只需要在脚本中写碰撞。

最后,我们还有一个问题—这个脚本做了太多工作,它变得很慢!

随着激活硬币的数量变换,性能线性变换。

限制硬币的最大数量。这能做足以实现我们的目标:100个硬币,两个灯光,在移动端能很快运行。

更多深入优化的事:

不是单独计算光照,将它们分成块,在每帧单独地计算每块光照情况。

使用一个带有硬币位置和旋转的查找表格作为指标。

通过位置双线性插值增加真实度。

查找表上的稀疏更新,或者,全部静态的查找表。

使用灯光探测器?而不用在脚本中使用发现贴图粒子计算光照?

使用“Display Normals”着色器烘焙帧动画。

限制灯光数量。

解决脚本慢的问题。

这个粒子的最终目标或“故事的道德”是,如果有一些东西是你游戏真正需要的,而且当你尝试传统方法实现它,它很慢时,不意思这就不可能了,这只是意味着你需要用其他的方法来提高它的效率。

管理数千个对象的技术

这些是特定的脚本优化,适用于成百上千个动态物体的情况。在每个脚本上使用这个技术是可怕的想法;它们应该作为工具和设计指南来工作,运行时处理大量的物体或数据。

避免或最小化大数据集合上O(n2)操作。

在计算机科学中,O(n)表示评估操作所需的时间随着物体数量增加而增加的量。

例如,考虑一个基本的排序算法。我有n个,我需要将它们升序排列。

重要的是这里有两个循环一个内嵌循环。

假设算法最糟糕的情况:这些数字都是按相反的方向排好顺序的。这种情况,内置的循环将执行j次。平均j从1到数组长度减1,j将是数组长度除以2。就O(n)来说,数组长度就是这里的n,因此,在总体上,最里面的循环运行 nn/2次。 O(n),我们去掉所有的常量量1/2,因为我们讨论数量增加时,操作次数的增加,不是实际操作数量。因此算法是O(n2)。如果数量集合很大,操作的顺序很重要,因为操作数量可能会以指数方式增加。

O(n2)的一个粒子是100个敌人,每个敌人的AI控制敌人的移动。将地图划分成单元格可能会更快,在最近的单元格中记录每个敌人的移动,然后使每个敌人样本在最近的单元格中。这将是一个 O(n)操作。

缓存引用而不是执行不必要的查找

假设你在游戏中有100个敌人,而且他们都向玩家移动。

如果有很多同时运行,这就可能会很慢。很少人知道:MonoBehaviour中所有组件访问器,像transform,renderer,audio,相当于GetComponent(Transform),他们实际上有点慢。GamObject.FindWithTag已经优化了,但在某些情况下,例如,内置循环,或者很多实例化上运行的脚本上,也会有些慢。

这是一个更好的脚本。

最小化数学功能的花费

函数(Mathf.Sin,Mathf.Pow,等等),除法和平方根都占用相对于乘法100倍的时间。

最常见的情况时法线向量归一化。如果你一次又一次地归一化同一个向量,考虑归一化一次,缓存结果然后稍后使用。

如果你同时使用向量的长度和进行归一化,通过乘法获得向量的归一化会比使用.normalized属性更快。

如果你比较距离,你不必比较实际距离。你可以比较比较距离的平方,而不是.sqrMagnitude属性,保存平方根。

另一个,如果被一个常数C分割一次又一次,你可以使用倒数。先做1.0/c。

只是偶尔做昂贵的操作,如Physics.Raycast()

如果必须做一些昂贵的事,你可以通过尽量少用,缓存结果来优化。例如,考虑使用了Raycast的子弹脚本。

现在我们可以通过update替换FixUpdate,deltaTime替换fixedDeltaTime。FixedUpdate是指物理更新,会比Update调用的更频繁。但是,我们每隔n秒采用有射线查询。N越小,消耗越大,n越大,效率越高。目标越大,时间混淆发生前可能越大。(出现延迟时间,玩家击中目标,但爆炸延迟几秒,或者玩家击中目标,但是子弹正好穿过)

最小化内部循环中的堆栈开销

调用函数本身就有一点开销。如果你每帧都调用 x =Mathf.Abs(x)几千次,用x = (x > 0 ? x : -x)会好些。

优化物理性能

Unity 使用NVIDIA PhysX物理引擎,在移动端是可行的,但是硬件的性能限制比台式更容易达到。

下面是移动端调整物理以获得更好的性能的方法:

你可以调整固定时间设置(在Time manager中)减少物理更新的时间。增加时间步长,会减少CPU的开销。通常,精确度和速度是一个权衡。

设置允许的最大时间步,在8到10fps范围,在最坏情况下获取物理上的时间花费。

网格碰撞器开销高于原始碰撞器,所以尽量少用。通常可以子物体使用原始碰撞器来代替网格碰撞器。

虽然车轮碰撞器在固态物体的严格意义上不是碰撞器,但它们仍然具有较高的CPU开销。

完结~

原文地址:

https://docs.unity3d.com/Manual/MobileOptimizationPracticalingOptimizations.html

蛮牛社区(manew.com)分享最新的游戏研发和虚拟现实相关技术内容。

发表评论

陕ICP备2022006270号-1 网站地图 抖音真文案网