unity 网页游戏 本地

0

Unity 网页游戏通常指的是一种使用 Unity 引擎开发,然后通过 Web 服务发布,可以在网页浏览器上直接玩耍的游戏。在本地开发这样的游戏,你需要按照以下步骤进行:

1. **安装 Unity**: 首先,你需要在 Unity 的官网(https://unity.com)下载并安装 Unity Editor。

2. **创建项目**: 打开 Unity,创建一个新的项目。根据你的游戏类型(如 2D 或 3D),选择相应的模板。

3. **开发游戏**: 使用 Unity 的工具和组件进行游戏开发。Unity 支持 C# 语言,你可以编写游戏逻辑和用户界面。记得保存你的项目。

4. **构建 Web 版本**: 在 Unity 中,选择 "File" > "Build Settings",在 "Player" 标签页选择 "Web Player" 或 "WebGL",然后按照向导进行设置。这会生成一个包含所有依赖的 HTML、CSS 和 JavaScript 文件的项目。

5. **测试与调试**: 在本地浏览器中打开 "Build" 文件夹下的 HTML 文件,测试游戏是否正常运行,检查有没有错误。

6. **部署**: 当你满意游戏的本地测试结果后,你需要将 HTML、CSS 和 JavaScript 文件上传到服务器,或者使用 Unity 提供的 Build Player 工具生成一个可发布的.zip 文件,然后上传到网站。

注意,Unity 网页版游戏通常依赖 WebGL 技术,这意味着游戏可能需要在支持 WebGL 的浏览器上运行。你可能需要在发布前检查你的目标用户浏览器是否支持。

在传输方面,网络游戏采用的是基于TCP/P协议的网络传输。这种传输方式可以保证数据的稳定传输,并且可以将数据分包传输,提高数据传输的效率。

在网络游戏中,存储和传输数据非常重要。存储主要是指将数据保存在游戏服务器或本地电脑中,而传输则是指将数据从服务器传输到玩家的电脑中,在存储方面,网络游戏通常采用数据库进行数据的存储。由于数据库具有快速、安全、可靠的特点,因此是网络游戏最常用的数据存储方式。在数据库中,数据可以被高效地管理,修改和查询。

unity 网页游戏 本地

怎么下载黑鲨游戏盒子string fileName = Path.GetFileNameWithoutExtension(assetPath);

ResetGroup(createGroup.createGroupPaths[i].GroupName, createGroup.createGroupPaths[i].GroupPath,

AddressableCreateGroup createGroup = Resources.Load(path);

public List createGroupPaths = new List();

ScriptableObject是一个可独立于类实例来保存大量数据的数据容器。如果你想创建独立于GameObjects的对象,你可以从中派生一个类。

Resources类的函数成员 public static T Load(string path); 用于加载存储在资源文件夹中”path”路径处的指定类型的数据资源。

GetPlayerDataFromLevel(pl.level, ref maxExp, ref maxHp, ref maxMp);

PlayerPrefs是一个在游戏会话之间存储玩家偏好的类。它可以将字符串、浮点值和整数值存储到用户的平台注册表中。Unity将PlayerPrefs存储在本地注册表中,无需加密。请勿使用PlayerPrefs数据存储敏感数据。

游戏数据存储的方法很多,分本地和网络存储,本地存储有txt文件、json、PlayerPrefs、ScriptableObject和SQLite数据库读写等等;网络存储则是数据存储在服务器端,然后通过网络传输的方式进行存储。

Unity小游戏-平衡大师(安卓、PC、web)项目展示+完整项目源码

var path = Path.Combine(Application.persistentDataPath, saveFileName);

var path = Path.Combine(Application.persistentDataPath, saveFileName);

var path = Path.Combine(Application.persistentDataPath, saveFileName);

public static void SaveByJson(string saveFileName, object data)

有种简易判断是否支持序列化的方法,就是将类型标记为 公有的[System.Serializable],观察编辑器中是否显示该字段并且没有报错,则该类型可支持序列化。

注意并非所有的数据都能通过JsonUtility转化为json数据,它必须是 MonoBehaviour、ScriptableObject 或应用了 Serializable 属性的普通类/结构。要包含的字段的类型必须受序列化器支持;不受支持的字段以及私有字段、静态字段和应用了 NonSerialized 属性的字段会被忽略。

这是比较常用的游戏存读档方式,通过JsonUtility将数据转化为json数据,然后将输入写入到本地文件中实现存档,当玩家加载游戏时读取本地文件数据实现读档。

四月底发布的Chrome 113已经支持WebGPU了,目前我们也是一边集成一边研究如何重构GFX Device的接口层,使它更接近于现代图形API,从而能够更多地发挥WebGPU的性能优势。

但是目前Unity多线程还不够稳定、不够完善,切换场景的时候可能Crash,目前也不支持RenderThread,因为web worker无法访问DOM。打开多线程以后,内存增加也比较厉害。另外WebGL多线程只能支持Native代码,不支持C#代码,也是我们要努力解决的问题。

Unity现在已经可以打开WebGL多线程,可以看到打开多线程以后,DeformSkinnedMeshJob从主线程转到了web worker上。

目前我们做了的工作有:将一部分c++模板参数改为函数参数,减少生成的代码量;用宏剔除 webgl项目用不到的模块和函数,例如:Sqlite,ComputeShader,Physx的部分功能。未来我们还会继续清理启动流程、主循环里面不必要的步骤,以及探索如何优化il2cpp代码生成。

通过分析,目前发现的问题有:案例2是一个消除类游戏,并未使用到什么Physx仿真,仅仅在UI上使用了Physx的射线检测,就引入了一个庞大的Physx库,所以是非常不合理的。Wasm中有很多模版展开的代码,拿空间换时间可能在某些平台上是比较不错的策略,但WebGL平台内存特别紧张,所以在WebGL上并不是一个好的策略。

我们分析两个案例。游戏指令数都是1200万左右,其中il2cpp占比约60%,其余是引擎C++代码,占比40%,然后我们按模块对其进行分类,发现其中较重的模块有 Physx, particle system, sqlite, mecanim等,如Physx占了 8%。

看一看引擎代码的轻量化。从前面的内存分析可以知道,30多M的wasm在加载后会占用300多M的内存,因此生成的wasm越小越好。之前Unity的方法主要是Managed Code Strip和Engine Code Strip,它们是通过静态分析依赖的方式做的strip,以函数作为颗粒度。我们在这里会更加深入地分析打包生成的wasm代码,看看除了这两个Strip,我们是不是还有更多的优化空间。

从下图中的Timeline Profile,可以看到MeshSkinning.Update时间开销从57ms降低到了29ms。

图中可以看到,除了Field之外的信息都可以进行延迟加载(Field信息在构建对象实例时就需要,它决定了对象实例的的内存布局)。延迟加载粒度可以精确到逐个方法的粒度。延迟加载也会带来一个比较小的开销,就是在访问某个元数据前需要做一次非空判断,目前我们还没有Profile出它引入的性能回退。

在一个案例中IL2CPP运行时内存占用从64M优化到了33M。也有优化DynamicVBO pool的复用机制,测试案例中从59M降低到了38M。后面提到的代码轻量化和资源裁减也会帮助减少运行时的内存占用。

为了减轻WebGL平台限制对小游戏开发的影响,我们在引擎侧也有很多优化和改进,包括优化内存占用、优化绘制的效率、进一步给引擎瘦身、加快小游戏的启动速度。

再来看GPU的对比,去除空白网页本身的GPU消耗以外,对一个游戏来说,WebGL和原生APP差距并不大,我们可以认为WebGL小游戏的GPU性能和原生APP差不多。

我们拿了一款真实的小游戏进行测试。Timeline Profile可以看出原生APP耗时3.5毫秒左右,小游戏耗时10毫秒,所以整体来看WebGL的CPU性能与原生App相比相差3倍左右,其中既有WebGL单线程的原因,也有wasm本身执行效率的问题,印证了之前Benchmark结果。

再来看一看CPU计算性能的对比。之前网上看别人的Benchmark研究,webassembly的执行效率约为原生app的三分之一左右。

我们看到WebGL相比原生APP也有一部分内存占用减少,比较显著的就是Native Heap中的IL2Cpp Runtime。通过延迟加载meta信息、使用Sparse HashTable等方式使内存从101MB降低到35.3MB。这里主要是针对WebGL平台进行优化,后面会详细介绍这些。Asset相关的部分也有降低,因为资源压缩格式进行了调整,来自引擎底层内存分配器的行为和策略在不同平台上也有不同。

还有一处值得注意的是Mono Heap和Emscripten malloc的空闲空间。WebGL上,Mono Heap由IL2Cpp分配管理,其他native内存(包括引擎Native Heap和其他第三方库如Lua分配的内存)由Emscripten的malloc分配管理(默认使用dlmalloc)。这两部分都是只增不减,而且相互独立,空闲空间无法共享,因此需要各自都注意控制峰值。

文件系统会多使用内存。浏览器的沙盒机制导致WebGL无法访问本地文件,为了浏览器安全,只能使用JavaScript + IndexedDB模拟一个文件系统。Wasm访问js层,js层再访问IndexedDB,这里js层会占用一定内存,不能像Native文件系统那样直接使用一小块内存访问大的文件。

接下来分析Unallocated的部分。Wasm heap的大小是从一个预设值开始,然后以一定步长逐步扩容,扩容的方式比较傻,需要复制整个ArrayBuffer。例如从400M扩容到500M,扩容的时候400M也在,500M也在,总共会有900M的峰值。我们建议开发者根据游戏实际内存峰值,刚开始设立一个比较大的预设值。但这样会带来另外一个问题,就是会在wasm heap的尾部留有一段尚未分配的部分,就是90M的地方。

除了Wasm文件本身之外,浏览器的内核在代码编译执行的时候也会产生更多的内存消耗,相关的缓存、JIT优化也会使用较多内存,总体大约是Wasm文件大小的10倍左右。

相比原生APP,WebGL进程内存占用多了450M左右,增大的部分在于加载和编译占到340M;Wasm heap有些Unallocated内存,多出来90M;File System多了60M。

我们这里使用一个案例分别打包原生APP和WebGL小游戏,对比内存、CPU、GPU的差异。我们使用的测试手机是iPhone12。

由于CPU侧性能比较弱,游戏复杂度提高、计算量增大的时候三国杀单机版游戏攻略技巧,手机很容易过热。也会对网络API有限制,因为只支持websocket,所以需要开发者进行适配。由于以上这些限制,导致能使用的插件也比较有限。iOS对于WebGL的支持也不尽如人意,我们经常要为iOS平台做特殊优化、写特别的workaround。

WebGL在iOS平台上内存十分受限,低档机不能超过1GB,高档机大概1.4GB左右,超过这一限制可能就会触发操作系统OOM迫使进程重启。WebGL运行效率比原生APP慢3倍左右,目前只支持单线程不支持多线程,所以WebGL小游戏CPU性能比原生低不少。图形API只支持WebGL1/WebGL2,所以有些高级特性和优化没有办法使用,包括Compute Shader。没有文件系统,所以需要更大的内存模拟文件系统。这也导致Unity cache机制受到很大影响,cache文件无法被同步访问。

宿主客户端启动一个小游戏的时候会根据刚才提到的json文件描述拿到游戏首包。前面提到的共享引擎包,宿主通常都会提前下载和解压。然后客户端把首包解压到小游戏对应的沙盒文件夹,通过很小的InstantGame Launcher启动Unity小游戏子进程就可以了。

右侧图是来自抖音平台的小游戏,叫做《古董就是玩儿》,我们曾经将其适配至WebGL平台,画质降低还是很明显的,所以这是Native Instant Game的优点。

简单介绍一下Native Instant Game方案:优点很明显,可以直接对标原生APP,性能一样,体验也是一样;支持多线程;支持Gles3、Vulkan;原生APP插件也都可以用。可以采用同步方式访问沙盒中的文件,访问效率比较高,占用内存也比较少;以独立的子进程运行在沙盒中,不会干扰宿主运行;稳定性和安全问题Native Instant Game也提供完整的方案。因此对移动游戏开发者来说适配Native Instant Game成本很低,只要进行流式加载,不需要额外的适配和优化。

这是webgl平台的一个特殊之处,它没有真正的文件系统,只有一个内存中的文件系统。首包里的资源会持续占用内存,AB在未unload前也会一直占用内存。这跟原生APP不一样,在原生APP中,每次读取文件中的一块,只要通过复用一小块内存就可以访问一个大文件。

另一处很重要的收益来自于内存,内存占用减少了75MB。内存对于iOS平台是很珍贵的。减小的原因在于被剥离的重度资源有更加合理的生命周期。未开启AutoStreaming时,这些纹理在加载后依然占用内存(首包内存orAB内存)。

这里我们以一款线上的小游戏为案例,看一看AutoStreaming的效果:首包中的数据减少了很多,从42M降低为6.8M,因此大大减少了启动耗时(40秒降低为7.88秒)。用户打的AssetBundle也减小了一些,因为我们只选择了一部分贴图做AutoStreaming,所以瘦身程度不是很大。

专题: 三国单机版游戏   三国时单机游戏   三国智单机游戏