3D移动端游戏的优化方向-收集整理

2024-08-20 16:18

本文主要是介绍3D移动端游戏的优化方向-收集整理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

发现一篇给我写的几乎一样的,估计是听的同一个人的视频吧http://www.cnblogs.com/willbin/p/3389837.html

相关:http://blog.codeconch.com/archives/499

        http://blog.sina.com.cn/s/blog_471132920101dqsl.html 

http://blog.jobbole.com/84323/

http://blog.csdn.net/yesy10/article/details/7847926

http://blog.csdn.net/sgnyyy/article/details/41621039

http://www.cnblogs.com/hellohuan/p/3716357.html

http://gamerboom.com/archives/76214


一.资源相关优化。

二.引擎相关优化。

三.代码相关优化。

四.shader相关优化。


#############################################资源相关优化#############################################


一.可移动的物体

1.主角、NPC、怪物等

a.控制面片的数量:300-2000面片(三角面),如果只有两三个角色(例如,双人格斗游戏),可以适当提高面数。

b.控制Skinned Mesh Renderer数量:1个。

c.控制材质数量:1-3个,如果主角有换装要求另谈。

d.控制骨骼数量:小于30根,在pc端,可以到60根,甚至到100根。

2.其他动态物体(比如:飘的云彩什么的)

a.控制整体的的数据大小(比如雨滴,能用两个面片,就不要用多个)。

利用Dynamic Batching进行合并。

二.静态物体

1.一般静态物体(比如地表的一些装饰物体,像是箱子,铁桶等)

a.控制网格的顶点数:小于500个。

标记为“static”:Static Batching。

b.Animation组件:不要附加Animation组件,因为每次update或者fixedUpdate时都会有计算。

2.地形

a.控制地形的解析度:长宽均尽量小于257,当然你也可以很大,然后streaming,streaming之后,再动态加载。不建议一次性设置很大,因为性能损耗特别大。

b.混合纹理数量:不要超过4。当超过4 的时候,在pad这种真机上会出现一些混合错误,超过4之后计算量会非常大,mobile是扛不住的。如果已经这么做了,可以做纹理拼接,把小的纹理拼接成大的像是2048x2048这种,但是这样会吃掉内存,来换取帧频的提升。

三.纹理数据

1.纹理格式:

a.建议png或tga。IOS会在压包时自动转换为pvrtc格式,这样IOS设备可以硬件解,省时省电;而Android不会自动转换,因为Android的硬件众多,建议:手动改成ETC格式的,有90%的机器可以硬件解码这个格式。

2.纹理尺寸:

a.长宽小于1024,:同时应该尽可能的小,够用就好,2048的图片有些机器可能不能正确的读出来。

3.支持Mipmap:

a.建议生成Mipmap:虽然这种做法会增加包体的大小,但会提高一些渲染效率。2D游戏没有必要生成Mipmap了。

4.控制UV值的范围:

a.UV值的范围不要超过[0,1]。

四.音频数据

1.播放时间较长的音乐(如背景音乐)

a.建议使用.ogg或.mp3的压缩格式。

2.播放时间较短的音乐(如枪声)

a.使用.wav和.aif的未压缩音频格式。

###############################################################################################################



#############################################引擎相关优化#############################################

一.光源设置

1.控制“Important”光源个数

a.建议1个或者0个,一般为方向光。

b.个数越多,drawcall越多。

2.PixelLight数目

a.1-2个

二.相机设置

1.设置合理的远裁剪平面

a.默认为1000,建议根据各自不同的游戏场景进行修改。

2.设置分层的远裁剪平面

例如:

using UnityEngine;
using System.Collections;public class example : MonoBehaviour {void Start() {float[] distances = new float[32];distances[10] = 15;//设置层10的消隐为15米距离,其他所有层使用远剪裁屏幕距离camera.layerCullDistances = distances;}
}
function Start () {var distances = new float[32];// Set up layer 10 to cull at 15 meters distance.// All other layers use the far clip plane distance.//设置层10的消隐为15米距离,其他所有层使用远剪裁屏幕距离

a.根据物体的体积大小、渲染成本来进行分层。

三.粒子特效

1.荧屏上的最大粒子数目

a.建议小于200个粒子

2.每个粒子发射器的最大粒子数

a.建议不要超过50个。

3.粒子的大小

a.如果可以的话,粒子的size应该尽可能的小。

b.对于非常小的粒子,建议粒子的纹理去掉alpha通道。

4.尽量不要开启粒子的碰撞功能。

四.物理系统

1.碰撞体控制

a.如果可以的话,尽可能地使用SphereCollider、BoxCollider。

b.尽量避免使用MeshCollider等。

如果你想在Mobile上达到30fps的话,那么在每一帧上只有33ms的cpu时间。

五.动画系统

1.没有骨骼动画的模型要去除Animation组件

2.如果Animation不进行缩放,去除ScaleCurves(用脚本把它去掉,当然手动也可以,如果不嫌工作量的繁多)

a.减少33%的Blending时间

3.只有一个AnimationClip,使用老版本的Animation系统

4.如果使用Mecanim动画系统的话,要使用BodyMask来减少不必要的计算量

5.如果使用IK,建议使用GenericMode而不是HumanoidMode:不管角色有多少骨骼,在Mecanim系统里,HumanoidMode的Avatar系统会有一个特定数量的骨骼数目,假设有30根,而做的角色有60根的话,avatar就会自动缓存,计算IK的时候在30根中计算,然候在60根骨骼上自动映射,这样就多出一些计算,因为GenericMode是直接按照60根计算的。

6.主要Mecanim系统在Android上运行效率

a.数值运算非常高

b.在支持NEON的Android机上跑的才非常好

六.渲染设置

1.尽可能地避免AlphaTest和AlphaBlend

a.非常耗时,性价比很低

b.如果实在无法避免,请将进行Alpha Test或Alpha Blend的pixel数将至最低。

2.DrawCallBatching

a.Unity在进行时可以将一些物体进行合并,从而用一个DrawCall来渲染它们,我们将这一操作称之为“DrawCallBatching”

b.一般来说,Unity Batch的物体越多,你就会得到越好的渲染性能。

3.Static Batching

a.针对静态的物体进行Batch

b.对几何数据的大小没有限制

1).原理

a.静态VertexBuffer+动态IndexBuffer

b.在Build过程中,同种材质的物体被合并在一个大的VertexBuffer中

c.在Run-time时,通过视域体裁剪来动态改变IndexBuffer

2).注意

