循迹研究室
https://imzlp.com/icon.png
2024-03-11T02:42:36.384Z
https://imzlp.com/
查利鹏
Hexo
公告栏
https://imzlp.com/posts/1/
2024-03-11T02:42:36.384Z
2024-03-11T02:42:36.384Z
<p>欢迎访问循迹研究室,这是一个专注于游戏开发的技术站点。我在Github上的开源项目:<a href="https://github.com/hxhb">github.com/hxhb</a>及<a
循迹研究:记一次iPhone硬件维修
https://imzlp.com/posts/27221/
2024-03-01T14:45:08.000Z
2024-03-01T14:45:08.000Z
<p>元旦期间,我的iPhone12跌落导致了一些故障,勉强能用。但前段时间电池也鼓包很容易自动关机,已经彻底不能用了。换了备机之后,搁置了一段时间。</p>
<p>最近想起来,因为还能正常开机,且主要功能还能正常使用,所以推测应该还是部分故障,不是整体损坏。完全报废有些可惜,只能换不锈钢盆了。</p>
<p>自己动手拆机分析了下故障原因,并尝试购买配件修理解决,本篇文章记录拆机和解决过程。</p>
循迹旅行:澳门旅游攻略
https://imzlp.com/posts/35791/
2024-02-15T15:35:31.000Z
2024-02-15T15:35:31.000Z
<p>今年春节在深圳过年,计划大湾区旅行的下一站为澳门。而且从深圳去澳门也算比较方便,于是规划成行。做了一些攻略和行程安排,可以作为首次去澳门旅游的参考。</p>
UE中利用反射为资产建立属性缓存
https://imzlp.com/posts/71162/
2023-10-25T15:27:37.000Z
2023-10-25T15:27:37.000Z
<p>在前一篇文章<a href="https://imzlp.com/posts/19901/">UE中资源自修正的设计与实现方案</a>中,我介绍了利用ResScannerUE的资产检查进行过滤,然后自动化处理的实现方案。</p>
<p>在通常情况下,如果想要检查资源内的某个属性,就需要把资产加载进来,获取对象:<br><img src="https://img.imzlp.com/imgs/zlp/picgo/2023/10/24/105204.png"></p>
<p>但是,如果想要批量地检查资源的属性,用这种形式挨个加载资源的耗时很久,尤其是在没有DDC的情况下,加载资源就会触发DDC缓存的构建,这部分耗时很久,对于机器性能占比也较高。</p>
<p>而且随着资产规模的扩大,如果想要完整扫描一遍工程里的所有资源,耗时就会异常夸张。所以,我设想能否实现一种无需加载资源,但能够获取资源内属性的方法。</p>
<p>经过研究发现,通过一种取巧的方法做到这一点,利用了反射、资产序列化、以及AssetRegistry的特性组合起来。并且是非侵入式的,无需修改任何现有资源类型的代码。</p>
<p>本篇文章会介绍其实现原理,以及对引擎中相关逻辑的分析,并介绍该机制在工程中的实际应用。</p>
UE中资源自修正的设计与实现方案
https://imzlp.com/posts/19901/
2023-10-18T14:45:12.000Z
2023-10-18T14:45:12.000Z
<p>在先前的文章中,我曾介绍了在UE中利用ResScannerUE进行资源的<strong>多阶段</strong>与<strong>自动化</strong>检查的实现和执行效率优化。</p>
<ul>
<li><a href="https://imzlp.com/posts/22655">UE中多阶段的自动化资源检查方案</a></li>
<li><a href="https://imzlp.com/posts/20376/">基于ResScannerUE的资源检查自动化实践</a></li>
<li><a href="https://imzlp.com/posts/11750">UE资源合规检查工具ResScannerUE</a></li>
</ul>
<p>已经能够实现非常灵活地配置资源检查和及时提醒,具有非常强大的规则表达能力。但它们还都仅限于<strong>发现问题</strong>予以提醒的阶段,虽然有强制约束不能提交,但仍需人工地去处理。尤其是具有大量存量资源的情况下,手动处理的人力耗时非常大。<br><img src="https://img.imzlp.com/imgs/zlp/picgo/2023/202310181358828.png"></p>
<p>基于这种情况下,我设计了一种自动化修正资源的机制,能够在规范制定之后自动修复资源,确保被扫描出来资源的都被设置为正确的状态。<br><img src="https://img.imzlp.com/imgs/zlp/picgo/2023/202310131604358.png"></p>
<p>补齐了我这套资源检查方案中的最后一块拼图,并且可以应用在各个阶段的扫描过程,按需执行。本篇文章会介绍它的设计思路与实现机制,以及一些在项目中实际的应用场景。</p>
UE插件与工具开发:j2的设计思路与实现
https://imzlp.com/posts/86105/
2023-10-14T20:23:37.000Z
2023-10-14T20:23:37.000Z
<p>如果让我挑一个近期在工作当中使用UE感觉最无意义和折磨的事情,那一定是根据一大串字符串路径,在ContentBrowser里找到它。</p>
<p>由于无法快速地直接跳转到目录和资源,每次逐级点开一个深层目录都给我带来一种浪费人生的感觉。 </p>
<p>基于这种痛点,我写了一个小工具,可以极大地缓解这种手动焦虑。我把它命名为<code>j2</code>(jump to),是一个极简的ContentBrowser跳转工具,开源在github上:<a href="https://github.com/hxhb/JumpTo">hxhb/JumpTo</a>。</p>
<p>本片文章会介绍该项目的用法,以及构想解决方法的思考过程和逐步的代码实现。虽然功能本身是一个极简的插件,但对于实际痛点的发现、分析和解决过程值得记录。</p>
基于Obsidian构建知识管理体系
https://imzlp.com/posts/30911/
2023-09-07T16:19:40.000Z
2023-09-26T10:42:58.000Z
<p>在2020年,我曾写过一篇文章<a href="https://imzlp.com/posts/29551/">如何构建自己的知识体系?</a>,其中主要是对于日常技术积累的思考,偏向于方法论。</p>
<p>本篇文章会从工具和实际使用的角度出发,基于<a href="https://obsidian.md/">Obsidian</a>探索个人知识管理的可能性,并尝试将其与Hexo博客结合起来。当然,这种工具偏好和实践具有强主观性,本文完全从我个人的实践和经历出发,<strong>没有最好的工具,只有最适合自己的。</strong></p>
循迹旅行:香港旅游攻略
https://imzlp.com/posts/31438/
2023-08-21T09:37:37.000Z
2023-09-01T09:50:12.000Z
<p>深圳与香港仅一江之隔,虽早有打算去香港玩一圈,但因为前两三年因为疫情的原因迟迟未能成行。今年疫情放开之后,香港和内地之间通关也变得比较方便了,所以把去香港提上了日程。</p>
<p>周末和老婆一起去香港玩了一趟,去之前做了一些攻略和行程安排,可以作为首次去香港旅游的参考。</p>
UE构建提升:优化远程构建IOS的实现
https://imzlp.com/posts/50293/
2023-08-16T10:43:50.000Z
2023-09-05T20:11:12.000Z
<p>远程构建是UE中非常方便好用的一种打包IOS方式,能够只在Mac上编译代码,不COOK资源,能够极大地降低对于Mac硬件的需求。</p>
<p>而且,Mac的售价颇高,传统模式下,如果需要部署多个独立的IOS包构建流程,通常就需要采购多台独立的Mac机器分别部署,硬件成本较高。</p>
<p>况且,IOS的开发环境往往需要随着IOS系统迭代进行更新。每年WWDC发布新版本IOS,就会需要新版本的XCode支持,新版本XCode又依赖新版本的MacOS,套娃式的链式依赖。如果Mac的构建环境增多,那么更新这些机器的构建环境也会变为一个繁琐的重复任务。</p>
<p>远程构建IOS也能够比较好的解决这个问题,一台独立的Mac,可以同时给多个IOS构建流程提供支持,如果需要更新环境也只需要处理一台即可。而且编译代码的耗时相对固定,且能够进行增量编译,理论上来说只要不是所有的机器同时执行全量编译,那么对于Mac的性能压力就没有那么大。</p>
<p><img src="https://img.imzlp.com/imgs/zlp/picgo/2023/20230816154208.png"></p>
<p>博客中也有开启远程构建IOS的文章:<a href="https://imzlp.com/posts/1948/#%E8%BF%9C%E7%A8%8B%E6%9E%84%E5%BB%BAiOS">UE 开发笔记:Mac/iOS 篇</a>,可以参考基础配置启用。</p>
<p>但UE默认实现的IOS远程构建在实际使用中也存在不少的问题,无法实现从部署到构建全自动化流程,本篇文章会针对远程构建在实际的工程应用中痛点进行优化。</p>
循迹研究:利用AI助力生活及开发探索
https://imzlp.com/posts/71467/
2023-04-24T17:01:46.000Z
2023-04-24T17:01:46.000Z
<p><strong>工欲善其事,必先利其器!</strong>以ChatGPT和Stable Diffusion为代表的AIGC工具横空出世,AI浪潮席卷了各行各业。作为开发者,如何利用AI的能力,提升做事情的效率,是个值得研究的问题。</p>
<p>现阶段需要注意的是,GPT回复的内容非完全准确,存在胡诌的可能。但它的潜力在于有望实现了一种通用型的AI助手。没有人能在所有领域都具备专家级别的知识,在不熟悉的领域,充分利用GPT能够显著降低上手成本。</p>
<p>本篇文章我会介绍,利用GPT助力工作、生活和学习的一些案例,以及使用GPT API进行二次开发应用场景的探索。文后会分享一些我在使用的Prompts,并推荐一些我觉得不错的GPT工具,以及对Azure OpenAI服务使用Cloudflare Worker封装的方案。</p>
DevOps:虚幻引擎的CI/CD实践
https://imzlp.com/posts/96336/
2023-04-15T14:30:56.000Z
2023-04-15T14:30:56.000Z
<p>DevOps是一种思想,以自动化进行持续集成(CI)和持续部署(CD)为基础,优化开发、测试、运维等所有环节。强调软件开发测试运维的一体化,减少各个部门或流程之间的沟通成本从而实现快速高质量的发布和迭代。</p>
<p>虽然在游戏领域的开发情况和传统互联网有很大区别,但借用DevOps的概念把项目中所有的生产环节最大限度地接入自动化,能够大幅提升效率。</p>
<p>本篇文章会介绍,UE实现自动化的基础概念,及我在虚幻引擎自动化构建方面的一些尝试和实际的工程实践。</p>
循迹研究:在复杂的世界中寻找确定性
https://imzlp.com/posts/83875/
2023-04-08T14:10:39.000Z
2023-04-08T14:10:39.000Z
<p>最近总会产生一种莫名的焦虑感,经过一段时间的自我观察和思考,我认为需要直面这些问题并尝试给出回答。</p>
<p>本文是对当前生活状态和问题进行研究并剖析的思想实验,总结用于指导生活和工作的思想工具。作为个人方法论,其中包含大量的主观内容。</p>
资源管理:UASSET资源加密方案
https://imzlp.com/posts/32412/
2023-04-07T12:50:04.000Z
2023-04-07T12:50:04.000Z
<!-- ![](https://img.imzlp.com/imgs/zlp/picgo/2023/20230407125507.webp) -->
<p>在游戏项目开发中,会涉及到大量的开发、美术、策划以及外包等等各个方面的研发人员。出于资源安全和信息保密的考虑,通常会做一些复杂的权限控制和同步逻辑。</p>
<p>但抛开权限控制,仅探讨资源本身,在UE中资源是向上兼容的,用同版本号的引擎或者更高版本号的引擎可以直接打开。这意味着分发出去的资源,可以直接在另外的项目里使用。所以,该如何保证开发阶段资源的安全性是要重点关注的。</p>
<p>本篇文章提供一种加密工程中原始UASSET资源的思路,并介绍可以用于资源加密的基础原理。但如果公开具体的加密实现,就等同于裸奔,所以本篇文章仅提供对uasset资源结构的分析以及可用于实现加密的思路,但不会提供具体的实现代码。</p>
UE插件与工具开发:Commandlet
https://imzlp.com/posts/27475/
2023-03-23T13:46:03.000Z
2023-03-23T13:46:03.000Z
<p>在使用UnrealEngine开发工具时,有相当一部分的情况是对资源处理和数据导出需求,这些任务是需要频繁且自动化执行的,通常会把它们集成到CI/CD系统中。</p>
<p>在具体的实现中,就要利用UE的<code>Commandlet</code>机制,用命令行的形式去驱动引擎,做自定的行为。</p>
<p>以我开发的插件中支持的Commandlet功能为例:</p>
<ol>
<li><a href="https://imzlp.com/posts/10938/">HotPatcher</a>:导出基础包信息、打包补丁</li>
<li><a href="https://imzlp.com/posts/22655/">ResScannerUE</a>:变动资源的增量扫描</li>
<li><a href="https://imzlp.com/posts/24350/">HotChunker</a>:独立打包Chunk</li>
<li><a href="https://imzlp.com/posts/26943/">libZSTD</a>:训练Shader字典</li>
<li><a href="https://imzlp.com/posts/20203/">ExportNavMesh</a>:导出NavMesh数据</li>
</ol>
<p>Commandlet能够使它们比较方便地集成到CI/CD中,实现自动化。</p>
<p>本篇文章中,我将会主要介绍UE的Commandlet机制,并分析它的实现原理,以及提供一些开发技巧、我在开发过程中的一些思考等。</p>
<p>同时,这也是我<a href="https://imzlp.com/categories/UnrealEngine/%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91/">UE插件与工具开发</a>系列的第二篇文章,后续会持续更新,敬请期待。</p>
资源管理:重塑UE的包拆分方案
https://imzlp.com/posts/37036/
2023-03-15T11:24:32.000Z
2023-03-15T11:24:32.000Z
<p>之前我写了一篇文章,介绍UE默认的拆包方式(<a href="https://imzlp.com/posts/13765/">UE 热更新:拆分基础包</a>),但UE默认的拆包方式在大规模资源项目中不够灵活,无法满足对超大规模资源项目的精细化管理需求。</p>
<p>为了解决<a href="https://imzlp.com/posts/37036/#UE%E9%BB%98%E8%AE%A4%E6%89%93%E5%8C%85%E7%9A%84%E9%97%AE%E9%A2%98">UE默认打包和资源拆分的痛点</a>,我基于HotPatcherCore开发了一个扩展,能够能够解决默认拆包流程的缺点,足够地灵活与强大。博客中有篇文章,介绍它的整体实现机制: <a href="https://imzlp.com/posts/24350/">一种灵活与非侵入式的基础包拆分方案</a>。</p>
<p>HotChunker能够非侵入式地集成到UE默认的打包流程中,无需手动做任何的处理,只要UE默认打包,就会自动拉起HotChunker的拆包流程,实现资源的Cook、打包,以及自动Copy到StagedBuilds目录中。</p>
<p>本篇文章会着重介绍,使用HotChunker在进行资源拆分的配置方式和自动化构建、最大限度地降低资源冗余、以及进行并行打包的实现。</p>
内存扩展:UE中利用IOS新的内存特性
https://imzlp.com/posts/56381/
2023-01-31T10:37:38.000Z
2023-01-31T10:37:38.000Z
<p>内存优化是游戏开发中经常关注的课题,为了避免App过度分配内存触发OOM被系统强杀,通常的优化手段是从使用层面入手,提升内存的利用效率,裁剪不需要的功能、控制加载的资源等等。</p>
<p>但还有一种情况,提升App触发OOM的阈值,让系统允许我们的App分配更多的内存。在新的IOS版本中,苹果为App引入了新的内存特性,可以允许App扩展寻址空间和提高可分配内存。</p>
<p>本篇文章,我将研究如何把这些特性在UE内利用起来,提高游戏在IOS平台的可分配内存总量。</p>
UE插件与工具开发:基础概念
https://imzlp.com/posts/75405/
2023-01-29T12:12:55.000Z
2023-01-29T12:12:55.000Z
<p>在使用UnrealEngine进行项目开发的过程中,经常会开发和接入各种类型的插件来对引擎进行扩展,从而实现不同的需求。对于开发者而言,对运行机制的理解优于工具的使用。所以对于插件的接入和开发,有必要了解其原理。</p>
<p>之前我也开发了一些UE的工具和插件,我希望写一个相关的系列文章,把UE插件与工具开发相关具有共性的技术内容做一些总结,并分享一些我开发插件时的一些思考和功能脚手架。尽可能用最少的代码、最小的侵入式和最佳的实现策略,来实现需要的功能。</p>
HotPatcher的模块化改造和开发规划
https://imzlp.com/posts/30178/
2023-01-07T11:25:54.000Z
2023-01-07T11:25:54.000Z
<p>随着<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>的开发以及我对于资源管理方面的技术的研究,围绕着<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>实现的功能越来越多,实现也越来越复杂,加上引擎的不断更新,一个大而全的插件对引擎的兼容性越来越难以维护。</p>
<p>随着新一代引擎UE5的到来,<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>同样会跟进UE5中支持,并针对UE5的特性开发新的功能。我希望它不仅仅只是一个资源打包工具,而是包含资源管理、审计、打包、热更新、包体优化、构建提升等等全方位的资源管理方案,并且作为一个开放式的资源处理框架。<br><img src="https://img.imzlp.com/imgs/zlp/picgo/2022/202301071731545.webp"></p>
<p>本篇文章会介绍<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>的模块化进展,对现有功能的支持。以及如何利用<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>强大的打包能力根据项目需求进行自定义的模块化扩展。最后,会介绍<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>项目后续的开发计划。</p>
2022 Unreal Open Day
https://imzlp.com/posts/10975/
2022-11-20T10:04:57.000Z
2022-11-20T10:04:57.000Z
<p>2022年的Unreal Open Day是Epic官方以线下活动+线上直播的形式进行的,很开心今年参加了线下的Unreal Open Day活动。<br>今年我录制了一场线上的技术演讲,也去上海直播现场参加了线下活动,很荣幸再次获得了Epic授予的<strong>杰出社区贡献者</strong>奖项,对我是认可也是激励,期待UE技术社区能发展的越来越好,成为最为活跃的游戏开发者社区。<br>本篇文章做一个简单的记录,把 UOD 2022的资料做一下整理,也把我参加 UOD 的视频、演讲 PPT,以及相关的资料做一个总结,还有一些在 UOD 直播现场拍的照片。</p>
一种灵活与非侵入式的基础包拆分方案
https://imzlp.com/posts/24350/
2022-10-23T15:20:00.000Z
2022-10-23T15:20:00.000Z
<p>UE默认的资源管理较为复杂,默认情况下是根据在<code>ProjectSetting</code>里配置的地图、目录、PrimaryAsset的配置,以及对一些条件的组合检测来执行资源打包过程的。并且,UE的Cook是根据运行时的动态加载来实时添加资源打到包中的,这导致打包的资源进包过程几乎等同于黑盒。</p>
<p>博客中介绍<strong>默认的进包资源规则</strong>及<strong>基础包拆分</strong>的文章:</p>
<ul>
<li><a href="https://imzlp.com/posts/22570/">UE 资源管理:引擎打包资源分析</a></li>
<li><a href="https://imzlp.com/posts/13765/">UE 热更新:拆分基础包</a></li>
</ul>
<p>本篇文章提供了一种新的思路,利用<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>的精确Cook和打包机制,实现了一个HotChunker的Mod,能够对引擎的<strong>非侵入式</strong>,直接<strong>复用UE默认打包过程</strong>、<strong>简单清晰</strong>地进行拆分基础包。本篇文会具体介绍使用方式以及实现原理。</p>
循迹研究:如何写好一篇技术文章
https://imzlp.com/posts/23932/
2022-09-12T20:18:36.000Z
2022-09-12T20:18:36.000Z
<p>技术文章是能够有效锻炼<strong>表达能力</strong>和进行<strong>技术积累</strong>的方法。与单纯的技术笔记不同,我认为的技术文章应该是对<strong>实际的问题</strong>或<strong>新技术思路</strong>的解决方案,而不是技术点的简单堆砌。</p>
<p>对于如何写一篇我认为合格的技术文章, 最近做了一些思考,本篇文章会探讨我写文章时的一些思路和步骤,以及工具推荐和CI/CD自动化发布的实现。</p>
UE中ASTC贴图压缩分析及效率优化
https://imzlp.com/posts/7181/
2022-09-08T19:01:53.000Z
2022-09-08T19:01:53.000Z
<p><code>ASTC</code>是<code>Adaptive Scalable Texture Compression</code>的简称,是在移动端流行的贴图压缩方案。当平台使用ASTC打包时,UE默认使用<a href="https://github.com/GameTechDev/ISPCTextureCompressor">Intel ISPC Texture Compressor</a>压缩贴图,但它具有一些局限性,只支持<code>8x8</code>及以上的压缩规格,<code>10x10</code>和<code>12x12</code>则不支持,如果在项目中指定它们,也是会使用<code>8x8</code>的规格。除<a href="https://github.com/GameTechDev/ISPCTextureCompressor">ISPC</a>外,引擎中也提供了ARM的<a href="https://github.com/ARM-software/astc-encoder">astc-encoder</a>压缩方式,可以支持<code>8x8</code>以下的规格,但默认未启用,而且引擎中的集成压缩效率非常低,在大规模资源中,使用<a href="https://github.com/ARM-software/astc-encoder">astc-encoder</a>压缩贴图对Cook耗时是非常大的挑战。</p>
<p>本篇文章分析UE中贴图使用ASTC压缩的配置以及实现方式,以及引擎中<a href="https://github.com/ARM-software/astc-encoder">astc-encoder</a>的压缩效率和优化思路。</p>
UE中多阶段的自动化资源检查方案
https://imzlp.com/posts/22655/
2022-08-23T11:30:21.000Z
2022-08-23T11:30:21.000Z
<p>在大型项目中,资源的规模非常庞大,涉及的制作团队也非常广泛,场景、角色、UI、动画、特效、蓝图、数据表格等等,随之而来就是资源量和资源规范的管理难以把控。</p>
<p>对于制定的资源规格,美术制作人员难以覆盖100%的情况,会存在不经意间漏掉,大多数情况下都是包内发现问题后再处理,而且对于存量的资源,需要耗费大量的人力处理,难以审查和修复。</p>
<p>基于这种痛点,我之前开发了一个资源扫描工具,可以方便地编辑规则对项目内的资源进行扫描。</p>
<ul>
<li><a href="https://imzlp.com/posts/71162/">UE 中利用反射为资产建立属性缓存</a></li>
<li><a href="https://imzlp.com/posts/19901/">UE 中资源自修正的设计与实现方案</a></li>
<li><a href="https://imzlp.com/posts/22655/">UE 中多阶段的自动化资源检查方案</a></li>
<li><a href="https://imzlp.com/posts/20376/">基于ResScannerUE的资源检查自动化实践</a></li>
<li><a href="https://imzlp.com/posts/11750/">UE资源合规检查工具ResScannerUE</a></li>
</ul>
<p>近期,我对插件做了全方面地升级,增强了编辑时和自动化检查的能力,本篇文章会介绍如何利用<a href="https://imzlp.com/posts/11750/">ResScannerUE</a>实现<strong>编辑时</strong>、<strong>提交时</strong>、<strong>CI定时或Hook任务</strong>、<strong>Cook时</strong>等各个阶段的资源扫描,把错误地资源尽可能地在制作时暴露出来并提示解决,避免包内资源异常。</p>
<p>在插件的具体实现上,也针对扫描速度做了很多优化,尽可能把检查变成一个无感知的行为,文章内会具体介绍。</p>
一种高效的ZSTD Shader字典训练方案
https://imzlp.com/posts/26943/
2022-07-14T13:01:54.000Z
2022-07-14T13:01:54.000Z
<p>在文章<a href="https://imzlp.com/posts/24725/">基于 ZSTD 字典的 Shader 压缩方案</a>中,我介绍了一种利用ZSTD字典压缩UE的ShaderCode的方法,可以极大地提升ShaderLibrary的压缩比。但训练字典和使用字典进行压缩的流程仍然比较复杂,并不是一个高效的工程实现:</p>
<ol>
<li>需关闭引擎默认的Shader压缩</li>
<li>Cook一遍项目才能Dump每个Unique Shader的ShaderCode</li>
<li>基于Dump出的ShaderCode文件,使用ZSTD程序训练字典</li>
<li>再次执行完整的Cook过程,使用字典进行压缩,生成最终的shaderbytecode</li>
</ol>
<p>根据上述的流程,需要变动引擎才能实现Dump ShaderCode;其次是流程的割裂,Dump ShaderCode之后需要拉起<code>zstd</code>程序执行训练才能得到字典;最后,仍需要再Cook一遍工程,使用训练出的字典压缩Shader。并且在关掉Shader的压缩后会导致使用LZ4压缩的DDC Cache Miss,重复Cook执行的时间开销巨大,在海量Shader的项目中耗时无法接受。</p>
<p>基于这种痛点,我研究并实现了一种高效的字典训练方法,无需修改引擎,并且十分快速地训练字典和基于字典压缩。能够直接从ushaderbytecode中训练字典,并生成使用ZSTD+字典压缩的ushaderbytecode,极大地提升了处理效率,完全Plugin-Only的实现,接入成本几乎为零,后续将作为<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>的扩展模块发布。</p>
虚幻引擎中Pak的运行时重组方案
https://imzlp.com/posts/12188/
2022-05-23T11:03:22.000Z
2022-05-23T11:03:22.000Z
<p>Pak是UE中的UFS中的一环(Unreal File System),是在应用层构造的一种虚拟文件系统。用于把游戏相关的资源、文件打包至一个Pak文件中,避免在运行时对游戏资源的访问创建出大量的文件句柄,并且可以做读缓存(PakCache),提升加载效率。</p>
<p>并且,在UFS中,可以控制每个Pak的优先级,可以用来控制文件系统中文件的优先级。在通过UFS加载文件时,优先级高的Pak中的文件会被首先命中,就可以替换掉低优先级的文件,这也是UE实现热更新的关键,详见之前的<a href="https://imzlp.com/categories/UnrealEngine/%E7%83%AD%E6%9B%B4%E6%96%B0/">热更新系列文章</a>。</p>
<p>但默认情况下,Pak的打包都是在UE端进行的,<code>PakUtilities</code>和<code>UnrealPak</code>都是开发端的功能,运行时不存在,这意味着不能在运行时创建出Pak文件。但Pak本身是Archive的文件形式,理论上是可以进行运行时重组的。</p>
<p>本篇文章就从Pak的创建、文件格式、UFS分析、运行时重组可行性等方面着手,探讨运行时重组Pak的实现细节以及应用方向。</p>
基于ZSTD字典的Shader压缩方案
https://imzlp.com/posts/24725/
2022-04-17T17:37:38.000Z
2022-04-17T17:37:38.000Z
<p>随着项目规模的日益增大,UE里Shader的变体数量逐渐累增,往往能够达到数百万的Shader变体,虽然UE为了避免Shader的重复存储提供了<code>Share Material Shader Code</code>功能,可以把Shader序列化到一个独立的<code>ushaderbytecode</code>文件中,但也会占用几百M的包体大小。而UE默认情况下,把这些NotUAsset文件默认进Chunk0,即必须进基础包,对于移动端的基础包影响很大,几百M的空间,可以放很多资源了。</p>
<p>为了解决这个问题,只能从三个方面入手:</p>
<ol>
<li>降低项目中的变体数量,Dump出项目中的Shader信息,分析哪些是不必要的;</li>
<li>拆分shaderbytecode,基础包中只包含必要的Shader,其余按需下载。但UE默认没有提供这样的机制,可以使用我开发的<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>拆分基础包,生成多个shader lib,使用热更流程动态下载资源和所需的shaderbytecode。</li>
<li>使用压缩率更高的算法来对ShaderCode进行压缩,引擎中默认使用LZ4;</li>
</ol>
<p>第一种方式需要TA和美术协同实现,想要有显著的提升较为困难。第二种方案详见之前的热更新系列文章(<a href="https://imzlp.com/categories/UnrealEngine/%E7%83%AD%E6%9B%B4%E6%96%B0/">Unreal Engine#热更新</a>)。本篇文章从第三种方式入手,为Shader实现了一种特殊的压缩方式,可以有效地降低shaderbytecode的大小,大幅度提升Shader的压缩比,并且可以与方案2结合使用,在拆分shaderbytecode的同时,大幅度提高压缩率。</p>
高效调试:命令行参数启动UE Android App
https://imzlp.com/posts/29169/
2022-01-01T19:58:02.000Z
2022-01-01T19:58:02.000Z
<p>在使用UE开发的过程中,指定命令行参数(Command Line)是一个经常会用到的功能,可以方便地控制部分流程、开关等。UE也是大量地使用了Comandline来控制引擎的行为,官方文档:<a href="https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/CommandLineArguments/">Command-Line Arguments</a>,不同的模块都可以从Commandline中读取或检查参数,实现自定义的命令行参数功能。</p>
<p>但是,对于移动端Android平台,并不能很方便地指定启动参数,需要编辑<code>ue4commandline.txt</code>文件,非常繁琐。</p>
<p>基于这种痛点需求,我利用元旦的假期开发一个UE的Android的插件,可以让Android的程序像PC一样方便启动和指定命令行参数,并且不需要修改引擎,启用插件后打包Apk即可使用,开源在Github上:<a href="https://github.com/hxhb/AppCmderUE">hxhb/AppCmderUE</a>。</p>
<p><img src="https://img.imzlp.com/imgs/zlp/picgo/2023/20230118171536.webp"></p>
<p>本篇文章分析了UE在Androdid端Commandline的读取规则,并介绍了<a href="https://github.com/hxhb/AppCmderUE">AppCmderUE</a>插件的实现原理与使用方法。</p>
UE资源管理:引擎打包资源分析
https://imzlp.com/posts/22570/
2021-12-31T14:33:25.000Z
2021-12-31T14:33:25.000Z
<p>默认情况下,在UE中打包项目时,会拉起BuildCookRun来执行Compile/Cook/Pak/Stage等一系列流程。在UE中,只有参与Cook的资源才会被打包,但是通常会包含很多预期之外的资源,可能会造成困扰,到底引擎依赖哪些资源?以及该如何管理UE参与打包的资源。</p>
<p>本篇文章从UE打包时分析资源进行Cook的规则入手,研究在打包时究竟会将哪些资源进行Cook,了解这一点对于资源管理很有作用,基于此可以实现自定义的Cook过程,将Cook任务分配至不同的进程乃至机器实现并行化,加速UE的构建过程。</p>
<p>除了uasset这些资源外,打包时还有很多Non-Asset文件,如ini、Shader Library、AssetRegistry、或者项目中添加的脚本文件等等,在之前的文章<a href="https://imzlp.com/posts/17371/">UE热更新:需求分析与方案设计</a>中有过介绍,UE对于它们的<strong>收集</strong>并不在Cook阶段(Shader Library和AssetRegistry是在Cook阶段生成),本篇文章暂不作讨论,后续会写一篇专门介绍的文章。</p>
循迹研究:我的2021年度总结
https://imzlp.com/posts/24854/
2021-12-23T20:58:35.000Z
2021-12-23T20:58:35.000Z
<p>我一直希望做的所有事情都是可以量化、能够被记录的,不然一年又一年循环往复会记不起自己到底做了什么事情,所以会做一个年度总结。</p>
<p>2021年马上结束,回想这一年,发生了许多事,有了很多新的想法,也是对我影响最大的一年。</p>
循迹研究:分析流量数据的二三事
https://imzlp.com/posts/14354/
2021-11-21T10:25:13.000Z
2021-11-21T10:25:13.000Z
<p>近期查看了博客Google Analysic的访问数据,通过流量分析发现一些很有意思的点,能够在一定程度上体现出在使用虚幻引擎进行游戏开发方面的用户特征。文章内的数据样本为本站2021.11.14-2021.11.20一周的访问流量,总体数据量有限不一定能体现出真实趋势,仅供参考。</p>
UE5:Game Feature预研
https://imzlp.com/posts/17658/
2021-11-17T12:31:24.000Z
2021-11-17T12:31:24.000Z
<p>UE5的预览宣传视频里,介绍了一种模块化开发GamePlay的机制,类似于Mod式地开发和管理游戏功能和资源,被称作“Game Feature”,在UE4.27和UE5中已经可以启用了,我觉得这个新的Gameplay Modualr形式很棒,所以做一个技术预研。</p>
<p>本篇文章介绍Game Feature的启用流程和运行机制介绍,文末分享了一个基于Game Feature的展示Demo。并为<a href="https://imzlp.com/posts/17590">HotPatcher</a>实现了能够将Feature独立打包的机制,Game Feature不必预先打包进基础包内,可以在运行中按需下载与加载,实现真正意义上的独立地模块化加载。</p>
<p>目前UE5 EA版本中还有不完善的地方,相关的内容也会随着引擎的更新进行补充。</p>
开源一个虚幻引擎启动器UE Launcher
https://imzlp.com/posts/3635/
2021-11-10T14:17:15.000Z
2021-11-10T14:17:15.000Z
<p>通常在使用UE进行项目开发时,本地会有多个引擎版本,而Epic Game Launcher只支持安装版引擎的启动,不支持源码编译的引擎。<br>当本地具有多个引擎版本时,切换不方便,并且没有一种便捷地启动引擎工具、项目以及给项目添加启动参数的方式,在执行Commandlet时需要创建很多脚本,管理非常麻烦。基于这些痛点,我开发了一个UE启动器:<a href="https://github.com/hxhb/UE4Launcher">UELauncher</a>,用来解决这些问题,同时支持UE4和UE5。</p>
基于ResScannerUE的资源检查自动化实践
https://imzlp.com/posts/20376/
2021-10-25T15:49:18.000Z
2021-10-25T15:49:18.000Z
<p>对于项目中的资源检查需求,需要能够实现简单且方便地配置、自动化地执行,并且能够及时地定位相关人员。基于这个需求,我开源了一个资源合规扫描工具<a href="https://imzlp.com/posts/11750/">ResScannerUE</a>,配置文档:<a href="https://imzlp.com/posts/11750/">UE 资源合规检查工具 ResScannerUE</a>。<br>本篇文章将介绍如何通过该工具,实现资源扫描的自动化,并提供了与Git结合的方式进行增量检测支持,使用Commandlet在CI平台上实现Content内容变更的自动触发并执行检测规则,并能够定位到出问题资源最近提交人,实现精确定位,实时发送扫描报告至企业微信,提醒通知相关人员进行处理。<br>另外,我还提供了基于Git的Pre-Commit Hook实现,可以在提交之前检测本次提交是否具有不合规资源,并禁止提交,避免问题资源污染远程仓库。整体方案经过了精心设计和大量体验优化、增强自动化支持,可以非常方便地配置、接入,能够实现各种资源扫描的需求。</p>
虚幻引擎中的属性面板定制化
https://imzlp.com/posts/26919/
2021-10-25T09:34:21.000Z
2021-10-25T09:34:21.000Z
<p>在UE中开发编辑器插件时,通过USTRUCT的反射信息自动创建属性面板是非常方便提供配置化的方式,但经常会有一些特殊的属性面板定制需求,比如提供特殊的面板选项、根据参数的不同展示不同类型的值等。UE中的属性面板在<a href="https://imzlp.com/posts/17590/">HotPatcher</a>和<a href="https://imzlp.com/posts/11750/">ResScannerUE</a>中都有应用,能够非常方便地进行插件地配置与定制化。UE的官方文档:<a href="https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/Slate/DetailsCustomization/">Details Panel Customization</a>。</p>
<p>本篇文章从创建独立的<code>Details</code>面板入手,通过<a href="https://imzlp.com/posts/11750/">ResScannerUE</a>中的具体案例,提供属性面板和属性条目的自定义的实现方法。</p>
UE热更新:Config的重载与应用
https://imzlp.com/posts/9028/
2021-10-18T14:57:38.000Z
2021-10-18T14:57:38.000Z
<p>在UE引擎中有大量的配置使用ini来进行设置与控制。对于项目而言,了解其中哪些是能够更新的,能够对制定项目的更新内容规则有帮助。并且,UE很多功能都是通过CVars等方式实现的配置化和动态开关以及对指定平台或设备的Device Profiles设置,同样可以在热更中实现运行中配置的动态下发及应用。<br>本篇文章从引擎机制分析ini config的加载流程、以及不同的配置模块在热更之后重载、在项目中如何应用等内容,基于Ini配置文件的热更实现运行时引擎或项目中参数的修改、reapply,增强游戏的更新能力。</p>
UE资源合规检查工具ResScannerUE
https://imzlp.com/posts/11750/
2021-09-15T15:29:18.000Z
2021-09-15T15:29:18.000Z
<p>在游戏项目开发中,因为资源量大,涉及人员广,比较难自觉地统一资源规范,如果资源出现问题,手动排查要花费大量的人力,这也是资源管理的风险和痛点。<br>基于这种需求,我开发了一款编辑器下的资源扫描规范工具<a href="https://imzlp.com/posts/11750/">ResScannerUE</a>,可以非常方便地配置规则并实现自动化,由美术人员在资源提交前、定期执行等方式,提前检查项目中的资源是否合规,避免在打包后才发现问题。<br>本篇文章介绍<a href="https://imzlp.com/posts/11750/">ResScannerUE</a>插件的使用方法、运行机制、自定义规则的扩展方式,以及后续的优化安排。</p>
UE热更新:Shader更新策略
https://imzlp.com/posts/15810/
2021-09-13T10:24:16.000Z
2021-09-13T10:24:16.000Z
<p>在之前的一些文章中,介绍了UE热更新丢失Shader使用默认材质的处理问题,以及Shader Patch的方案。<br>详情可见文章:</p>
<ul>
<li><a href="https://imzlp.com/posts/5867/">UE 热更新:Create Shader Patch</a></li>
<li><a href="https://imzlp.com/posts/16895/#%E7%83%AD%E6%9B%B4%E7%9A%84%E8%B5%84%E6%BA%90%E6%B2%A1%E6%9C%89%E6%95%88%E6%9E%9C-%E6%9D%90%E8%B4%A8%E4%B8%A2%E5%A4%B1">UE热更新:Questions & Answers#热更的资源没有效果/材质丢失</a>。</li>
</ul>
<p><img src="https://img.imzlp.com/imgs/zlp/blog/notes/ue/index/UE4/pak-shadercode-error-in-ue425.webp"></p>
<p>其实运行时丢失材质的根本原因是新添加或修改的资源所依赖的Shader没有被打包,运行时读取失败导致的错误。本篇文章来介绍一下Shader更新的策略和优缺点,以及对引擎内机制的分析,并提供一个结合Shader Patch与Inline Shader Code优点的优化方案,已经在<a href="https://github.com/hxhb/HotPatcher">HotPacther</a>中实现。</p>
UE热更新:资源的二进制补丁方案
https://imzlp.com/posts/25136/
2021-09-06T16:27:10.000Z
2021-09-06T16:27:10.000Z
<p>先前介绍了一系列UE中热更新工程实践的文章,能够实现基于原始工程的资源的版本比对与差异更新。但默认情况下资源的更新是基于文件的更新,某个资源产生了变动,就要将该资源的文件完整地打包进去,而UE的资源变动在Cook之后并不会造成整个文件的全部更新,序列化时只变动了某些bytes。在这种情况下,基于文件的Patch机制能够大幅度减少补丁的大小,本篇文章对二进制补丁的生成和加载方案做一个概述,以<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>为基础,可以方便地实现二进制补丁的生成。<br>为了实现这个需求,我将HDiffPatch移植到了UE内,将其作为<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>默认的二进制差异补丁的DIFF/PATCH算法,基于Modular Feature方式也可以方便地扩展其他的算法。</p>
UE As Lib机制初探
https://imzlp.com/posts/26475/
2021-08-24T09:34:30.000Z
2021-08-24T09:34:30.000Z
<p>UE4.27推出了一项新的机制,可以把UE编译成库,能够嵌入到外部程序中,由其他的程序来驱动引擎的执行与消息通信。但是目前官方还没有放出任何有价值的文档,我分析了引擎中的相关代码,提出一个UE as Lib的实践方案,理论上也能在4.27之前的引擎版本实现,或许会与后续官方发布的文档不一致,权当抛砖引玉。相关的研究内容也会在本篇文章中持续更新。</p>
Profiling IOS With Unreal Insights
https://imzlp.com/posts/14154/
2021-08-19T14:14:48.000Z
2021-08-19T14:14:48.000Z
<p>Unreal Insights是UE自4.23之后提供的一个Profiling工具,可以非常方便地看到游戏运行的各个线程的火焰图,但是官方文档只提供了PC和Android的连接方法,并不直接支持IOS,不太方便。研究了一下发现IOS主要是网络策略的问题,本篇文章提供一个UE与IOS设备的真机Profliing以及端口互通方案,可以支持实时的Profiling以及Cook on the fly等IOS真机与PC数据互通的需求。</p>
UE多用户协同编辑服务部署指南
https://imzlp.com/posts/25226/
2021-08-05T16:15:28.000Z
2021-08-05T16:15:28.000Z
<p>在大世界项目以及疫情导致的远程办公需求,开发中的协同编辑显得格外重要。在UE的资源机制中,地图是单个的资源,虽然可以使用Sub-level的形式拆分,但是最小元素仍然是单个资源,当不同的Designer修改相同的资源时,就会造成文件冲突,也没办法像文本那样合并。并且每个人负责编辑单个子关卡也没有办法实时预览整个场景的效果,在协同开发中,这是一个瓶颈。<br>在UE4.23之后,UE官方推出了一个多人协作机制,可以使多人共同地编辑同一份地图,并不会造成冲突,并且可以同步其他变动的资源并能够实时生效,作为版本控制的补充,能够比较完美地解决同步协作的问题。<br>本篇文章记录一下启用流程、使用规范以及网络策略等问题,也会提取独立的Server端程序而无需依赖完整的引擎,实现Server端的方便部署。</p>
Zlib/Oodle/ZSTD压缩算法性能对比
https://imzlp.com/posts/30732/
2021-07-06T19:59:39.000Z
2021-07-06T19:59:39.000Z
<p>之前我写了一篇文章,在UE中集成了ZSTD压缩算法:<a href="https://imzlp.com/posts/8470/">ModularFeature:为 UE4 集成 ZSTD 压缩算法</a>,并且把UE5中的Oodle的压缩算法库提取出来,可以在UE4中使用:<a href="https://imzlp.com/notes/ue5/#Oodle-Compression">Oodle Compression</a>。最近分析了一下他们的压缩、解压、CPU、内存的消耗,分别测试了WindowsNoEditor/Android_ASTC/IOS三个平台,以及Oodle的Kraken使用不同的压缩级别在不同平台的性能。</p>
UE5:新一代虚幻引擎初探
https://imzlp.com/posts/8724/
2021-05-25T12:22:44.000Z
2021-05-25T12:22:44.000Z
<p>终于,在2021年的五月底,UE5终于要推出第一个预览版本了,<a href="https://mp.weixin.qq.com/s/W0e79uhqOyxLKXeC9MwnDg">虚幻引擎5——将于中国时间5月26日周三晚10点开启抢先体验计划!</a>。<br>对UE5期待许久,去年Nanite和lumen一石激起千层浪,时隔一年,终于能够实际体验到了。<br>过去一年,关于UE5的技术消息不多,我做过了一些Epic披露的关于UE5相关的信息总结和分析,有兴趣的可以移步<a href="https://imzlp.com/notes/ue5/">notes/ue5</a>中查看。本篇文章会记录上手UE5的一些体验,相较于UE4开发方式的变动,为UE4到UE5的过渡,以及将UE5应用到生产环境做一个技术预研,近期会持续更新。</p>
UE项目优化:PSO Cache
https://imzlp.com/posts/24336/
2021-04-22T19:40:55.000Z
2021-04-22T19:40:55.000Z
<p>UE中具有PSO Cache机制,全称Pipeline State Object Caching,用于预先记录和构建出运行时所使用的材质依赖的Shader信息,当项目首次使用这些Shader时,该列表可以加速Shader的加载/编译过程。PSO Cache会把渲染状态、顶点声明、Primitive类型、RenderTarget像素格式等数据保存到文件中,提升Shader的加载效率。<br>本篇文章主要介绍PSO Cache的启用及构建流程,并会分析PSO Cache在引擎中的加载流程以及实现热更PSO方式、错误处理等,PSO Cache的原理有时间再进行详细分析。</p>
UE开发笔记:Android篇
https://imzlp.com/posts/17996/
2021-04-15T19:54:12.000Z
2021-04-15T19:54:12.000Z
<p>在之前的一篇文章中,介绍了Mac/IOS的开发笔记和一些工程实践:<a href="https://imzlp.com/posts/1948/">UE4 开发笔记:Mac/iOS 篇</a>。本篇文章作为姊妹篇,记录我在使用UE在开发Android时所用的标准化环境、调试工具、工程实践以及分析相关的引擎代码等内容,记录了一些在项目中遇到的坑,主要从我之前的笔记<a href="https://imzlp.com/notes/ue/">notes/ue</a>中整理而来,后续Android相关的内容也都会更新到这篇文章里。</p>
UE性能分析:内存优化
https://imzlp.com/posts/19135/
2021-03-30T10:59:16.000Z
2021-03-30T10:59:16.000Z
<p>在开发游戏时,程序性能是需要着重考虑的问题,因为要尽可能覆盖最多的用户群体,就要考虑那些中低端设备的运行效果,兼容非常多配置差异的硬件,在这种情况下,怎么样分析和优化游戏的性能瓶颈是关键。</p>
<p>在运行时把更多的资源加载至内存中,本质上是一种空间换时间的思路。因为频繁从磁盘进行IO是非常耗时的,把资源预先加载到内存就可以实现高速读取,但是内存资源也是有限的,并不能不加限制地使用,尤其是对某些中低端移动设备而言,4G甚至更小的内存的设备目前还具有不少的占有率,所以在内存方面不能浪费,而且过高的内存占用也有可能导致被系统查杀。</p>
<p>内存优化本质上就是在加载效率和内存占用之间寻求一个平衡,怎么样在能满足兼容更多低配设备正常运行不触发OOM的同时尽可能地把可利用的内存使用起来,提高程序的运行效率。</p>
<p>准备写几篇性能优化相关的文章,本篇文章先从UE内存分析入手,介绍常用的内存分析工具和方法,以及对UE项目中能够进行的内存优化手段做一个整理,这部分内容之前以笔记的形式记录在<a href="https://imzlp.com/notes/ue/">notes/ue</a>中,后续内存相关的内容都会补充到本篇文章。</p>
UE热更新:Questions & Answers
https://imzlp.com/posts/16895/
2021-03-12T10:45:44.000Z
2021-03-12T10:45:44.000Z
<p><a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>项目开源这一年多以来,经过了不少的更新和优化,也被越来越多的开发者选择作为自己项目的热更新方案,期间有不少人陆陆续续询问UE4热更新相关遇到的问题,很多问题比较常见,重复询问的频率也比较多,所以我准备把一些常见的问题进行整理,方便初步上手UE4热更新方案的人能够尽快地排查问题。</p>
<p>本篇文章会持续更新UE4热更新和<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>相关的Q&A内容,有疑问的地方也可以直接在本篇文章中评论,我会定期统一回答和整理,也可以加入我的UE4热更新群讨论遇到的问题(QQ群958363331)。</p>
UE热更新:Create Shader Patch
https://imzlp.com/posts/5867/
2021-03-12T09:49:27.000Z
2021-03-12T09:49:27.000Z
<p>之前的热更新系列文章中介绍了UE热更新的流程和打包细节,其实有一些热更补丁优化的工程实践我觉得也可以详细介绍。</p>
<p>本篇文章从生成Shader的Patch入手,目的减少每次热更新时的Shader的大小,并会对引擎内部的实现细节做一些分析,解决引擎中的Shader Patch的相关问题,并基于<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>的实现自动化的Shade Patch流程。</p>
<blockquote>
<p>2021.11.02 UPDATE:<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>已支持对Patch中所有Cook资源编译的Shader收集起来打包为Shader Library,可以替代Shader Patch的机制。详情见文章:<a href="https://imzlp.com/posts/15810/">UE热更新:Shader更新策略</a>。</p>
</blockquote>
UE反射实现分析:反射代码生成(一)
https://imzlp.com/posts/9780/
2021-03-10T15:14:19.000Z
2021-03-10T15:14:19.000Z
<p>之前写了两篇UE中实现反射的文章分析,介绍了UE的反射基础概念和依赖的一些C++特性,本篇文章开始分析UE反射实现的具体流程。</p>
<p>C++标准中并没有反射的特性,UE使用的反射是基于<strong>标记语法</strong>和<strong>UHT扫描生成辅助代码</strong>来实现的一套机制,正如<a href="https://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)">David Wheeler</a>的那句名言一样:“<em>All problems in computer science can be solved by another level of indirection</em>”,UHT做的就是这样的事情,在真正执行编译之前分析标记代码并产生真正的C++代码,收集反射类型的元数据,供运行时之用。</p>
<p>UHT生成的代码内容很多,为了避免文章组织上的混乱,本篇文章主要讲<code>GENERATED_BODY</code>/<code>UFUNCTION</code>等反射标记通过UHT之后生成到<code>generated.h</code>中的<strong>真正的C++代码</strong>。</p>
<p>UHT生成的代码分别在<code>generated.h</code>和<code>gen.cpp</code>中,<code>generated.h</code>中的代码大多是定义了一些宏,用在所声明的类内通过编译器预处理来添加通用成员,<code>gen.cpp</code>中的代码则是UHT基于反射标记生成的用来描述类反射信息的具体代码,<code>genrated.h</code>和<code>gen.cpp</code>也是为了声明和定义分离。</p>
UE热更新:资产管理与审计工具
https://imzlp.com/posts/3675/
2021-03-09T18:16:31.000Z
2021-03-09T18:16:31.000Z
<p>在前面的文章中,介绍了基础包的拆分规则和实现,在基础的打包规则稳定之后,日常开发中的关注重点就转向侧重于项目的资产管理和包体资源审计、分析项目中的资产大小和冗余情况等。</p>
<p>本篇文章介绍UE中的资源打包配置、常用的资产管理方式以及资产审计工具等工程实践,热更新系列文章的资源管理篇,也是对上一篇文章<a href="https://imzlp.com/posts/13765/">UE4热更新:拆分基础包</a>的内容补充。</p>
UE热更新:拆分基础包
https://imzlp.com/posts/13765/
2021-01-27T21:51:56.000Z
2021-01-27T21:51:56.000Z
<p>在之前的几篇文章中,分别介绍了UE热更新的实现机制,以及热更的自动化流程,近期打算继续写几篇文章介绍下UE里热更新中资源包管理的流程和规则。</p>
<p>当然,不同类型的项目会有不同的打包策略,资源管理也没有通用的最佳策略。本篇文章主要介绍热更新流程中基础包的拆分的工程实践,涉及修改引擎实现Android/IOS通用拆分方式的方法,希望对不同业务的项目能提供一些有用的思路。</p>
<blockquote>
<p>在实际的工程实践中,我们抛弃了UE自带的包拆分方案,基于<a href="https://imzlp.com/posts/17590/">HotPatcher</a>框架实现了一套灵活的包拆分方案,详见文章:<a href="https://imzlp.com/posts/37036/">资源管理:重塑 UE 的包拆分方案</a>。</p>
</blockquote>
UE热更新:基于HotPatcher的自动化流程
https://imzlp.com/posts/10938/
2021-01-24T12:47:34.000Z
2021-01-24T12:47:34.000Z
<p><a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>是我之前开源的一个UE4热更新版本管理和资源打包工具,可以方便地进行版本间的差异分析和pak打包。之前的文章为了直观地介绍都是基于手动地在编辑器中进行配置和打包的,在真正的工程实践中,可以自动化的重复操作就要避免手动的参与,较早之前我就在插件中添加了commandlet的支持,近期修复了一些问题以及增加了很多针对commandlet的优化,本篇文章是基于HotPatcher的自动化热更新流程的工程实践。</p>
对开源的一些思考与想法
https://imzlp.com/posts/8890/
2020-12-18T22:21:02.000Z
2020-12-18T22:21:02.000Z
<p>开源,不仅仅只是需要把代码开放那么简单,而是怎么样用自己的代码去解决实际的需求、进行不断地迭代更新、以及构建开源项目的交流社区。根据过去一两年的开源经历,聊一聊我从开发者角度思考开源的观点以及对开源行为的一点想法。</p>
UE反射实现分析:C++特性
https://imzlp.com/posts/23694/
2020-12-13T19:39:37.000Z
2020-12-13T19:39:37.000Z
<p>在前一篇文章中,介绍了UE的反射的基础概念,这篇文章开始研究UE的反射机制的具体实现。</p>
<p>在介绍UE的代码之前,需要先要介绍一些C++特性,虽然UE的反射实现是大量依赖UHT的代码生成的,但是也需要C++的语法特性支持,只有把这些特性还有它们背后的含义了解清楚,才能够更好地理解UE的反射机制。</p>
<p>本篇文章中介绍的C++的特性和标准描述均基于<code>ISO/IEC 14882:2014</code>,也就是C++14标准。</p>
UE反射实现分析:基础概念
https://imzlp.com/posts/12624/
2020-12-12T23:56:24.000Z
2020-12-12T23:56:24.000Z
<p><strong>反射</strong>,是指程序在运行时进行自检的的能力,在编辑器的属性面板、序列化、GC等方面非常有用。但是C++语言本身不支持反射特性,UE在C++的语法基础上通过UHT实现了反射信息的生成,从而实现了运行时的反射的目的。</p>
<p>在之前的文章中,有一些涉及到UE的构建系统和反射相关的内容。</p>
<p>涉及了UE的构建系统文章:</p>
<ul>
<li><a href="https://imzlp.com/posts/6362/">Build flow of the Unreal Engine4 project</a></li>
<li><a href="https://img.imzlp.com/imgs/zlp/blog/posts/16643/">UE4 Build System:Target and Module</a></li>
<li><a href="https://imzlp.com/posts/20425/">UEC++ 与标准 C++ 的区别与联系</a></li>
</ul>
<p>基于UE的反射机制来做一些奇淫巧技的文章:</p>
<ul>
<li><a href="https://imzlp.com/posts/15049/">UE4:Hook UObject</a></li>
</ul>
<p>UE的反射实现是依赖于构建系统中UHT来执行代码生成的,本篇文章对UE的反射做一个基础概念介绍,后续会花几篇文章完整地介绍UE里反射的实现机制。</p>
2020 Unreal Open Day
https://imzlp.com/posts/11043/
2020-12-05T13:38:15.000Z
2020-12-05T13:38:15.000Z
<p>2020年的Unreal Open Day是在线上直播和技术分会场的形式进行的,很开心参加了今年的UOD活动,我录制了一场UOD的技术视频,也去上海直播现场参加了UOD的颁奖活动,很荣幸也很感谢Epic授予我<strong>杰出社区贡献者</strong>奖项,对我既是认可也是激励,我也会尽力产出更多的技术内容,促进UE社区的发展。</p>
<p>本篇文章做一个简单的记录,把UOD的资料做一下整理,也把我参加UOD的视频、演讲PPT,以及相关的资料做一个总结,还有一些在UOD直播现场拍的照片。</p>
UE:UPL与JNI调用的最佳实践
https://imzlp.com/posts/27289/
2020-11-15T10:45:27.000Z
2020-11-15T10:45:27.000Z
<p>在使用UE4开发Android时,有时需要获取平台相关的信息、或者执行平台相关的操作,在这种情况下,需要在代码中添加Java的代码以及在C++中调用它们。有些需求也需要在游戏中从Java侧接收一些事件,需要处理Java调用C++的流程。</p>
<p>本篇文章主要涉及以下几部分内容:</p>
<ul>
<li>UE工程中添加Java代码</li>
<li>Java函数的签名规则</li>
<li>Java调用C++的函数</li>
<li>C++调用Java的函数</li>
</ul>
<p>如何利用UE的UPL特性、Java的签名规则,以及在UE中进行JNI调用实现方法,会在文章中做详细的介绍。</p>
UE:Hook UObject
https://imzlp.com/posts/15049/
2020-11-08T22:35:37.000Z
2020-11-08T22:35:37.000Z
<p>Hook是一种机制,通过拦截和勾取一些事件来实现自己需求的方式。不同于传统的底层Hook,本篇文章主要介绍在UE中如何使用类似Hook的这种机制来实现业务需求。</p>
<p>有些需求是要全局地修改某个类的所有对象,比如在UI中为某种类型的的Button播放统一的音效,如果在每个控件都需要监听它的OnClicked再去播放音效,会有大量的重复操作。所以,我想要找一种全局的方法,可以监听所有UButton的点击事件,然后统一来处理。再或者想要控制一个在蓝图中不可见的属性,如果只是一些简单的需求就要去修改引擎的代码,有点得不偿失。</p>
<p>可以通过UE的反射机制来实现这些需求,本篇文章来提供一种思路,做一个简单的实现分析。</p>
BuildGraph:构建支持多平台打包的二进制引擎
https://imzlp.com/posts/11956/
2020-11-08T15:40:19.000Z
2023-10-22T12:35:18.000Z
<p>通常,UE4开发者获取UE4引擎的方式有两种:</p>
<ol>
<li>从Epic Games Launcher安装</li>
<li>从Github上Clone代码本地编译</li>
</ol>
<p>从EpicGamesLauncher安装的是公版引擎,不能修改代码重新编译,可以在根据选择安装支持的平台、调试符号等。<br>自己从Github上Clone代码进行编译的则是源码版引擎,有些功能只能在源码版中使用(比如Standalone Application),但是如果在项目中修改了引擎的代码,导致每个人都需要Clone一遍源码编译一遍引擎,这个过程十分耗时,而且源码版引擎的占用的磁盘空间十分巨大,达到上百G。在当需要把引擎部署到多台构建机时,编译引擎的时间和空间是冗余的,所以需要通过一台机器编译引擎,然后其他的机器只需要拉取编译后的引擎即可,实现与安装版引擎一样的行为。</p>
<p>本篇文章主要介绍BuildGraph的工作流程,以及对引擎默认构建脚本<code>InstalledEngineBuild.xml</code>的分析;如何使用BuildGraph从源码配置、编译并导出支持Android/IOS打包的二进制引擎、以及如何裁剪和加速整个的构建流程。</p>
二零二零:下一个五年计划
https://imzlp.com/posts/27392/
2020-10-25T12:18:58.000Z
2020-10-25T12:18:58.000Z
这是一篇加密文章,请输入密码后阅读。
UE工具集:我的开源项目介绍
https://imzlp.com/posts/21696/
2020-10-11T10:33:56.000Z
2020-10-11T10:33:56.000Z
<p>工欲善其事必先利其器,本文主要介绍在我在使用UE的过程中开发的一些开源的工具和插件,能够方便地在项目中使用,提高开发效率。之前简单罗列在<a href="https://imzlp.com/resources/">资源</a>页面里,今天做一个详细的整理,对各个工具、插件做一些介绍。</p>
如何构建自己的知识体系?
https://imzlp.com/posts/29551/
2020-10-10T10:08:52.000Z
2020-10-10T10:08:52.000Z
<p>学习如逆水行舟,不进则退。这一点在CS领域尤甚,新技术、新框架日新月异地发展,业务层面的技术迭代非常快,可能刚熟悉了一项技术,很快就又被淘汰了。所以只有不停地接触、了解和学习新的知识和技能才能不断地拓展自己的程序生涯。<br>本篇文章是我写博客几年的对平时技术积累进行的一些思考,本来当作<a href="/notes">notes</a>改版的记录,现在觉得抽离出来当作单独的文章也比较合适,我很少写感悟类的东西,觉得方法论太虚,但是如果具有理论指导行动的自制力,方法论也是很有必要的,希望自己也能做到。</p>
UE集成WWise:概念与代码分析
https://imzlp.com/posts/9809/
2020-09-12T15:31:46.000Z
2020-09-12T15:31:46.000Z
<p><a href="https://www.audiokinetic.com/zh/products/wwise/">WWise</a>是Audiokinetic的跨平台音频引擎,可以与游戏引擎很好地进行交互,负责音频的同事可以只在WWise中处理音频,把游戏业务和音频的制作与管理分离,提供事件和参数给游戏引擎使用,实现与业务的解耦和对音频更精确的控制。<br>本篇文章主要介绍WWise与UE4的集成、远程构建、资源分析、文档收录,WWise与UE的控制交互以及Bank生成的代码分析。</p>
UE导入图集:TexturePacker
https://imzlp.com/posts/28513/
2020-09-11T15:53:22.000Z
2020-09-11T15:53:22.000Z
<p>在开发游戏时,会使用到大量的图片资源,使用图集的作用在于减少 DrawCall,提高性能。在UE中没有图集的打包工具,比较流行的方案是使用第三方的图集打包工具<a href="https://www.codeandweb.com/texturepacker">TexturePacker</a>。新版本的TexturePacker支持直接导出UE4的Sprite,并且可以在引擎中直接导入。在之前的版本中可以使用<a href="https://github.com/ufna/VaTexAtlas">VaTexAtlas</a>通过Json Array的数据导入,不过与TexturePacker直接导出UE的Sprite相比,VaTexAtlas并没有优势,UE的Sprite还可以直接预览,VaTexAtlas则不可以,在官方已经支持的情况下不建议再使用VaTexAtlas作为UE导入图集的方式。</p>
<p>本篇文章主要内容是记录TexturePacker图集生成文件的分析、导入UE、选项介绍、以及记录在UE中使用遇到的问题。</p>
UE开发笔记:Mac/iOS篇
https://imzlp.com/posts/1948/
2020-09-01T21:45:03.000Z
2023-09-08T09:47:17.000Z
<p>本篇文章的主要内容是介绍UE在Mac上的开发环境部署、配置iOS远程出包、UPL在iOS上的应用(介入ipa出包过程)、工具和开发技巧、以及分析相关的引擎代码等内容,记录了一些在项目中遇到的坑,主要从我之前的<a href="https://imzlp.com/notes">笔记</a>中整理而来,后续Mac和iOS相关的内容也都会更新到这篇文章里。</p>
UE热更新:需求分析与方案设计
https://imzlp.com/posts/17371/
2020-05-16T11:22:35.000Z
2020-05-16T11:22:35.000Z
<p>游戏热更新是在玩家不重新安装游戏的前提下获取最新游戏内容的方式,在PC和移动端的网络游戏中有很多应用,因为游戏上上线后要快速调整、修复bug、更新内容等等。如果每修改一点点内容都需要玩家去AppStore更新应用,甚至去网站手动下载再安装,而且不同的平台对于游戏的审核规则和反馈时间也不一致,运营也会疯掉。</p>
<p>在其他引擎中的热更应该有比较成熟的方案,但是在UE里还没看到有比较全面的文章来讲UE4的热更实现的文章,恰好之前分析和实现了UE4热更的内容,准备写两篇文章来记录一下思路和实现方案,并会实现一个可以运行的Demo,希望能对有需要的朋友一点帮助。</p>
<p>为了方便地统一收集和管理热更新和HotPatcher常见的问题与解决方案,我新建了一篇文章来记录和整理:<a href="https://imzlp.com/posts/16895/">UE4热更新:Questions & Answers</a>,遇到问题可以先去看这个FAQ页面。</p>
ModularFeature:为UE4集成ZSTD压缩算法
https://imzlp.com/posts/8470/
2020-04-20T21:52:56.000Z
2020-04-20T21:52:56.000Z
<p>UE在打包时默认使用<code>Zlib</code>作为资源的压缩算法,但是从压缩率和解压速度来看它并不是最好的选择,可以从<a href="https://quixdb.github.io/squash-benchmark/">Squash Compression Benchmark</a>去看各种压缩算的效率对比,我选择了facebook开源的<a href="https://facebook.github.io/zstd/">ZStandard</a>作为替换Zlib的压缩实现,因为ZSTD在保证压缩比的同时还具有不错的解压效率。<br>本篇文章并不只是讲怎么在UE里集成一个压缩算法,还会简单介绍一下UE里的一些功能的模块化组织方式——<code>ModularFeature</code>,使用这种方式可以比较方便地替换某些功能的实现,本文中的替换压缩算法是一个实践。</p>
<p>我在UE中集成<a href="https://facebook.github.io/zstd/">ZSTD</a>的方式是写了一个插件,源码集成,开源在Github上:<a href="https://github.com/hxhb/ue-zstd">hxhb/ue-zstd</a>,支持Android和Windows、IOS以及MacOS,欢迎Star。</p>
UE热更新:基于UnLua的Lua编程指南
https://imzlp.com/posts/36659/
2020-03-24T10:50:17.000Z
2021-06-22T11:08:09.000Z
<p>UE使用的是C++这种编译型语言,在编译之后就成了二进制,只有通过玩家重新安装才能打到更新游戏的目的。但是对于游戏业务而言,对于需求调整和bug修复时间要求非常迫切,频繁地让玩家更新App是不能接受的,游戏项目一般使用Lua作为游戏业务的脚本语言,是为了把运行时不可变的C++代码变成运行时可更新的Lua代码。</p>
<p>UE官方没有提供Lua的支持,但是腾讯开源了<a href="https://github.com/Tencent/UnLua">UnLua</a>,在我当前的项目使用了,这两天我梳理了一下UnLua的资料(主要是官方文档、issus、宣讲PPT),加上自己测试UnLua写了一个小Demo的感悟,形成了本篇UE结合UnLua的编程指南,主要是总结使用UnLua来写业务的一些基本方法和坑,方便查看,本篇文章会持续更新。</p>
<blockquote>
<p>另外,Lua文件打包成Pak可以用我之前开源的工具:<a href="https://github.com/hxhb/HotPatcher">hxhb/HotPatcher</a>,而且我基于UnLua自己修改了一个版本,添加了一些额外的优化,源码集成了<a href="https://github.com/diegonehab/luasocket">Luasocket</a>/<a href="https://github.com/Tencent/LuaPanda">Luapanda</a>/<code>lpeg</code>/<code>Sproto</code>/<code>Luacrypt</code>库,可以直接使用<a href="https://github.com/Tencent/LuaPanda">LuaPanda</a>调试,Github地址为:<a href="https://github.com/hxhb/debugable-unlua">hxhb/debugable-unlua</a>.</p>
</blockquote>
UEC++与标准C++的区别与联系
https://imzlp.com/posts/20425/
2020-02-11T11:22:44.000Z
2020-02-11T11:22:44.000Z
<p>受<a href="https://g.co/kgs/oevWTp">新冠病毒(COVID-19)</a>影响,整个春节都禁足在家,目前还没有复工,只能看看书整理一下笔记,希望疫情尽快过去,希望朋友们都身体健康。<br>本篇文章的主要内容是分析一下在使用UE开发时使用的C++和**标准C++**在语法上有哪些区别,UEC++本质是C++的一个超集,它支持和使用C++的全部特性,但是它在标准特性之上自己构建了一套语法。很多开发中的编译问题只有知道了两者的边界,才能够快速和准确地定位问题出现在哪个阶段。对于使用UE之前就学习过C++的来说这不是什么问题,但是对于先接触UE然后慢慢学C++的同学来说,这是个挺大的问题。</p>
<p><strong>标准C++**是基于</strong>ISO/IEC 14882**的语言规范(C++98/03/11/14/17等标准),UEC++则是我们开发当中使用的Epic在标准C++之上扩展的用法,这里不讨论GC、反射之类的基于C++之上自己构建的对象体系,也不涉及UE中的各种库,关注的着重点在于核心语法层面。</p>
UE源码分析:修改游戏默认的数据存储路径
https://imzlp.com/posts/20367/
2020-01-22T09:10:02.000Z
2020-01-22T09:10:02.000Z
<p>默认情况下,使用UE打包出游戏的Apk并在手机上安装之后,启动游戏会在<code>/storage/emulated/0/UE4Game/</code>下创建游戏的数据目录(也就是内部存储器的根目录下)。按照Google的规则,每个APP的数据文件最好都是放在自己的私有目录,所以我想要把UE打包出来的游戏的数据全放到<code>/storage/emulated/0/Android/data/PACKAGE_NAME</code>目录中(不管是log、ini、还是crash信息)。<br>一个看似简单的需求,有几种不同的方法,涉及到了UE4的路径管理/JNI/Android Manifest以及对UBT的代码的分析。</p>
UE资源热更打包工具HotPatcher
https://imzlp.com/posts/17590/
2020-01-15T09:41:30.000Z
2020-08-31T17:27:31.000Z
<p><strong>重要通知:作者没有任何平台和渠道录制收费课程,也不对任何第三方的商业行为背书。请擦亮双眼,谨防上当受骗。</strong><br><strong>本软件的开源协议:允许在商业项目中免费使用功能,但不允许任何第三方基于该插件进行任何形式的二次收费,包括但不限于录制收费课程、对插件及代码的二次分发等。</strong></p>
<p><a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>是一个用于管理热更版本和资源打包工具,用于追踪工程版本的原始资源变动来打出Patch。支持一键Cook多平台,一键打包多平台Patch,编辑器支持Windows和MacOS,再写一套从服务器下载patch的流程就是一套完整的游戏热更方案。<a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>已经在非常多的UE项目中使用,并会持续更新支持新的引擎版本,欢迎提issus。</p>
<p><a href="https://github.com/hxhb/HotPatcher">HotPatcher</a>与UnrealFrontEnd中的Patch机制不同,UE的Patch管理工程时存在一些问题:基于原始的的工程版本,很难在不同的电脑上打出完全相同的Patch,也无法基于Patch的版本再打出一个Patch,并且Patch包含的内容不能够直观预览。并且不能方便地能够把外部文件打包到pak中(如lua文件、db等non-assets,往往不在Content目录下),也无法方便地管理工程和Patch版本。</p>
<p>这个插件就是为了解决这样的问题,以项目原始资源作为版本依据,只需管理工程本身而无需关注UE生成的其他文件。并且可以方便地进行Cook/生成Pak/提取基础包中的资源信息/版本间diff/Patch拆分等操作。具有非常丰富的配置化选项与Commandlet支持,可以非常方便地实现自动化热更新出包流程。</p>
<blockquote>
<p>目前支持的引擎版本为UE4.21-UE5,并对IoStore机制提供了支持!有很多朋友私信来问插件相关的问题,我创建了个群来讨论UE热更新和HotPatcher插件的问题(QQ群958363331),欢迎加入交流UE相关的技术。</p>
</blockquote>
<p>为了方便地统一收集和管理热更新和HotPatcher常见的问题与解决方案,我新建了一篇文章来记录和整理:<a href="https://imzlp.com/posts/16895/">UE4热更新:Questions & Answers</a>,遇到问题可以先去看这个FAQ页面。关于比较多人反馈插件内配置参数与之前的录制视频不一致的问题,是因为插件进行了很多更新迭代,每个版本的详细变动,可看<a href="https://imzlp.com/posts/17590/#Update-Log">更新日志</a>。</p>
UE项目的设计规范和代码标准
https://imzlp.com/posts/25915/
2020-01-01T11:55:16.000Z
2020-01-01T11:55:16.000Z
<p>最近新开了项目,大概总结了之前项目的一些问题,列举了一些UE开发项目的设计规范和代码标准(代码标准这个词看起来太严肃了,写代码的习惯是一个比较主观的概念,其实叫代码约定更好,但是在组内推广还是要有严格执行的要求)。本篇文章会持续更新和整理,欢迎指出问题和交流意见。</p>
成为虚幻商城的内容创作者
https://imzlp.com/posts/1927/
2019-12-08T22:49:19.000Z
2019-12-08T22:49:19.000Z
<p>上周我把之前写的一个插件<a href="https://www.unrealengine.com/marketplace/en-US/slug/exportnavigation">ExortNavigation</a>上架了虚幻商城,熟悉了一下UE代码插件的提交流程,在此记录一下。</p>
Export Recast Navigation Data from UE4
https://imzlp.com/posts/20203/
2019-11-01T09:18:13.000Z
2019-11-01T09:18:13.000Z
<blockquote>
<p>最新版本已支持UE5,详见github的UE5.0分支:<a href="https://github.com/hxhb/ue4-export-nav-data/tree/UE5.0">ue4-export-nav-data/tree/UE5.0</a>。</p>
</blockquote>
<p><a href="https://github.com/recastnavigation/recastnavigation">Recast Navigation</a>是一个开源的游戏导航/寻路引擎,可以为游戏中的AI提供寻路计算。UE和Unity都是集成了RecastNavigation来为游戏提供导航和寻路计算(当然是修改过的版本),UE的模块<code>NavigationSystem</code>以及<code>NavMesh</code>中可以看到相关的代码实现。<br>最近有个需求是要将客户端的地图信息导出给非UE网络架构的服务端,用于在服务器上对玩家位置的校验,想到可以把客户端的生成的导航数据导出作为客户端世界的<strong>地图</strong>,所以折腾了一下写了一个UE的插件(开源在Github上:**<a href="https://github.com/hxhb/ue4-export-nav-data">ue4-export-nav-data</a><strong>)实现了</strong>直接**将UE生成的导航数据导出,有兴趣的可以直接去看具体的代码。<br>根据导出的导航数据可以完整地在非UE网络架构的服务端上实现基于<a href="https://github.com/recastnavigation/recastnavigation">Recast Navigation</a>的寻路计算,而且与UE无缝衔接。</p>
<blockquote>
<p>**2019.12.04 Update:**本插件已上架虚幻商城,购买链接<a href="https://unrealengine.com/marketplace/en-US/slug/exportnavigation">ExportNavigation</a>,为了程序员情怀支持开源,所以该项目在Github上的开源仓库不会关闭,但基本不会更新,如果该插件对你有用,欢迎在商城购买支持作者。</p>
</blockquote>
Oculus Quest Development with UE4
https://imzlp.com/posts/30042/
2019-09-24T10:41:10.000Z
2020-09-17T21:31:19.000Z
<p><a href="https://www.oculus.com/quest/">Oculus Quest</a>是Oculus发布的新一代支持6DoF的VR一体机设备,不需要连接PC以及额外的定位基站,而且支持Guardian,当戴着头显走出定位边界时,头显中会立即显示现实中的画面,防止玩家误碰出现意外情况。<br><a href="https://www.oculus.com/quest/">Oculus Quest</a>使用两个<code>Pentile OLED</code>的屏幕,单眼分辨率为<code>1440x1600</code>,刷新率为<code>72Hz</code>,使用的是<code>arm</code>架构的高通骁龙835处理器,与两年前的Android旗舰级的处理器相同(如小米6、三星S8)。<br>Quest使用的是<code>Oculus Insight</code>(inside-out tracing)定位方案,使用四枚摄像头进行位置追踪,分别位于头显面板的四角。<br>发布会时对Oculus Insight的介绍:<a href="https://www.youtube.com/watch?v=2jY3B_F3GZk">Oculus Insight VR Positional Tracking System (Sep 2018)</a></p>
<p>以及国外的一个老哥对Quest追踪范围的测试视频:<a href="https://drive.google.com/file/d/1-bqNmwUi8J57yykxLP6szgiLeU3IgdgL/view">Quest Distance Test</a>.</p>
<p><code>Oculus Quest</code>64G存储版本的售价为399刀,128G的为499刀,不计税的价格大概是3500;相比较HTC的同类新产品(HTC Vive Focus)是便宜了不少,与PC-Base VR相比那就更具优势了,还不需要一台高性能的主机,我觉得6DoF的VR一体机设备一定是未来的趋势!</p>
<blockquote>
<p>国庆前的OC6,Oculus发布了Oculus Link和finger tracking两项技术,十分厉害,十分看好。</p>
</blockquote>
<p>整套Quest设备的大小与<code>10.5</code>寸的iPad差不多,提个小包就能带走:<br><img src="https://img.imzlp.com/imgs/zlp/blog/posts/30042/20190925000314.webp"></p>
<p>Quest设备的参数细节不再多说,本篇文章的主要内容是使用UE来开发Quest项目时的环境部署、开发文档、调试工具以及额外的注意事项,会持续更新。</p>
UE Build System:Target and Module
https://imzlp.com/posts/16643/
2019-09-12T13:14:22.000Z
2019-09-12T13:14:22.000Z
<p>Module是构成Unreal的基本元素,每一个Module封装和实现了一组功能,并且可以供其他的Module使用,整个Unreal Engine就是靠各个Module组合驱动的,连我们创建的游戏项目本身,都是一个单独的Module。</p>
<p>那么UE又是怎么创建和构建这这些Module的呢?这是写这篇文章的主要目的,研究一下Unreal的构建系统以及它们(Target和Module)支持的各种属性。</p>
<p>建议在看这篇文章之前先看一下我之前的这篇文章:<a href="https://imzlp.com/posts/6362/">Build flow of the Unreal Engine4 project</a>,主要内容是大致过一遍UE的构建流程,本篇文章只是UE构建系统中的一环。</p>
UE工具链配置与开发技巧
https://imzlp.com/posts/12143/
2019-09-09T23:32:08.000Z
2019-09-09T23:32:08.000Z
<p>工欲善其事,必先利其器!掌握好的工具会使开发效率上一个层次。<br>本文是我平时记录在<a href="https://imzlp.com/notes">notes</a>中关于UE工具链以及一些组合UE使用的工具配置和使用技巧的笔记整理,后续这方面的内容也会收录到这篇文章中。<br>下面是我之前写的关于UE工具链或扩展相关的单独的文章:</p>
<ul>
<li><a href="https://imzlp.com/posts/9050/">分析UBT中EULA的内容分发限制</a></li>
<li><a href="https://imzlp.com/posts/31962/">Create A Standalone Application in UE4</a></li>
<li><a href="https://imzlp.com/posts/6362/">Build flow of the Unreal Engine4 project</a></li>
<li><a href="https://imzlp.com/posts/11515/">抓取UE4 API并生成带索引的Dash文档</a></li>
</ul>
分析UBT中EULA的内容分发限制
https://imzlp.com/posts/9050/
2019-08-24T14:15:36.000Z
2019-08-24T14:15:36.000Z
<p>UE的<a href="https://www.unrealengine.com/en-US/eula">EULA</a> <strong>License Grant/(A)</strong> 中明确说明了,使用UE开发并再分发的内容不得包含 <strong>未Cook的源格式</strong> 和基于 <strong>引擎工具</strong> 开发的付费内容,本篇文章研究一下EULA里对内容分发的具体内容和从技术上怎么绕过这个限制。</p>
PixelStreaming:基本概念与上手初探
https://imzlp.com/posts/9455/
2019-07-30T17:48:27.000Z
2019-07-30T17:48:27.000Z
<p>PixelStreaming是UE_4.21开始支持的一项技术,简单来说就是能够将游戏跑在服务器上,你可以通过浏览器来玩,玩家端不需要额外操作,只需要一个浏览器,所有的逻辑处理和渲染都在“云”端执行。它不仅仅只是一个插件(虽然有PixelStreamingPlugin这个插件,但它只是<strong>PixelStreaming</strong>实现中的一环),其实现具有一套独立与UE游戏的设计和组织方式。<br>本篇文章主要介绍PixelStreaming中的基本概念和使用PixelStreaming的Demo的实际体验。</p>
UE Modules:Find the DLL and load it
https://imzlp.com/posts/31203/
2019-07-16T18:23:29.000Z
2019-07-16T18:23:29.000Z
<p>在Windows上,UE的模块在非<code>IS_MONOLITHIC</code>(打包成一个单独的可执行文件的<strong>单片模式(Monolithic)</strong>)模式下,是通过查找DLL来加载模块的。可以调用<code>FModuleManager</code>下的<code>LoadModuleWithFailureReason</code>/<code>LoadModuleChecked</code>等函数,通过传入Module的字符串名字来加载。<br>本篇文章算是<a href="https://imzlp.com/posts/24007/">UE4 Modules:Load and Startup</a>的扩展和补充,与之不同的是,这篇文章的<strong>侧重点</strong>在于Module的DLL的查找和加载的细节<strong>而不是</strong>引擎启动和加载Module的时机和顺序。</p>
UE接入SteamSDK及相关资料
https://imzlp.com/posts/3231/
2019-05-27T23:02:17.000Z
2019-05-27T23:02:17.000Z
<p>游戏上架<a href="https://store.steampowered.com/">Steam</a>必须要接入<a href="https://partner.steamgames.com/doc/sdk">SteamSDK</a>,本篇文章简单介绍一下在UE4中接入<a href="https://partner.steamgames.com/doc/sdk">SteamSDK</a>的方法,后续与接入Steam平台服务相关的内容也会放到这篇文章中。</p>
<blockquote>
<p>SteamSDK的接入可以使游戏与Steam的社区整合,Steam拥有很好的社区生态,这一点是Epic刚出的<a href="https://www.epicgames.com/store/e/en-US/">Epic Games Store</a>目前比不了的~(当然我是支持市场竞争的。</p>
</blockquote>
UE代码分析:GConfig的加载
https://imzlp.com/posts/2386/
2019-05-27T22:57:58.000Z
2020-05-28T18:02:53.000Z
<p>UE4中提供了一套非常成熟的INI文件配置机制,引擎中也使用了ini作为引擎和项目的配置文件。本篇文章来简单分析一下引擎中GConfig的加载。</p>
UE开发的问题笔记和资料辑录
https://imzlp.com/posts/25331/
2019-05-27T22:07:50.000Z
2019-05-27T22:07:50.000Z
<p>在平时的开发和学习中遇到和解决的一些问题以及摘录的一些资料,都随手写在了<a href="https://imzlp.com/notes/">notes</a>中,UE相关的积攒了不少,其他的混在一起比较混乱,整理到本篇文章中。<br>与<a href="https://imzlp.com/posts/3380/">UE4和VR开发技术笔记</a>不同的是,这里的内容更偏向于项目中实际的问题记录和资料收集。</p>
HTC Vive Tracker Developer Guide
https://imzlp.com/posts/2125/
2019-04-03T11:41:23.000Z
2019-04-10T09:42:32.000Z
<p>HTC发布的Vive配件<a href="https://www.vive.com/us/vive-tracker/">Vive Tracker</a>可以用来扩展与SteamVR连接的设备。而且还具有Pogo引脚,可以自己DIY出特殊功能的配件,最近看到了一些使用<a href="https://www.vive.com/us/vive-tracker/">Vive Tracker</a>来实现的非常棒的创意。相关的资料和技术细节在本篇文章里整理辑录。</p>
Create A Standalone Application in UE4
https://imzlp.com/posts/31962/
2019-03-30T18:14:46.000Z
2020-03-18T14:10:55.000Z
<p>虽然UE是个<strong>游戏引擎</strong>,但并不是只能写游戏——你甚至可以用来写Win32 GUI程序😏.<br>通常,我们使用Editor创建一个UE的游戏项目,然后在其基础上构建自己的类并在游戏中使用。但是如果不想要创建一个游戏项目,UE也支持可以独立运行的程序(Standalone Application),能够从<code>main</code>函数来自主构建自己的程序,完全控制启用哪些Modules,而不依赖于引擎本身的逻辑架构,也可以将其作为学习和测试UE模块的轻便方法。</p>
<blockquote>
<p><strong>注</strong>:UE并没有提供直接创建Standalone Application的方法,我自己写了一个创建<code>Program</code>项目的工具:<a href="https://github.com/hxhb/ue4program">hxhb/ue4program</a>,并实现了一个独立运行工具的Demo:<a href="https://github.com/hxhb/UE4Launcher">hxhb/UE4Launcher</a>。</p>
</blockquote>
LaTeX数学符号速查表
https://imzlp.com/posts/23224/
2019-03-22T00:27:13.000Z
2019-03-22T11:25:15.000Z
<p>最近读<a href="https://book.douban.com/subject/30426701/">龙书DX12</a>会用到LaTeX来记录一些公式。为了方便查找,整理了一些常用的LaTeX数学符号语法表,更多符号可以看<a href="https://artofproblemsolving.com/wiki/index.php/LaTeX:Symbols">LaTeX:Symbols</a>。</p>
引擎源码分析:模块的加载和启动
https://imzlp.com/posts/24007/
2019-03-19T11:11:57.000Z
2019-03-30T15:38:27.000Z
<p>UE是模块化的架构,Engine/Game Project/StandaloneApplication/Plugins都是Module(<a href="http://api.unrealengine.com/INT/API/index.html">Unreal Engine API Reference</a>列出了Engine提供的Module列表),本篇文章从<code>FModuleManager</code>的代码来分析一下UE的Module是如何通过<code>FModuleManager::LoadModule</code>加载和启动的。</p>
Build flow of the Unreal Engine4 project
https://imzlp.com/posts/6362/
2019-03-16T23:09:52.000Z
2019-09-16T19:01:45.000Z
<p>UE通过UBT来构建项目(不管是VS里的Build也好,Editor里的Compile也好,最终都会调用UBT)。UBT和UHT是UE工具链的基石,内容太多,没办法一次性分析全部,先梳理出一个大致的轮廓,有时间再慢慢补充。</p>
C++多态与虚函数表
https://imzlp.com/posts/25558/
2019-02-26T13:36:47.000Z
2019-02-27T11:47:32.000Z
<p>C++是一门支持面向对象编程(object-oriented Programming)的语言,继承和多态(Polymorphic)是其最重要的特性。<br>关于C++的继承和类内成员的各种内容在之前的文章中已经有了不少介绍,本篇文章主要是研究一下编译器对C++多态的一个实现方式:<strong>虚函数表</strong>。<br>C++标准(<strong>[IOS/IEC 14882:2014]</strong>)中写道:</p>
<blockquote>
<p>Virtual functions support dynamic binding and object-oriented programming. A class that declares or inherits a virtual function is called a polymorphic class.</p>
</blockquote>
<p>注意:<strong>C++标准并没有规定如何实现多态</strong>,所以编译器对多态的实现是<code>Implementation-defined Behavior</code>,意思就是不同的编译器可能对多态的实现是不一样的,在<strong>不同的平台可能会无法得到相同的实验结果</strong>。</p>
UE Package Error:ObservedKeyNames.Num()>0
https://imzlp.com/posts/359/
2019-01-17T09:50:36.000Z
2019-01-17T09:50:36.000Z
<p>最近项目打包时遇到一个非常奇怪的错误:</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// package log</span><br><span class="line">Ensure condition failed: ObservedKeyNames.Num() > 0 [File:D:\Build\++UE4+Release-4.18+Compile\Sync\Engine\Source\Runtime\AIModule\Private\BehaviorTree\Decorators\BTDecorator_BlueprintBase.cpp] [Line: 67]</span><br></pre></td></tr></table></figure>
<p><img src="https://img.imzlp.com/imgs/zlp/blog/posts/359/ue-package-error-ObservedKeyNames-Num.png"><br>我调试了一下UE4的代码,分析了一下原因和解决过程。</p>
Macro defined by UBT in UE4
https://imzlp.com/posts/5214/
2019-01-09T18:17:35.000Z
2019-01-09T18:17:35.000Z
<p>UE4引擎里面定义了很多引擎中的宏和一些处理逻辑,如<code>WITH_ENGINE</code>/<code>WITH_EDITOR</code>等,它们部分是UBT通过读取<code>*.target.cs</code>文件中的配置来定义的,有些逻辑是通过读取<code>*.Build.cs</code>的配置处理的。<br>我读了一下UBT的代码,抽出来部分UBT中配置文件(<code>Target.cs</code>/<code>Build.cs</code>)参数与MACRO的相互定义,作为速查手册。<br><code>*.Target.cs</code>的参数可以看:<a href="https://docs.unrealengine.com/en-US/Programming/BuildTools/UnrealBuildTool/TargetFiles/index.html">UnrealBuildSystem/Targets</a><br><code>*.Build.cs</code>的参数可以看:<a href="https://docs.unrealengine.com/en-US/Programming/BuildTools/UnrealBuildTool/ModuleFiles/index.html">UnrealBuildSystem/ModuleFiles</a><br>UE的构建系统文档:<a href="https://docs.unrealengine.com/en-US/Programming/BuildTools/index.html">Build Tools</a></p>
提取Tor并搭建Tor Bridge
https://imzlp.com/posts/11177/
2018-11-04T19:36:04.000Z
2018-11-05T10:29:09.000Z
<p>Tor的Bridge如果传播的范围比较广,可能隔几天就被和谐掉了,频繁地换有点麻烦(恍惚间让我想到了当年改host上Google的时光)。今天折腾了一下,自己在VPS上搭建tor的Bridge来自用。<br>而且也从<a href="https://www.torproject.org/projects/torbrowser.html.en">Tor Browser</a>里提取出tor,使其不依赖Tor Browser,可以供其他浏览器使用。<br><strong>警告</strong>:部署Bridge<strong>可能</strong>会增加服务器被墙的概率。</p>
动态链接库的使用:加载和链接
https://imzlp.com/posts/18949/
2018-10-15T20:50:34.000Z
2018-10-15T20:50:34.000Z
<p>在部分SDK的对接中,有些平台除了DLL外并没有提供导入库来供我们使用,那就只能使用代码中加载DLL的办法来调用DLL内的函数,本文来记录一下两种用法,再分析一下优劣。</p>
抓取UE API并生成带索引的Dash文档
https://imzlp.com/posts/11515/
2018-07-05T23:43:43.000Z
2021-11-22T10:55:31.000Z
<p>不知为何,<a href="http://api.unrealengine.com/INT/API/index.html">UE API</a>现在已经不随引擎发布chm的离线文档了,官方发布的最新版本还是2014年的,UE发展到现在有了很多变化,显然四年前的API文档已经丧失部分参考价值了。但是UE文档站自身的搜索功能就我的体验而言,十分的烂。<br>所以折腾了一下把UE API的所有页面爬了下来,并且生成了Dash支持的文档,检索起来十分酸爽。(文后附下载链接)</p>
<blockquote>
<p>2022.06.07更新:把API文档更新至UE 5.0.2,可在<a href="#Update">文末</a>下载。。</p>
</blockquote>
使用frp进行内网穿透
https://imzlp.com/posts/5050/
2018-06-09T11:40:09.000Z
2018-11-10T16:19:17.000Z
<p>最近想到还有块树莓派在吃灰,今天使用<a href="https://github.com/fatedier/frp">frp</a>折腾了一下内网穿透,把放在家里的树莓派也可以通过外网访问。</p>
UE和VR开发技术笔记
https://imzlp.com/posts/3380/
2018-06-06T08:16:10.000Z
2019-01-17T14:00:15.000Z
<p>平时随笔写下的一些UE4和VR开发中的技术笔记,以及一些相关资料的收录,之前零零散散放在<a href="https://imzlp.com/notes/">imzlp.com/notes</a>中,今天整理了一下,后续的笔记都会放到这篇文章中。</p>
UE无缝地图:传递Actor到下个关卡
https://imzlp.com/posts/19376/
2018-04-28T00:43:40.000Z
2018-04-28T00:43:40.000Z
<p>因为UnrealEngine在切换关卡(<code>OpenLevel</code>)时会把当前关卡的所有对象全部销毁,但是常常我们需要保存某些对象到下一关卡中,今天读了一下相关的代码,本篇文章讲一下如何来实现。<br>其实Unreal的文档是有说明的(<a href="https://docs.unrealengine.com/en-us/Gameplay/Networking/Travelling">Travelling in Multiplayer</a>),实现起来也并不麻烦,但是UE文档的一贯风格是资料是不详细的,中文资料更是十分匮乏(多是机翻,而且版本很老),在搜索中也没有查到相关的靠谱的东西,我自己在读代码实现的过程中就随手记了一下,就当做笔记了。</p>
Build protobuf with MSVC on Windows
https://imzlp.com/posts/9903/
2018-02-27T10:01:32.000Z
2018-02-27T10:01:32.000Z
<p>最近有在VS中用到Protobuf,简单记录一下使用MSVC构建Protobuf的流程。</p>
反向代理Github Pages启用HTTPS
https://imzlp.com/posts/18841/
2017-09-07T20:49:29.000Z
2018-02-05T13:26:38.000Z
<p>由于<a href="https://pages.github.com/">Github Pages</a>不支持<code>custom domain</code>的HTTPS,今天折腾了一下搞定了在VPS上用<a href="https://nginx.org/en/">Nginx</a>到<a href="https://pages.github.com/">Github Pages</a>的反向代理,使用的是<a href="https://letsencrypt.org/">Let’s Encrypt</a>签发的证书,实现了全站HTTPS(资源外链也都换成了HTTPS),简单记录一下。</p>
为什么不能重载&&与||以及,(comma)?
https://imzlp.com/posts/11306/
2017-06-24T22:21:39.000Z
2017-06-24T22:21:39.000Z
<p>C++的基础语法里提供了<code>||</code>与<code>&&</code>两个逻辑操作符还有<code>,</code>(comma)运算符。在类中我们也可以重载这些操作符,但是不要这样做,我会在这篇文章中写出标准描述以及不能重载的原因。<br>概括来说,因为内置的||和&&具有短路求值语义,如果你自己重载了他们就变成了普通的函数调用,会具有与built-in <code>||</code>与<code>&&</code>完全不同的语义。<br>而,操作符具有从左到右求值的语义,所以如果自己重载,会变成函数调用,也会具有不同于built-in的语义。</p>
C++模板元编程资料辑录
https://imzlp.com/posts/23043/
2017-06-17T23:21:33.000Z
2017-06-17T23:21:33.000Z
<p>本文主要是我学习模板元编程过程中的一些心得总结,以及我写的一些模板元编程的代码也都会放到这里来。</p>
operator new:void*到T*的转换
https://imzlp.com/posts/21564/
2017-05-22T18:03:33.000Z
2017-05-22T18:03:33.000Z
<p>在C++14标准(C++98/11也一样)中,在<strong>Annex C Compatibility</strong>里有这么一条:</p>
<blockquote>
<p>Change: Converting void* to a pointer-to-object type requires casting</p>
</blockquote>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">char</span> a[<span class="number">10</span>];</span><br><span class="line"><span class="type">void</span>* b=a;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">foo</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="type">char</span>* c=b;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>ISO C will accept this usage of pointer to void being assigned to a pointer to object type. C ++ will not.</p>
</blockquote>
<p>但是为什么<code>operator new()</code>会返回<code>void*</code>且不用显式转换为<code>T*</code>就能赋值给<code>T*</code>呢?</p>
lambda在编译器中实现的方式
https://imzlp.com/posts/19441/
2017-05-17T23:35:54.000Z
2017-05-17T23:35:54.000Z
<p>在C++中<code>lambda-expression</code>的结果叫做<code>闭包对象(closure object)</code>。本篇文章并非是介绍C++ lambda的用法的(这一点《TC++PL》、《C++ Primer》中都十分详细,或者看我之前的总结<a href="https://imzlp.com/posts/2441/#lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F">C++11的语法糖#lambda表达式</a>),而是从LLVM-IR来分析在Clang中是如何实现<code>lambda-expression</code>的。</p>
访问控制机制的可见性与可访问性
https://imzlp.com/posts/17586/
2017-05-13T10:44:06.000Z
2017-05-13T10:44:06.000Z
<p>在上一篇文章<a href="https://imzlp.com/posts/12080">突破C++类的访问控制机制</a>中简略提到了C++类的成员访问控制(<code>public</code>/<code>protected</code>/<code>private</code>)只是限制了成员名字的<strong>可访问性(accessable)**而非</strong>可见性(visable)**。在这篇文章中主要分析这种性质带来的后果以及如何避免。</p>
突破C++类的访问控制机制
https://imzlp.com/posts/12080/
2017-05-12T11:58:05.000Z
2021-05-24T17:28:06.000Z
<p>众所周知,在C++中类成员能够具有三种访问权限,分别为<code>public</code>/<code>protected</code>/<code>private</code>:<br>[ISO/IEC 14882:2014]A member of a class can be</p>
<ul>
<li><strong>private</strong>: that is, its name can be used only by members and friends of the class in which it is declared.</li>
<li><strong>protected</strong>: that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see 11.4).</li>
<li><strong>public</strong>: that is, its name can be used anywhere without access restriction.</li>
</ul>
<p>从标准意图上来看,是希望隐藏类的实现细节和底层数据,即为<strong>封装</strong>。但是我们也可以通过一些特殊的方式来突破访问权限的限制。</p>
技术书籍书评汇总
https://imzlp.com/posts/15564/
2017-05-06T02:57:42.000Z
2017-05-06T02:57:42.000Z
<p>单独开一篇文章,之前零零散散的书评散落在<a href="https://imzlp.com/notes">笔记</a>和<a href="https://imzlp.com/tweets">微言</a>中,没有具体辑录到一块,不方便索引。以后读过的技术类的书籍之后我会写一些评价就都放到这里来了。因为评价对象是技术书籍,只言片语也不能描述所有的技术细节,本文立意也非“技术笔记”而是“书籍评价”,所以我不会在这里涉及太多书籍中描述的技术细节,只是我作为一个普通读者的阅读感受以及分享我个人的阅读技巧,若其中对某些书透露出褒贬之意均为我个人对书籍的评价无任何贬低作者的意图。</p>
特殊成员函数的隐式声明及其标准行为
https://imzlp.com/posts/21790/
2017-05-04T23:37:05.000Z
2017-05-04T23:37:05.000Z
<p>在C++编程中比较痛恨欲绝的事莫过于:编译器瞒着程序员做了太多事。<br>本篇文章是从C++标准([ISO/IEC 14882:2014])中整理摘录出来的关于编译器生成类的<code>默认构造函数(default constructor)</code>/<code>拷贝/移动构造函数(copy/move constructor)</code>/<code>拷贝/移动赋值操作符(copy/move assignment operator)</code>/<code>析构函数(destructor)</code>这六个特殊成员函数的几种情况以及其实际行为的文档。可以作为《Inside The C++ Object Model》的辅助资料,组合观看效果更佳(通过标准描述来理解编译器的实现)。<br>另外,《Inside The C++ Object Model》主要是从“编译器实现”的角度来描述的,但是从“C++标准”的角度来看,书里很多是依赖于编译器实现的,就像虚函数表,标准并没有规定编译器应该用何种方式实现多态行为,自然也就不可能描述关于虚函数表的东西。<br>还有很多对于“编译器生成”的行为在主观意识中带有歧义的理解,都可以在这里找到解答,这也是读C++标准的乐趣所在——不论好坏,标准<strong>规定</strong>不会出错,所有不符合标准描述的实现都是unstandard的。</p>
函数模板的特化和重载
https://imzlp.com/posts/10380/
2017-05-04T00:20:56.000Z
2017-05-04T00:20:56.000Z
<p>不同于类模板,可以具有显式特化和局部特化(partial specializations),函数模板没有”局部特化”的概念,只有显式特化和重载。</p>
C++中指向类成员的指针并非指针
https://imzlp.com/posts/27615/
2017-04-29T21:28:17.000Z
2019-04-22T00:38:56.000Z
<p>“指向类成员的指针(Pointers to members)”,是一种在C++不常用的特性,但是这里使用术语“指针”略有不妥,因为它们并不包含地址,行为也不像指针。<br>本篇文章会通过LLVM-IR来分析clang中对于“指向类成员的指针”的实现方式,以及穿插C++14标准内定义的相关内容和涉及到的LLVM-IR的语法。</p>
为什么需要extern "C"?
https://imzlp.com/posts/5392/
2017-04-11T22:20:00.000Z
2017-04-24T01:14:08.000Z
<p>在上一篇文章(<a href="https://imzlp.com/posts/27118/">C/C++编译模型分析</a>)中介绍了C和C++中编译和链接的成因和方式。接上篇文章的坑,本篇文章从<code>extern "C"</code>着手分析C和C++编译与链接模型中的不同点及其成因,主要为<code>function overload</code>、<code>function signatures</code>、<code>name mangling</code>三个部分。</p>
C/C++编译和链接模型分析
https://imzlp.com/posts/27118/
2017-04-10T23:05:44.000Z
2017-07-02T00:18:53.000Z
<p>C和C++均使用分离编译来支持多源文件模块化机制,但是为什么这么做以及如何做是个值得探讨的问题。本篇文章并非是讲述C和C++中如何才能产生不同链接的语法规则,而是分析下C/C++编译器是如何实现编译和链接模型的。</p>
Array of length zero
https://imzlp.com/posts/21095/
2017-03-30T19:00:01.000Z
2017-03-31T11:48:43.000Z
<p>看了下在C中<code>Array of length zero</code>的用法,感觉脑洞大开啊。不过从标准角度(非编译器扩展)来说,这个特性只存在于C语言(C99之后),C++中是不存在的。先挖个坑,来分析一下。</p>
虚拟存储器的缺页异常分析
https://imzlp.com/posts/30933/
2017-03-22T01:22:02.000Z
2017-03-22T01:22:02.000Z
<p>考虑这样一个问题:能否通过管道(fifo)从一个进程A向另一个进程B(A和B之间并无亲属关系)中传递A进程中对象的地址,从而在进程B中访问到A进程的对象呢?</p>
STL容器的迭代器失效
https://imzlp.com/posts/3276/
2017-03-17T11:43:47.000Z
2017-03-17T11:43:47.000Z
<p>容器的大小指的是容器中的元素数目;容器的容量指的是重新分配更多内存之前容器能够保存的元素数目。在改变大小或容量时,元素可能会移动到新的存储位置。这意味着指向元素的迭代器(以及指针或引用)可能会失效(即指向旧元素的位置)。<br>指向关联容器元素的迭代器只有当所指元素从容器中删除时(erase)才会失效。与之相反,指向顺序容器元素的迭代器当重新分配空间(<code>resize()</code>/<code>reverse()</code>或<code>push_back()</code>)或指向元素在容器中移动(如在前一个位置进行<code>erase()</code>或者<code>insert()</code>)也会失效。</p>
通过IR代码来分析C++代码语义
https://imzlp.com/posts/20479/
2017-03-08T11:46:55.000Z
2017-03-08T11:46:55.000Z
<p>IR代码是LLVM生成的<code>Intermediate Code</code>。可以通过IR代码来分析编译器对我们所写的代码是如何解析并执行的,使得分析代码语义变得简洁明了。IR代码的语法语义可参考<a href="http://llvm.org/docs/LangRef.html#store-instruction">LLVM Language Reference Manual</a>。</p>
fork/vfork浅谈
https://imzlp.com/posts/2658/
2017-03-06T13:40:08.000Z
2017-03-06T13:40:08.000Z
<p>在*UNIX中可以通过fork/vfork来实现多进程编程,整理总结一下相关的知识。</p>
C/C++中的编程技巧及其概念
https://imzlp.com/posts/1756/
2017-03-05T01:21:25.000Z
2017-04-28T07:53:38.000Z
<p>一些C++中比较能令人迷惑或者用法比较奇特的示例记录。</p>
main原型考证及程序终止行为
https://imzlp.com/posts/15272/
2017-02-27T15:30:09.000Z
2017-02-27T15:30:09.000Z
<p>在C和C++中流传着很多版本的<code>main</code>函数原型,不同的书里也有不同的写法。今天我从几种标准(C89/99/11以及C++98/03/11/14)的角度来寻找一下什么是“<strong>标准行为</strong>”以及在主函数中return后发生了什么。</p>
C和C++之间的不兼容
https://imzlp.com/posts/14446/
2017-02-27T15:25:56.000Z
2017-05-23T10:46:52.000Z
<p>之前提到过数次C和C++并不是一个语言,就算是C++中从C继承来的那部分也和ISO C有很大区别,以后我会逐渐整理一些它们之间不兼容的特性到这里来。</p>
C++中declaration与define的区别
https://imzlp.com/posts/21831/
2017-02-24T21:09:53.000Z
2017-02-24T21:09:53.000Z
<p>看过不少C++的书籍里都没有明确地指出处声明(declaration)与定义(define)的区别,或者只是提到了需要支持分离式编译,使用<code>extern</code> specifier的就是声明,不带的就是定义。实际上我觉得C++标准中对于声明(declaration)与定义(define)的区别描述的更为清晰。</p>
对象的构造和析构顺序
https://imzlp.com/posts/16550/
2017-02-19T18:04:24.000Z
2017-02-19T18:04:24.000Z
<p>通过一道CppQuiz的题来使用C++14标准描述C++的对象在继承情况下构造和析构的顺序,以及在对象构造/析构时抛出异常。</p>
重载(overload)和重写(override)
https://imzlp.com/posts/29726/
2017-02-06T05:08:43.000Z
2017-02-06T05:08:43.000Z
<p>C++中<code>重载(overload)</code>和<code>重写(override)</code>并无关系,但是由于这个词比较相似还是容易搞混的。</p>
Linux上的Samba配置
https://imzlp.com/posts/17347/
2017-02-04T05:29:47.000Z
2017-02-04T05:29:47.000Z
<p>通过Samba我们可以将Linux上的文件夹挂载到Windows上,开台Linux虚拟机部署Samba之后,在Windows就可以使用我前几天写的远程编译插件(<a href="https://imzlp.com/posts/11793/">sublimeRemoteCompile</a>)来写代码啦!还是挺爽的。今天把服务器配置Samba共享文件的方法简单记录一下,方便有同样需求的朋友。</p>
工具、环境的知识收录
https://imzlp.com/posts/16793/
2017-02-03T23:39:14.000Z
2019-01-17T14:15:00.000Z
<p>一些工具、环境配置的一些技巧或者相关的知识概念记录在这里。</p>
SublimeText的远程编译插件
https://imzlp.com/posts/11793/
2017-01-25T01:43:55.000Z
2017-01-25T01:43:55.000Z
<p>经常在Win上写一些跑在Linux上的测试小代码还需要手动在Linux下执行编译命令有些麻烦,而且我用树莓派配置samba将代码共享到Win上也需要ssh上去手动编译,有点浪费时间。<br>这几天闲时写了一个SublimeText的小插件,用来在windows下远程编译C/C++的代码,就是在Windows上写代码但是实际会在Linux上执行。目前只是实现了功能,等放假后休息时有空优化一下。<br>代码放在Github上:<a href="https://github.com/hxhb/sublimeRemoteCompile">sublimeRemoteCompile</a>,使用了一些<code>C++11</code>的特性,编译时需指定。</p>
数组下标访问背后隐含的逻辑
https://imzlp.com/posts/20449/
2017-01-16T00:59:09.000Z
2017-01-16T00:59:09.000Z
<p>对于数组而言,下标运算是随机读写的一种方式,也是最常用的方式。但是有很多教材(尤其是国内教材)一上来就说数组名就是指针,这是不对的。而且对于数组的下标访问背后是有一套规则的,熟悉这些规则可以在一些复杂语义的情况下分析出代码的实际含义。</p>
裹一层重载的成员函数指针
https://imzlp.com/posts/19740/
2016-12-31T04:02:13.000Z
2017-05-15T16:27:14.000Z
<p>使用变长参数模板和lambda(或者使用generic lambda)来裹一层重载的成员函数指针,从而方便使用(bind绑定或者其他需要重载的成员函数指针的地方)。<br>关于<strong>成员函数指针</strong>的更多介绍请看我的另一篇文章:<a href="https://imzlp.com/posts/27615">C++中指向类成员的指针并非指针</a>。</p>
The C++ Object and Memory Model
https://imzlp.com/posts/21843/
2016-12-15T21:11:24.000Z
2016-12-15T21:11:24.000Z
<p>More documentation:<a href="http://en.cppreference.com/w/cpp/language/memory_model">Memory Model</a> and <a href="https://imzlp.com/2016/05/18/about-the-compiler-to-generate-the-default-constructor/">Default Constructor Construction</a>.</p>
关于读书的一些思考
https://imzlp.com/posts/17446/
2016-12-11T20:43:42.000Z
2016-12-11T20:43:42.000Z
<p>如何对一门不熟悉的领域或者书籍划定其中最重要的20%?如何划定细枝末节?<br>之前读书和学习中没有深入思考过这些方法论的东西,觉得方法论只是空谈,但是现在觉得掌握一个合适的技巧如有利刃在手,披荆斩棘方可游刃有余。</p>
读TC++PL、C++Primer和ISO C++
https://imzlp.com/posts/4367/
2016-12-06T23:16:00.000Z
2016-12-06T23:16:00.000Z
<p>花了一个月的时间读完了TC++PL4E,因为我之前读过C++ Primer,C++大部分的语法内容都已了解,所以读的速度还是比较快的,但是通过组合阅读C++标准也发现了很多C++中我原本不知道的东西,从标准和C++之父的视角来看C++确实是足够全面了,由此来对比一下C++ Primer、TC++PL4E和ISO C++文档。</p>
What is POD in C++?
https://imzlp.com/posts/1140/
2016-12-03T00:04:28.000Z
2016-12-03T00:04:28.000Z
<p>POD is Plain Old Data(普通旧数据).在C++中是指能被“仅当作数据”处理的对象,程序员无暇顾及类布局的复杂性以及用户自定义的构造、拷贝和移动语义。</p>
激进的ADL(Argument-dependent lookup)
https://imzlp.com/posts/25788/
2016-11-29T22:39:14.000Z
2016-11-29T22:39:14.000Z
<p>ADL是<code>Argument-dependent lookup</code>的简写,中文译作参数依赖查找。ADL对于避免冗长的代码很有用处,但是也会造成一些歧义。</p>
TC++PL4E中英版勘误
https://imzlp.com/posts/409/
2016-11-20T21:46:53.000Z
2016-11-20T21:46:53.000Z
<p>最近在读The C++ Programming Language Fourth Edition(简称TC++PL4E),由于我入的实体书是中译本(原版好贵),所以我是对照着英文版PDF看的,发现了一些原版和中译本中的勘误,还有一些我觉得书中歧义的地方,查阅标准(ISO/IEC 14882:2014(E))之后的定义也一并贴出,汇总在这里列出来。</p>
C/C++标准的一些摘录
https://imzlp.com/posts/19242/
2016-11-12T01:19:51.000Z
2017-04-05T15:19:57.000Z
<p>C/C++的很多资料网上数不胜数,但是经常会遇到看了一些文章资料后,我觉得作者自己都没彻底明白到底写的是什么(回头看看我以前写的文章也是,那时的眼光太片面和浅显了)。<br>所以对于C/C++的东西我觉得还是要直接来翻标准文档才行,因为标准是不会出现歧义的。不能盲目地只是在网上搜寻并相信别人二次消化过的资料。<br>我认为对于C/C++语言特性的知识,查阅这四份文档就足够了(点击即可在线预览或下载):</p>
<ul>
<li><a href="http://doc.imzlp.com/viewer.html?file=docs/standard/isoc99.pdf">ISO/IEC 9899:1999 (E)</a> (C99标准)</li>
<li><a href="http://doc.imzlp.com/viewer.html?file=docs/clang/TCPL2E.pdf">The C Programming language Second Edition</a> (C语言之父Dennis Ritchie和Brian Kernighan的大作)</li>
<li><a href="http://doc.imzlp.com/viewer.html?file=docs/standard/isocpp2014.pdf">ISO/IEC 14882:2014(E)</a> (C++14标准)</li>
<li><a href="http://doc.imzlp.com/viewer.html?file=docs/cpp/TCPPPL4E.pdf">The C++ Programming Language Fourth Edition</a> (C++之父撰写,依据C++11标准)</li>
</ul>
<p>之所以C语言标准没有依据最新的C11标准是因为目前的C++标准(C++14)的<code>Normative references</code>的C部分是<strong>ISO/IEC 9899:1999</strong>,使用TCPL和TC++PL可以作为C/C++标准的应用性描述,可以相互印证。<br>更多的关于C++<code>Normative references</code>的内容可参照<a href="https://o66j3dueo.qnssl.com/Document/ISOIEC.14882.2014%28C++14%29.pdf">ISO/IEC 14882:2014(E)</a> §1.2 Normative references.<br>我会逐渐把一些常见的会让人觉得模棱两可的语言特性查阅的标准规范摘录到这里来,可以保证写出的东西在标准文档中都有依据。</p>
CppQuiz一些有趣的题和分析
https://imzlp.com/posts/10205/
2016-10-24T06:15:05.000Z
2016-10-24T06:15:05.000Z
<p><a href="http://cppquiz.org/">CppQuiz</a> is a simple online quiz that you can use to test your knowledge of the C++ programming language.<br>很有意思,今天刷了几道随手写点东西出来,以后有空再刷刷都放到这里来好了。其实CppQuiz有很多题都可以从《深度探索C++对象模型》中找到原因…如果有很多题不会做我建议还是买一本《深度探索C++对象模型》认真看一遍吧!<br>另外,我尽量在解答题的同时会在C++标准(ISO/IEC 14882:2014)中找到相关的描述。</p>
使用Travis CI自动部署Github/Coding Pages博客
https://imzlp.com/posts/42318/
2016-10-21T06:36:49.000Z
2016-10-21T06:36:49.000Z
<blockquote>
<p>本博客已切换为Github Action进行自动化部署。</p>
</blockquote>
<p>使用Hexo生成静态博客然后部署到Github/Coding Pages是目前我的博客的托管方式。<br>用起来是很爽,但是存在几个问题:</p>
<ol>
<li>Hexo的环境配置太麻烦,麻烦到几乎换台电脑就不能更新博客了</li>
<li>每次修改文章之后都要重新生成一遍</li>
<li>再加上提交博客源文件的话执行命令的次数太多了(主要是第一步)</li>
</ol>
<p>在提交博文的时候浪费了很多时间,我优化了一下流程几乎可以全自动提交更新了。</p>
Boost源码分析笔记
https://imzlp.com/posts/18194/
2016-10-19T21:39:33.000Z
2016-10-19T21:39:33.000Z
<p>最近在读Boost的代码,将一些Boost库中好用的模块用法以及实现分析写一下咯,不定期更新。</p>
配置SublimeText为Boost开发环境
https://imzlp.com/posts/49268/
2016-10-13T09:24:16.000Z
2016-10-13T09:24:16.000Z
<p>近期想研究下<a href="http://www.boost.org/">Boost</a>库,网络上提供的大都是使用IDE(VS/Code::Blocks等)的教程,但是只是写一些测试代码就要开个臃肿的IDE我是很不爽的,今天折腾了一下在SublimeText中编译/链接使用Boost库的代码。顺便把折腾过程/工具整理了出来,如果别人有这样的需求而且恰好能看到这篇文章的话,就能少浪费时间了。</p>
<p><strong>2016.11.01 Update</strong><br>使用最新版本MinGW64-GCC6.2(x86_64-6.2.0-posix-seh-rt_v5-rev1)来编译出LLVM/Clang 3.9,再使用编译出来的Clang编译Boost1.62,之前在Clang中链接编译出来的Boost库出现的报错情况消失了。<br><strong>注意:使用Clang编译Boost时,最好确保当前的clang版本是由当前系统中gcc的版本编译而来的,不然使用clang链接编译出来的静态链接库时会出现奇怪的问题。</strong></p>
<p>可以在这里下载我编译好的版本:<a href="http://pan.baidu.com/s/1i5PpoB7">MinGW62-GCC6.2(x86_64-6.2.0-posix-seh-rt_v5-rev1)</a>,使用GCC6.2(上面的MinGW版本)编译的<a href="http://pan.baidu.com/s/1pKLyZ7H">LLVM/Clang3.9</a>,以及<a href="http://pan.baidu.com/s/1eRZU26u">Boost(MinGW64-GCC6.2/LLVM3.9/VC14-ALL)</a>,需要的链接库版本(debug/release/static等)可以自行选择。<br>完整的编译工具链可以<a href="http://pan.baidu.com/s/1pKN0TPh">点此下载</a>。</p>
使用Docker部署shadowsocks服务
https://imzlp.com/posts/354/
2016-10-10T22:10:01.000Z
2016-10-10T22:10:01.000Z
<p><a href="https://app.arukas.io/">Arukas</a>是日本的一家<a href="https://www.docker.com/">Docker</a>服务供应商,目前属于测试阶段,可以免费使用。我们可以用<a href="https://www.docker.com/">Docker</a>很方便的来做一些很有趣(好用)的事,比如部署自己的博客或者shadowsocks服务器。</p>
在UE中使用Git进行版本控制
https://imzlp.com/posts/7647/
2016-10-07T23:31:01.000Z
2016-10-07T23:31:01.000Z
<p>Unreal Editor中提供的Source Control可以通过Git实现蓝图项目的<strong>版本提交/版本比对/撤销修改</strong>等一些基本功能,远远比不上Git Bash强大,但是BluePrint间的Diff还是很好用的。</p>
Git快速上手指南
https://imzlp.com/posts/53696/
2016-09-29T22:19:37.000Z
2018-08-15T00:57:19.000Z
<p>我司最近搭建了内网服务器,以后再做项目时都要用git来进行版本控制了,我在这里把一些常用的操作写下来方便查阅。</p>
为C++的switch添加case的字符串匹配
https://imzlp.com/posts/1494/
2016-09-24T22:43:23.000Z
2016-09-24T22:43:23.000Z
<p>C++标准中的<code>switch</code>是不能够实现字符串的case匹配的,但是往往我们也有这个需求,来实现一下。</p>
总结一下编码的几个习惯
https://imzlp.com/posts/35673/
2016-09-13T07:26:09.000Z
2016-09-13T07:26:09.000Z
<p>最开始写代码的时候总是拿到一个问题就捋起袖子开干,基本上就是属于边写代码边排错顺便在写代码中设计解决问题的流程,但是这样效率实在是太慢,有很大的可能就是边写边删,等同于设计出来的蹩脚的就重构了,浪费了很多时间。</p>
读《C++语言的设计与演化》及一些疑问的解答
https://imzlp.com/posts/30227/
2016-09-09T08:15:46.000Z
2016-09-09T08:15:46.000Z
<p><a href="https://book.douban.com/subject/1096216/">C++语言的设计与演化</a>是C++作者Bjarne Stroustrup撰写的一本关于C++从构思设计到实际实现中思考权衡的过程的书,也(应该)是市面上唯一一本语言设计者站在<strong>语言设计</strong>的视角所写的书。</p>
<p>有很多问题我们不应该只知道<strong>How</strong>,更应该知道<strong>Why</strong>,因为这样可以从更深层次地理解这个东西。所幸的是《C++语言的设计与演化》就是这么一本书。最近在读期间明白了很多之前在C++中只知道<strong>How</strong>而不知道<strong>Why</strong>的东西(为了与C兼容C++真是割舍了太多),这篇文章算是一篇读书笔记和关于<strong>Why</strong>的记录,我会逐步整理出来。</p>
使用Unreal Engine 4采集360°全景视频
https://imzlp.com/posts/64044/
2016-09-05T19:44:11.000Z
2016-09-05T19:44:11.000Z
<p>本文部分内容摘自Unreal Engine的官方博客文章:<a href="https://www.unrealengine.com/zh-CN/blog/capturing-stereoscopic-360-screenshots-videos-movies-unreal-engine-4">从虚幻4中采集360度立体电影</a>,其余部分为修正该文章错误和提供一个现成可行的解决方案。</p>
读CSAPP:与《现代操作系统》的比较
https://imzlp.com/posts/33213/
2016-08-30T01:32:15.000Z
2016-08-30T01:32:15.000Z
<p>这两天读<strong>CSAPP</strong>读的兴起,昨天还发了条动态说读<strong>CSAPP</strong>比<strong>现代操作系统</strong>读着爽(哈哈)。</p>
动态内存和智能指针
https://imzlp.com/posts/4280/
2016-08-25T08:18:53.000Z
2016-08-25T08:18:53.000Z
<p>智能指针作为C++11最重要的特性之一,相关的内容本来是辑录在<a href="https://imzlp.com/2016/05/12/cpp11-new-features/">C++11的语法糖</a>中,但是这部分太重要而我最近又比较闲(逃),就单独列出来详细地总结一下咯。</p>
Source Insight插件与配置
https://imzlp.com/posts/42068/
2016-08-14T08:08:31.000Z
2016-08-14T08:08:31.000Z
<p>最近折腾上了几款开发相关的工具堪称神器,工欲善其事必先利其器也。有时间来整理一下写出来。</p>
使用VisualGDB在VS上编写Linux程序
https://imzlp.com/posts/9932/
2016-08-08T00:53:42.000Z
2016-08-08T00:53:42.000Z
<p>作为一个cpper和Linuxer,经常在Linux上写代码,最近发现了VisualGDB(VS的插件)这个神器,从此也可以在Windows上直接写跑在Linux的程序了!调试起来更爽!</p>
在VPS上部署shadowsocks服务
https://imzlp.com/posts/31145/
2016-07-27T20:34:32.000Z
2016-07-27T20:34:32.000Z
<p>这两天帮同事搭了一台用作代理的VPS,顺道把这些东西整理了一下。<br>本文不是面向零基础读者的,在阅读下面的东西之前,你首先应该有一台可以访问外网(国外网络)的VPS,其次你也应该具有一些基本的Linux操作的知识。</p>
学习C/C++的一些书籍和工具
https://imzlp.com/posts/64054/
2016-06-12T12:08:43.000Z
2016-06-12T12:08:43.000Z
<p>从开始学C语言到现在也有五六年的时间了,也看了不少的好书和烂书,折腾了很多工具(编译器/编辑器圣战),在这里详细汇总一下。折腾久了能够得到一种思想,这种思想不同于那种“拿来主义”,而是“自己去做”的经验。</p>
未来计划
https://imzlp.com/posts/52122/
2016-06-10T09:52:32.000Z
2016-06-10T09:52:32.000Z
<p><img src="https://img.imzlp.com/imgs/zlp/blog/posts/52122/future-plans.webp"><br>转眼大学即将毕业了,虽然大学期间学了(折腾)了不少东西,但是还是觉得很菜啊,还要继续努力。<br>对于未来我有几点想法,在这个当口写下来吧。督促勉励自己。</p>
谈高考
https://imzlp.com/posts/27665/
2016-06-08T07:44:11.000Z
2016-06-08T07:44:11.000Z
<p>这两天是高考的时间,想到了几年之前我参加高考的时候,那个时候还是too young,觉得有自己追求的东西就要去做,浪费了很多时间在学习编程上。可是现在看来高中的时候还是要好好学习的,因为学历就刚毕业而言确实是门槛。</p>
Pthread多线程编程
https://imzlp.com/posts/58408/
2016-06-04T17:08:48.000Z
2016-06-04T17:08:48.000Z
<p><a href="https://zh.wikipedia.org/wiki/POSIX%E7%BA%BF%E7%A8%8B">POSIX线程</a>(英语:POSIX Threads,常被缩写为Pthreads)是POSIX的线程标准,定义了创建和操纵线程的一套API。</p>
删除void*指针引发的内存泄露
https://imzlp.com/posts/6978/
2016-06-04T10:51:47.000Z
2016-06-04T10:51:47.000Z
<p>当一个void*指向一个class object时,我们对其执行<code>delete</code>操作,会引发未定义行为——可以确定的是该delete操作不会执行object的析构函数,会导致内存泄露。</p>
结构体成员内存对齐问题
https://imzlp.com/posts/61962/
2016-06-02T10:12:34.000Z
2016-06-02T10:12:34.000Z
<p>在讲内存对齐之前,先介绍一个相关的概念——<a href="http://www.baike.com/wiki/%E5%81%8F%E7%A7%BB%E9%87%8F&prd=so_1_doc">偏移量</a>。</p>
<blockquote>
<p>把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为“有效地址或偏移量”。</p>
</blockquote>
<p>简单来说,在结构体中偏移量指的是结构体变量中成员的地址和结构体地址的差。</p>
C语言中不具有原生bool类型
https://imzlp.com/posts/20582/
2016-06-01T19:46:55.000Z
2016-06-01T19:46:55.000Z
<p>有点标题党了,准确的说是C语言标准中并无<code>bool</code>这个关键字来表示布尔类型。<br>在C++中我们通常使用<code>bool</code>变量存储逻辑值。<br>但是,C语言中是没有<code>bool</code>类型的,C语言中只有<code>_Bool</code>类型。<br>今天和人聊到这个问题,确实容易搞混淆,写出来记录一下。</p>
将树莓派打造成便携的Linux编译环境
https://imzlp.com/posts/15989/
2016-05-25T09:04:52.000Z
2016-05-25T09:04:52.000Z
<p>手头有块Rspberry 2B+,吃灰挺长时间了,由于一直在学校老是停电也就没拿它来跑脚本或者下载机。也正是因为最近学校SSH连接VPS的时候老是断电/网,很郁闷,所以折腾一下把树莓派搞成一个便携的编译环境。</p>
关于编译器生成默认构造函数的一些误区
https://imzlp.com/posts/7666/
2016-05-18T19:38:50.000Z
2016-05-18T19:38:50.000Z
<p>当我们编写的一个类没有显式提供构造函数但<code>编译器需要构造函数时</code>(一定要注意这句话),编译器会为我们生成一个。<br>但是编译器生成的默认构造函数与我们假想其可以完成的行为并不一致。</p>
进程间通信
https://imzlp.com/posts/58483/
2016-05-17T19:48:04.000Z
2016-05-17T19:48:04.000Z
<p>实现进程/线程间通信的方法有:</p>
<ol>
<li>进程间通信方法有:文件映射、共享内存、匿名管道、命名管道、邮件槽、剪切板、动态数据交换、对象连接与嵌入、动态连接库、远程过程调用等</li>
<li>线程同步的方法有:事件、临界区、互斥量、信号量</li>
</ol>
C++11的语法糖
https://imzlp.com/posts/2441/
2016-05-12T22:30:19.000Z
2016-05-12T22:30:19.000Z
<p>从C语言过来觉得C++03和OO的特性简直不能更爽,最近着重看了一下C++11的新特性,觉得有好多很棒的语法糖啊!用起来也很爽啊。</p>
STL释放指针元素时造成的内存泄露
https://imzlp.com/posts/50773/
2016-05-08T13:51:13.000Z
2016-05-08T13:51:13.000Z
<p>当我们删除一个指针时,会删除该指针所指向的对象。但是当STL容器中存放指针对象时却不会这样。</p>
使用Gprof分析代码性能瓶颈
https://imzlp.com/posts/34573/
2016-05-07T13:32:34.000Z
2016-05-07T13:32:34.000Z
<p>使用<strong>profiler</strong>来分析代码的性能比纯脑补分析起来更省力更详细也更直观。</p>
详细分析下C++中的类型转换
https://imzlp.com/posts/27258/
2016-05-04T19:35:17.000Z
2016-05-04T19:35:17.000Z
<p>在C++中,如果一个运算符的运算对象类型不一致,这些运算对象将转换成同一种类型。<br>类型转换分为<strong>隐式转换</strong>、和<strong>显式转换</strong>。</p>
C++中面向对象部分知识整理
https://imzlp.com/posts/34569/
2016-04-16T17:31:49.000Z
2016-04-16T17:31:49.000Z
<p>近期准备求职面试。<br>将C++中面向对象部分的基础知识复习整理一下。</p>
选择操作符重载的成员和非成员实现
https://imzlp.com/posts/34001/
2016-03-21T16:54:58.000Z
2016-03-21T16:54:58.000Z
<p>为类设计重载操作符的时候,必须选择是将操作符设置为类成员还是普通非成员函数。</p>
读《人生》,谈谈面临的选择
https://imzlp.com/posts/54010/
2016-03-20T14:07:26.000Z
2016-03-20T14:07:26.000Z
这是一篇加密文章,请输入密码后阅读。
C/C++中占位修饰符*的用法
https://imzlp.com/posts/16506/
2016-03-19T11:49:16.000Z
2016-03-19T11:49:16.000Z
<p>在刷题的时候碰到的代码填空看到输出格式中的这段代码:<code>printf("%*s%s%*s\n",__________);</code><br>需要输出的格式为:<code>________123456________</code>//下划线为空格</p>
C++中错用宏定义造成的二义性
https://imzlp.com/posts/38656/
2016-03-14T19:07:46.000Z
2016-03-14T19:07:46.000Z
<p>在写代码的时候经常会用到宏(#define)命令,最近我遇到了这两个错用宏的地方,写出来分析一下。</p>
配置SublimeText为C/C++的轻量级IDE
https://imzlp.com/posts/14596/
2015-12-26T21:54:01.000Z
2017-04-10T18:18:34.000Z
<p>作为一个cpper,其实早就用惯了GCC这样的工具,不过不得不说啊,GCC的错误信息是真烂啊,虽然有错误提示,但是也经常需要自己肉眼Debug才能搞明白…现在福音来了,<code>Clang</code>的信息精准度不知道比GCC高到哪里去了。</p>
使用Wolfram|Alpha求积分
https://imzlp.com/posts/8531/
2015-12-24T20:52:35.000Z
2015-12-24T20:52:35.000Z
<p>其实使用<a href="http://www.wolframalpha.com/">WolframAlpha</a>求积分,简直就是大材小用啊(不过这也是硬性的偷懒需求啊)。<br>最近一直在研究Wolfram Language,慢慢发掘新玩法咯。</p>
使用Koding在线管理静态博客
https://imzlp.com/posts/58862/
2015-11-27T13:16:33.000Z
2015-11-27T13:16:33.000Z
<p>之前都是在local写完文章之后发布上来,在自己电脑上都折腾好了node.js 、hexo、git等一大堆东西。<br>所以在自己电脑上用起来很方便,但是如果换台电脑的话就悲剧了,所有的东西都要自己配置,所以几乎换了台电脑就处于不能用的状态。</p>
读《数学之美》
https://imzlp.com/posts/19425/
2015-10-24T18:22:02.000Z
2015-10-24T18:22:02.000Z
<p>到手《数学之美》也有一段的时间了,作为这段时间内我茶余饭后的书籍,确实引起了我极大的兴趣,因为时间分配的不多一天只有阅读一两章左右,昨天看完了所有的章节,意犹未尽啊。</p>
分析密码学中的数学原理
https://imzlp.com/posts/30891/
2015-09-09T18:19:26.000Z
2015-09-09T18:19:26.000Z
<p>这两天看到《数学之美》中讲到的计算机中的数学模型,以及《What is Mathematics》的<code>数论</code>,看的心痒痒。今天懒癌暂时被抑制住了,我就要分析一下,密码学中的数学模型!</p>
Linux下使用Shadowsocks服务
https://imzlp.com/posts/23429/
2015-08-26T17:31:57.000Z
2015-08-26T17:31:57.000Z
<p>这两天重装了Linux,又不想再用GUI的SS,网上的资料都不怎么好用,自己动手折腾了一下。</p>
提取优酷订阅视频的RSS源
https://imzlp.com/posts/23354/
2015-08-19T14:56:12.000Z
2015-08-19T14:56:12.000Z
<p>这两天在折腾RSS,收集了不少RSS源,对于我等懒人来说,不开网页尽知消息RSS才是真正的利器,这两天搞定了QQ空间的RSS输出(没什么实用性…)还有新浪微博和新浪博客的RSS输出,但是我还比较喜欢的逻辑思维(在优酷),优酷并不提供RSS订阅,目前网内还没有发现什么特别有效的提取优酷订阅RSS源的方法,各种在线转换的网站基本没用,这等还要打开网页才能干的麻烦不能忍,所以动手研究了一下怎么把优酷订阅搞成RSS源,成功了,非常爽。</p>
Windows下自定义Dvorak键盘布局
https://imzlp.com/posts/50343/
2015-08-19T11:01:32.000Z
2015-08-19T11:01:32.000Z
<p>几经波折总算是搞定了windows下的Dvorak布局(不过稍有修改)<br>先从Dvorak的布局图开始说吧<br><img src="https://img.imzlp.com/imgs/zlp/blog/posts/50343/dvorakpsb.webp"></p>
Chrome插件推荐
https://imzlp.com/posts/841/
2015-08-18T14:50:26.000Z
2015-08-18T14:50:26.000Z
<p><code>LastPass</code>: Free Password Manager<br>强大的密码管理器,从此以后只记住一个密码就好了。<br><code>Momentum</code><br>论如何优雅的使用Chorme,每天一张好看的壁纸。<br><img src="https://img.imzlp.com/imgs/zlp/blog/posts/841/Momentum.webp"><br><code>Pocket</code><br>稍后阅读,手机端扫货电脑端整理效果更佳。</p>
STL中容器的构造函数
https://imzlp.com/posts/42105/
2015-08-18T12:44:55.000Z
2015-08-18T12:44:55.000Z
<p><strong><code>注意</code></strong>:此文档中所有的初始化皆依据以下容器</p>
<figure class="highlight cc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建vector<int>容器test,并为其赋值</span></span><br><span class="line">vector<<span class="type">int</span>> test;</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i<<span class="number">10</span>;i++)</span><br><span class="line"> test.<span class="built_in">push_back</span>(i);</span><br></pre></td></tr></table></figure>
两个迭代器初始化容器出现浮点数舍入
https://imzlp.com/posts/15409/
2015-08-18T12:39:17.000Z
2015-08-18T12:39:17.000Z
<p>最近在整理笔记的时候发现了个奇怪的问题:<br><img src="https://img.imzlp.com/imgs/zlp/blog/posts/15409/1.webp"></p>
创业维艰·如何完成比难更难的事
https://imzlp.com/posts/39435/
2015-08-18T11:15:13.000Z
2015-08-18T11:15:13.000Z
这是一篇加密文章,请输入密码后阅读。
顺序容器与关联容器
https://imzlp.com/posts/33878/
2015-02-18T13:26:31.000Z
2015-02-18T13:26:31.000Z
<p>C++ STL中的顺序容器和关联容器概念和用法整理。</p>
C++的基础语法整理
https://imzlp.com/posts/42362/
2015-01-20T11:50:59.000Z
2015-01-20T11:50:59.000Z
<p>C++的基本语法概念整理。</p>
C/C++速查表
https://imzlp.com/posts/14660/
2015-01-15T23:56:13.000Z
2015-01-15T23:56:13.000Z
<p>整理的一份C/C++的速查表,平时整理下放到这里来,供方便查询。</p>
写点自己的感悟,我的软件专业
https://imzlp.com/posts/44216/
2015-01-04T22:32:01.000Z
2015-01-04T22:32:01.000Z
<p>本文是之前发表在我校的一个帖子,涉及自己以往学习编程的一些经历和看法,为软件专业的学弟学妹的科普解惑之用,最近被挖出来,我都快忘了,顺便整理一下,在此贴出。</p>
使用Github来管理博客源文件
https://imzlp.com/posts/55550/
2014-11-20T23:52:01.000Z
2014-11-20T23:52:01.000Z
<p>将博客的源文件(非hexo生成的文件)托管到Github上,方便同步和控制版本。</p>
Github Pages+Hexo博客搭建
https://imzlp.com/posts/58952/
2014-11-18T11:11:11.000Z
2014-11-18T11:11:11.000Z
<p>之前使用博客园,总觉得不爽,也试过自己搭建博客。<br>wordpress太臃肿,其他的功能不强大(界面不好看),仔细想来想去还是用Github Pages+Hexo搭建一个静态blog吧,专注于写作。</p>
<blockquote>
<p>截至到2021.03.23,我已经持续用Hexo部署博客快要有六年的时间了,六年间写了一百多篇文章,使用Hexo部署的方式也经过了很多变化,写博客也逐渐变成了一种习惯。依稀记得在大学的某一天,我想要自己搭建一个博客,于是折腾了一天写了这篇文章,本站的历史就从那里开始了,希望我能继续用Hexo写到十年、二十年!</p>
</blockquote>