Unity3D优化:分场景烘焙,综合场景加载
需求:
在游戏开发中,我们经常会遇到以下情况:
1,烘焙场景太大,每次只需要烘焙部分;
2,资源热更,需要分步加载;
3,场景跳转太慢,需手动处理资源;
4,网页游戏不方便场景跳转。
诸如此类问题,就需要将资源分配到不同的小场景分别进行烘焙,最后统一到综合场景中进行合并加载。
解决思路:
这里主要参考了这两篇博客:Unity在一个场景中使用其他场景烘焙的物体,Unity Lightmap使用总结。
其中第一篇博客提供了解决思路,但年代久远;第二篇不太完整,所以取舍之后做出如下解决方案。
注意:在以下解决方案测试中,渲染环境基本保持一致;如果不一致需自己进行扩充。
解决方案:
第一步:烘焙场景
将父节点及之下需烘焙的子节点勾选静态模式,自行设置参数进行烘焙:
烘焙会出现场景同名文件夹,如下图所示:
烘焙场景可以拷贝,这样能保持烘焙信息一致;另外拷贝一份删除所有信息,作为主场景。
第二步:代码处理
1,主场景渲染管理器,这个主要是控制场景的光照贴图信息,所以要放到Awake中启动,并在需要的时候刷新:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class LightMapControl : MonoBehaviour
{[SerializeField]public List<Texture2D> _renderDatainfo = new List<Texture2D>();// Start is called before the first frame updatevoid Awake(){SetLightMapData();}void Update(){if (Input.GetKeyDown(KeyCode.A)){SetLightMapData();}}/// <summary>/// 对场景进行烘培灯光性息的赋值\n/// _renderDatainfo: LIST类型的贴图组/// </summary>public void SetLightMapData(){// //缔特// //整理灯光贴图// //创建临时贴图list,并复制导入数据进入LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional;List<Texture2D> Templightmaps = new List<Texture2D>(this._renderDatainfo.ToArray());// this._renderDatainfo.ForEach(i => Templightmaps.Add(i));// Templightmaps = this._renderDatainfo; //List<Texture2D> //遍历当前场景数据,如果临时list里有就删除list里的数据,并按当前id插入进去,得到最终贴图的顺序for (int i = 0; i < LightmapSettings.lightmaps.Length; i++){Texture2D nowTex = LightmapSettings.lightmaps[i].lightmapColor;int ia = Templightmaps.IndexOf(nowTex);if (ia != -1){Templightmaps.RemoveAt(ia);}Templightmaps.Insert(i, LightmapSettings.lightmaps[i].lightmapColor);}//把贴图赋值给当前场景List<LightmapData> aa = new List<LightmapData>();Templightmaps.ForEach(i => aa.Add(this.setNewLightmapdata(i)));LightmapSettings.lightmaps = aa.ToArray();}private LightmapData setNewLightmapdata(Texture2D a){LightmapData tt = new LightmapData();tt.lightmapColor = a;return tt;}
}
将该脚本拖到主场景中,并将各个分场景烘焙的贴图赋值到光照贴图数组中,运行结果如下:
2,记录保存和加载使用烘焙信息,这里需要将父节点设置为预制体:
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(LightmapRoot))]
public class LightmapRootEditor : Editor
{private LightmapRoot Root{get { return target as LightmapRoot; }}public override void OnInspectorGUI(){base.OnInspectorGUI();GUILayout.Space(10);if (GUILayout.Button("SaveLightmapData")){Root.GetAllLightmapData();SavePrefab();}GUILayout.Space(10);if (GUILayout.Button("SetLightmapData")){Root.SetAllLightmapData();}}private void SavePrefab(){var prefab = PrefabUtility.GetCorrespondingObjectFromSource(Root);Debug.Log("记录预制体信息");if (prefab != null){PrefabUtility.ReplacePrefab(Root.gameObject, prefab);Debug.Log(prefab);}}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class LightMapControl : MonoBehaviour
{[SerializeField]public List<Texture2D> _renderDatainfo = new List<Texture2D>();// Start is called before the first frame updatevoid Awake(){SetLightMapData();}void Update(){if (Input.GetKeyDown(KeyCode.A)){SetLightMapData();}}/// <summary>/// 对场景进行烘培灯光性息的赋值\n/// _renderDatainfo: LIST类型的贴图组/// </summary>public void SetLightMapData(){// //缔特// //整理灯光贴图// //创建临时贴图list,并复制导入数据进入LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional;List<Texture2D> Templightmaps = new List<Texture2D>(this._renderDatainfo.ToArray());// this._renderDatainfo.ForEach(i => Templightmaps.Add(i));// Templightmaps = this._renderDatainfo; //List<Texture2D> //遍历当前场景数据,如果临时list里有就删除list里的数据,并按当前id插入进去,得到最终贴图的顺序for (int i = 0; i < LightmapSettings.lightmaps.Length; i++){Texture2D nowTex = LightmapSettings.lightmaps[i].lightmapColor;int ia = Templightmaps.IndexOf(nowTex);if (ia != -1){Templightmaps.RemoveAt(ia);}Templightmaps.Insert(i, LightmapSettings.lightmaps[i].lightmapColor);}//把贴图赋值给当前场景List<LightmapData> aa = new List<LightmapData>();Templightmaps.ForEach(i => aa.Add(this.setNewLightmapdata(i)));LightmapSettings.lightmaps = aa.ToArray();}private LightmapData setNewLightmapdata(Texture2D a){LightmapData tt = new LightmapData();tt.lightmapColor = a;return tt;}
}
这里的具体原理可参考博客:Unity Lightmap使用总结
使用方法是将一个放到Editor文件夹中,另一个赋值给各个分场景的预制体父节点,以记录烘焙信息。使用结果如下:
这里的basic是记录光照贴图初始位置的,下标从0开始。
3,在主场景中测试
测试代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){for (var _i = 1; _i <= 3; _i++){GameObject _obj = Instantiate<GameObject>(Resources.Load<GameObject>("" + _i));} }// Update is called once per framevoid Update(){}
}
测试结果为:
测试工程连接为:https://download.csdn.net/download/Tel17610887670/14934894
四,后记
这种方法在流程化的情况下,操作起来比较简单,但还是有如下不足之处:
1,因为静态的缘故,会占用双份内存;
2,加载操作比较麻烦,需要分步处理;
在公司内部项目使用的时候,使用了更好的替代方案,大致思路是:合并网格之后,使用shader的顶点信息记录本身贴图与光照贴图。在此就不做公开。
Unity3D优化:分场景烘焙,综合场景加载相关推荐
- Cocos creator加载场景、加载场景回调、预加载场景
注意场景名不要写错,是根据字符串去加载场景的. 同时这也在暗示我们,一个游戏应尽可能地少切换场景~ 官方文档:加载和切换场景 加载场景 加载场景调用如下API: cc.director.loadSce ...
- 优化Flash中的3D模型加载
2019独角兽企业重金招聘Python工程师标准>>> 来自:Kid's Zone 最近在做一个公司的Flash3D页游项目,遇到了这个问题,前前后后断断续续也优化了一段时间,觉得还 ...
- vue路由懒加载_优化vue项目的首屏加载速度
最近使用vue-cli3构建了一个小型的博客系统,完工之后,build打包出来发现一个chunk-vendors包就有1.1m,部署上去之后,访问的时候,首屏加载非常慢.居然需要21s,体验极差. 这 ...
- nginx加载图片慢_优化vue项目的首屏加载速度
最近使用vue-cli3构建了一个小型的博客系统,完工之后,build打包出来发现一个chunk-vendors包就有1.1m,部署上去之后,访问的时候,首屏加载非常慢.居然需要21s,体验极差. 这 ...
- 又优化了一下 Android ListView 异步加载图片
写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...
- unity 场景ab包_Unity加载AB包
Unity制作游戏AB包 需要注意的是在游戏场景运行的情况下,不能编译AB包,不运行的情况下编译AB包需要使用Unity的扩展菜单功能,首先需要建立菜单用来编译AB包. 1.建立AB包的名字,首先选中 ...
- 在Unity3D的网络游戏中实现资源动态加载
用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载.比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕.应该优先加载用户附近的场景资源,在游 ...
- 深度学习【使用pytorch实现基础模型、优化算法介绍、数据集的加载】
文章目录 一 Pytorch完成基础模型 1. Pytorch完成模型常用API 1.1 `nn.Module` 1.2 优化器类 1.3 损失函数 1.4 线性回归完整代码 2. 在GPU上运行代码 ...
- 微信小程序优化:如何实现图片懒加载?
前言 当我们在使用微信小程序浏览图片时,不可避免地会遇到加载缓慢的情况.这不仅会影响用户体验,还会耗费用户的流量.那么,有没有一种方法可以让图片在用户需要时再进行加载,从而提升用户体验和减少流量消耗呢 ...
- Web前端性能优化——如何有效提升静态文件的加载速度
原文链接:https://wetest.qq.com/lab/view/345.html?from=content_qcloud WeTest 导读 此文总结了笔者在Web静态资源方面的一些优化经验. ...
最新文章
- AAAI 2020论文解读:商汤科技发布新视频语义分割和光流联合学习算法
- 移动web开发---第二天
- [转]100个常用的linux命令
- P2709 小B的询问
- ServiceStack.Redis——Redis于.net向上client解
- [luogu2664]树上游戏
- gitignore忽略文件夹_原创 | 详解gitignore的使用方法,让你尽情使用git add .
- 关于python语言和人工智能下哪个说法不正确_“在资源管理器”窗口中,文件夹图标左侧有“...
- C++学习之Dev-C++安装与调试
- DragControl
- 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)
- Blumind 思维图软件
- 中国(龙港)首届 “港为人先”全球创新创业大赛
- 2021-2024年中国两轮电动车企业经营情况对比
- Gitblit创建版本库并提交项目到版本库
- android图片压缩的两个开源库
- CBCT重建保姆级入门(三)
- 微信中无法下载APP的解决方案(微信自动跳转浏览器打开下载链接)
- 和自己对话--陶渊明《饮酒》
- oracle 12c r2下载地址,Oracle 12C R2安装尝鲜
热门文章
- 关于#1-D:last line of file ends without a newline警告的解决办法(stm32)
- 修改yum源带来的问题 curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).
- learning psychology
- 清华山维EPS二次开发基础篇
- 高性能、分布式、低延迟的发布订阅中间件对比 Redis 和 emitter
- 笔记本电脑使用的11个酷炫技巧
- 在mysql调用存储过程完成spilt切割
- es2015学习笔记经典入门教程
- Qt水波进度条Demo
- 迪士尼电影经过多年的