a.使用StaticBatching需要额外的内存来存储batch后的几何数据

4.DynamicBatching

a.相同材质的动态物体,Unity会自动对其进行batch

1).原理

a.动态VertexBuffer+动态IndexBuffer

2).注意

a.目前仅支持小于900顶点的网格物体

b.如果shader里使用Position,normal和UV三种属性的话,那么你只能batch 300顶点一下的物体,如果使用Position,normal,UV0,UV1和Tangent,那你 只能batch 180顶点一下的物体

c.进行缩放物体无法与非缩放的物体进行batch

5.纹理拼合(Texture Packing):程序进行开发拼合工具

a.通过检测材质,将材质按照shader的种类来分类

b.将同种shader的不同纹理进行拼合,拼成一张或若干张大的纹理,同时生成新的拼合材质

c.根据拼合结果,修改相关Object的UV值

d.更新相关Object的材质

6.遮挡剔除(Occlusion Culling)

a.区分Occluder(遮挡者)和Occludee(被遮挡者):半透明委托一般不设定额外Occluder

b.选择合适的遮挡技术

1).PVS Only:动态物体仅通过视域体进行裁剪,适合动态物体很少的情况

2).PVS and dynamic objects:动态物体通过portal culling进行裁剪

3).Automatic Portal Generation:动态物体通过portal culling进行裁剪,同时场景支持动态portal

###############################################################################################################


#############################################代码相关优化#############################################

一.使用静态类型(JS)

二.使用#pragma strict

1.禁用JavaScript的动态类型


未完。。。。。。。


转载一些:如下

Unity3D优化
⼀、渲染优化
设置所需的帧率
Unity iOS 允许您更改您的应用程序执行渲染循环的频率,而它的默认设置为每秒 30帧。
您可以降低此帧率来节省电池的电量,但当然这种节约在每帧中也会给您来⼀定的更新代
价。相反,您也可以增加渲染帧率,从而使画面渲染优先于触摸输入和加速度计处理等其
他活动。您需要对帧速率进行反复试验,从而确定它是如何来影响您的游戏体验。
如果您的应用程序涉及到大量计算和复杂的渲染,并且只能达到15/秒,那么即便您将
所需帧率设置为高于15帧,那也于事无补。您只有将应用程序进行足够的优化,才能允
许获得更高的帧率。
为了设置需要帧率,打开Unity生成的XCode工程,并打开AppController.mm文件。下面
⼀行
#define kFPS 30
决定了当前的帧率,所以你可以通过更改该值来得到所需的帧率。比如,如果你改变这个
#define为:
#define kFPS 60
那么应用程序将试图将渲染帧率变为60FPS,而不是30FPS
渲染循环
在使用 iOS 3.1 或更高版本时, Unity将安排渲染循环使用 CADisplayLink类。版本 3.1
前的版本需要使用几种fallback方法来处理循环。但是, 3.1及更高版本的 iOS可以通过
以下方法来激活fallback方法。
二、性能脚本优化
1. 减少固定增量时间
将固定增量时间值设定在0.04-0.067区间(即,每秒15-25帧)。您可以通过Edit-
>Project Settings->Time来改变这个值。这样做降低了FixedUpdate函数被调用的频率以
及物理引擎执行碰撞检测与刚体更新的频率。如果您使用了较低的固定增量时间,并且在
主角身上使用了刚体部件,那么您可以启用插值办法来平滑刚体组件。
2. 减少GetComponent的调用
使用 GetComponent或内置组件访问器会产生明显的开销。您可以通过⼀次获取组件的
引用来避免开销,并将该引用分配给⼀个变量(有时称为"缓存"的引用)。例如,如果您
使用如下的代码:
function Update ()
{
transform.Translate(0, 1, 0);
}
通过下面的更改您将获得更好的性能:
var myTransform : Transform;
function Awake ()
{
myTransform = transform;
}
function Update ()
{
myTransform.Translate(0, 1, 0);
}
3. 避免分配内存
您应该避免分配新对象,除非你真的需要,因为他们不再在使用时,会增加垃圾回收系统
的开销。您可以经常重复使用数组和其他对象,而不是分配新的数组或对象。这样做好处
则是尽量减少垃圾的回收工作。同时,在某些可能的情况下,您也可以使用结构
struct)来代替类( class)。这是因为,结构变量主要存放在栈区而非堆区。因为栈的
分配较快,并且不调用垃圾回收操作,所以当结构变量比较小时可以提升程序的运行性
能。但是当结构体较大时,虽然它仍可避免分配/回收的开销,而它由于"传值"操作也会导
致单独的开销,实际上它可能比等效对象类的效率还要低。
4. 最小化GUI
使用GUILayout 函数可以很方便地将GUI元素进行自动布局。然而,这种自动化自然也附
带着⼀定的处理开销。您可以通过手动的GUI功能布局来避免这种开销。此外,您也可以
设置⼀个脚本的useGUILayout变量为 false来完全禁用GUI布局:
function Awake () {
useGUILayout = false;
}
4. 使用iOS脚本调用优化功能
UnityEngine 命名空间中的函数的大多数是在 C/c + +中实现的。从Mono的脚本调用 C/C
++函数也存在着⼀定的性能开销。您可以使用iOS脚本调用优化功能(菜单: Edit-
>Project Settings->Player)让每帧节省1-4毫秒。此设置的选项有:
Slow and Safe – Mono内部默认的处理异常的调用

