需求:

在游戏开发中,我们经常会遇到以下情况:

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优化:分场景烘焙,综合场景加载相关推荐

  1. Cocos creator加载场景、加载场景回调、预加载场景

    注意场景名不要写错,是根据字符串去加载场景的. 同时这也在暗示我们,一个游戏应尽可能地少切换场景~ 官方文档:加载和切换场景 加载场景 加载场景调用如下API: cc.director.loadSce ...

  2. 优化Flash中的3D模型加载

    2019独角兽企业重金招聘Python工程师标准>>> 来自:Kid's Zone 最近在做一个公司的Flash3D页游项目,遇到了这个问题,前前后后断断续续也优化了一段时间,觉得还 ...

  3. vue路由懒加载_优化vue项目的首屏加载速度

    最近使用vue-cli3构建了一个小型的博客系统,完工之后,build打包出来发现一个chunk-vendors包就有1.1m,部署上去之后,访问的时候,首屏加载非常慢.居然需要21s,体验极差. 这 ...

  4. nginx加载图片慢_优化vue项目的首屏加载速度

    最近使用vue-cli3构建了一个小型的博客系统,完工之后,build打包出来发现一个chunk-vendors包就有1.1m,部署上去之后,访问的时候,首屏加载非常慢.居然需要21s,体验极差. 这 ...

  5. 又优化了一下 Android ListView 异步加载图片

    写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...

  6. unity 场景ab包_Unity加载AB包

    Unity制作游戏AB包 需要注意的是在游戏场景运行的情况下,不能编译AB包,不运行的情况下编译AB包需要使用Unity的扩展菜单功能,首先需要建立菜单用来编译AB包. 1.建立AB包的名字,首先选中 ...

  7. 在Unity3D的网络游戏中实现资源动态加载

    用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载.比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕.应该优先加载用户附近的场景资源,在游 ...

  8. 深度学习【使用pytorch实现基础模型、优化算法介绍、数据集的加载】

    文章目录 一 Pytorch完成基础模型 1. Pytorch完成模型常用API 1.1 `nn.Module` 1.2 优化器类 1.3 损失函数 1.4 线性回归完整代码 2. 在GPU上运行代码 ...

  9. 微信小程序优化:如何实现图片懒加载?

    前言 当我们在使用微信小程序浏览图片时,不可避免地会遇到加载缓慢的情况.这不仅会影响用户体验,还会耗费用户的流量.那么,有没有一种方法可以让图片在用户需要时再进行加载,从而提升用户体验和减少流量消耗呢 ...

  10. Web前端性能优化——如何有效提升静态文件的加载速度

    原文链接:https://wetest.qq.com/lab/view/345.html?from=content_qcloud WeTest 导读 此文总结了笔者在Web静态资源方面的一些优化经验. ...

最新文章

  1. AAAI 2020论文解读:商汤科技发布新视频语义分割和光流联合学习算法
  2. 移动web开发---第二天
  3. [转]100个常用的linux命令
  4. P2709 小B的询问
  5. ServiceStack.Redis——Redis于.net向上client解
  6. [luogu2664]树上游戏
  7. gitignore忽略文件夹_原创 | 详解gitignore的使用方法,让你尽情使用git add .
  8. 关于python语言和人工智能下哪个说法不正确_“在资源管理器”窗口中,文件夹图标左侧有“...
  9. C++学习之Dev-C++安装与调试
  10. DragControl
  11. 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)
  12. Blumind 思维图软件
  13. 中国(龙港)首届 “港为人先”全球创新创业大赛
  14. 2021-2024年中国两轮电动车企业经营情况对比
  15. Gitblit创建版本库并提交项目到版本库
  16. android图片压缩的两个开源库
  17. CBCT重建保姆级入门(三)
  18. 微信中无法下载APP的解决方案(微信自动跳转浏览器打开下载链接)
  19. 和自己对话--陶渊明《饮酒》
  20. oracle 12c r2下载地址,Oracle 12C R2安装尝鲜

热门文章

  1. 关于#1-D:last line of file ends without a newline警告的解决办法(stm32)
  2. 修改yum源带来的问题 curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).
  3. learning psychology
  4. 清华山维EPS二次开发基础篇
  5. 高性能、分布式、低延迟的发布订阅中间件对比 Redis 和 emitter
  6. 笔记本电脑使用的11个酷炫技巧
  7. 在mysql调用存储过程完成spilt切割
  8. es2015学习笔记经典入门教程
  9. Qt水波进度条Demo
  10. 迪士尼电影经过多年的