Fast and Exceptions Unsupported –⼀个快速执行的Mono内部调用。不过,它并不
支持异常,因此应谨慎使用。它对于不需要显式地处理异常(也不需要对异常进行处理)
的应用程序来说,是⼀个理想的候选项。
5. 优化垃圾回收
如上文所述,您应该尽量避免分配操作。但是,考虑到它们是不能完全杜绝的,所以我们
提供两种方法来让您尽量减少它们在游戏运行时的使用:
如果堆比较小,则进行快速而频繁的垃圾回收
这⼀策略比较适合运行时间较长的游戏,其中帧率是否平滑过渡是主要的考虑因素。像这
样的游戏通常会频繁地分配小块内存,但这些小块内存只是暂时地被使用。如果在iOS
统上使用该策略,那么⼀个典型的堆大小是大约 200 KB,这样在iPhone 3G设备上,垃
圾回收操作将耗时大约 5毫秒。如果堆大小增加到1 MB时,该回收操作将耗时大约
7ms。因此,在普通帧的间隔期进行垃圾回收有时候是⼀个不错的选择。通常,这种做法
会让回收操作执行的更加频繁(有些回收操作并不是严格必须进行的),但它们可以快速
处理并且对游戏的影响很小:
if (Time.frameCount % 30 == 0)
{
System.GC.Collect();
}
但是,您应该小心地使用这种技术,并且通过检查Profiler来确保这种操作确实可以降低
您游戏的垃圾回收时间。
如果堆比较大,则进行缓慢且不频繁的垃圾回收
这⼀策略适合于那些内存分配 (和回收)相对不频繁,并且可以在游戏停顿期间进行处理
的游戏。如果堆足够大,但还没有大到被系统关掉的话,这种方法是比较适用的。但是,
Mono运行时会尽可能地避免堆的自动扩大。因此,您需要通过在启动过程中预分配⼀些
空间来手动扩展堆( ie,你实例化⼀个纯粹影响内存管理器分配的"无用"对象):
function Start() {
var tmp = new System.Object[1024];
// make allocations in smaller blocks to avoid them to be treated in a special way,
which is designed for large blocks
for (var i : int = 0; i < 1024; i++)
tmp[i] = new byte[1024];
// release reference
tmp = null;
}
游戏中的暂停是用来对堆内存进行回收,而⼀个足够大的堆应该不会在游戏的暂停与暂停
之间被完全占满。所以,当这种游戏暂停发生时,您可以显式请求⼀次垃圾回收:
System.GC.Collect();
另外,您应该谨慎地使用这⼀策略并时刻关注Profiler的统计结果,而不是假定它已经达
到了您想要的效果。
三、优化Draw Call 批处理
在屏幕上渲染物体,引擎需要发出⼀个绘制调用来访问图形APIiOS系统中为OpenGL
ES)。每个绘制调用需要进行大量的工作来访问图形API,从而导致了CPU方面显著的
性能开销。
Unity在运行时可以将⼀些物体进行合并,从而用⼀个绘制调用来渲染他们。这⼀操作,
我们称之为批处理。⼀般来说, Unity批处理的物体越多,你就会得到越好的渲染性能。





这篇关于3D移动端游戏的优化方向-收集整理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090553

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k