我是如何学习游戏引擎的?

Posted Jerish_C

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我是如何学习游戏引擎的?相关的知识,希望对你有一定的参考价值。

这是【游戏开发那些事】第51篇原创

前言:游戏引擎,表面上看是一个工具,实质上却是一本“技术图谱”,每一个点击行为的背后都有着其独到的意义。每一个模块都索引着数以万行的工程代码、数以百计的科研论文以及数以十计的专业书籍。学习引擎,其实就是一个修炼内功的过程,需要你不断深挖里面的技术细节,找到对应的学习资料并消化理解。

游戏引擎的概念我在前面文章已经说过,其实就是一套整合了各种游戏开发工具、封装底层并提供程序函数库的软件系统。

游戏引擎架构系统分层

引擎技术固然复杂,但通过这些年的不断迭代,大部分商业引擎已经拥有了非常完善的编辑系统、不错的交互体验、详细的文档以及丰富的开发功能,学习的门槛的降低也让更多的岗位参与进来(进而诞生出了越来越多的独立游戏)。下面列举了游戏开发中常见的岗位 以及 两条常见的协作开发的流水线:

其实学习游戏引擎,前期对于任何岗位来说路线都是相似的,基本上就是一个熟悉基本操作、理解基本概念、拓展专业知识的过程。但进入后期阶段,程序员需要拥有更多的思考和知识储备,需要从代码层面理解并进一步达到能够独立编写的境界。下面分享一下我近些年学习引擎的经验,希望能够帮助到你,

预备阶段:引擎选择,语言基础,计算机基础

Cocos、Cryengine、Unity、Unreal我都有接触过,其实发展了这么多年各有适合的领域,当然也有不少值得诟病的地方。如果非要一句话说出来谁好谁坏是不现实的,也显得很不负责任(其实每天都有人吐槽UE耦合的Gameplay、蓝图不好维护,吐槽Unity一堆半成品功能、资源加载慢、Mono低效等)。

在我看来,大部分人只要考虑学习引擎的成本,就业难度,发展方向就可以了,考虑目前市面上就业以及影响最广泛的是Unity和Unreal,所以只推荐这两个。

不过这两个引擎一开始就给开发者出了道难题:我是学C#还是C++?

  • 如果你是在校生,有时间慢慢学习,那么更推荐Unreal,开源代码有更多的研究空间,C++学透了也是好处多多。

  • 如果你是为了尽快找到一份工作或者快速出成品,Unity上手确实更快一些,C#也相对友好一点。

当然这不是绝对的,任何引擎的开始阶段和大成阶段都是相似的。但Unreal的学习曲线可能曲折一些(C++占了不小的因素),某一个阶段的受挫很可能会影响到开发者学习的动力和进度。

不管怎么说,学习语言、看书都是必经之路,无论哪个方向都要沉下心来好好看一两本经典书籍。比如C++,有《C++ Primer》《Effective C++》《C++语言的设计和演化》入门和拓展,进阶有《C++Template》《深入探索C++对象模型》《More Effective C++》,虚幻引擎里面的C++是经过魔改的,如果你专注于写游戏逻辑,确实用不到太多的C++特性,但考虑到未来的成长还是要尽可能深入。C#书籍,《C#图解教程》《C#本质论》《C#高级教程》《深入理解C#》《CLR via C#》,如果是纯小白,那么先只看一本,其他的慢慢消化。多说一句,语言的本质殊途同归,真正的大佬也不会拘泥于某一个语言。(PS:上述的电子书都可以从我的公众号里面获取)

除了语言外,还有一个更重要的预备知识——计算机基础。计算机基础水平决定了你以后的发展速度和天花板(也是科班出身的优势所在),所以强烈建议学好一门语言并持续性的巩固操作系统、计算机网络、数据结构和算法等专业知识。我一直后悔本科的时候并没有吃透这些内容,所以工作的这些年来从来没有停止过操作系统等知识的学习。这对很多人来说是一个漫长的过程,因此我们可以在后续的工作中慢慢巩固。

关于这些知识的意义,比较直观的例子就是他们通常能帮我解决各种疑难杂症,比如:

  1. 遇到崩溃但是堆栈信息不准(汇编可以辅助我们定位)

  2. 本地能编译通过,但是远端编译不过(可能是宏定义或者UnityBuild导致)

  3. 手机直接卡死,没有任何堆栈信息(可能是内存问题)

  4. 字符串莫名的乱码,Debug和Shipping版本表现不一致(编译器优化问题)

这些问题在没有融会贯通那些计算机基础知识前是很难找到解决方案的

第一阶段:熟悉游戏开发,学习引擎编辑器的基本操作

如果你从来没有接触过任何引擎,也没有相关的技术积累,那么无论你是做什么岗位都要放平心态,当做一普通的软件去学习即可。这个阶段的目的是熟悉引擎的基本操作,方法就是找一个入门教学视频/入门书籍跟着做,遇到不懂直接去搜索引擎(或者官方文档)上查同时尝试理解引擎中的一些基本概念,比如unity中的GameObject、Component、Script或者Unreal中的actor、Component、蓝图等(一个月的时间足够了)。很多大佬总是对教程或者视频嗤之以鼻,但是在我看来,视频教学确实是一个速度最快、理解起来最容易的方案。

如果你有一定的相关经验和积累,可以跳过上面这一步,直接尝试脱离教程进行Demo的编写。注意不要急于一口气把所有的Demo都做一遍,挑一个感兴趣的方向并尽可能地去完善,你的收获会更大的。比如做一个横版跳跃,一个简单的RPG或者ACT项目,不同的项目侧重点都有所不同,可以提前大致了解一下。此外,脱离教程并不是脱离项目,教程(或者官方案例)里面的项目代码、蓝图等还是有很大的参考意义的,自己在实现Demo的时候要多对比和借鉴,真正的理解其意图才能更好的优化和改进。

Unreal和Unity的编辑器界面其实都很相似,触类旁通

第二阶段:补充游戏专业知识,理解基本原理

当你可以轻车熟路地配置一个Prefab,写写脚本或者能手到擒来地拉一个蓝图,实现一个Demo后,就不要甘心再当一名熟练工了。接下来我们需要开始补充相关专业知识,尽量理解你常用的每一个模块以及每一个资源背后的意义

当你将一个Prefab拖入场景时或是当你打开一个蓝图时,不妨思考一下他到底是个什么东西?为什么模型分为静态模型和骨骼模型,而不是动态模型?为什么骨骼模型的外表叫做蒙皮?

这个阶段你可以配合官方文档去索引相关的技术概念,比如动画系统里面的IK、Montage(蒙太奇)、BlendSpace、骨骼动画、蒙皮动画,然后就能通过这些概念到网上搜索相关的书籍、论文、视频等等。如此往复拓展,你的知识图谱会迅速被打开并充实起来。

  • 动画系统的书籍有哪些——《Character Animation With Direct3D》

  • 动画系统一般包含哪些技术—— 骨骼蒙皮动画、Morph动画、状态机、Ragdoll、Root Motion、IK

  • 骨骼蒙皮的技术原理—— Mesh按照权重绑定到骨骼上进行递归移动

  • 动画系统有哪些前沿的技术——Motion Capture、Motion Match、Path Warpping等

    (其他模块类似,时间充裕的话建议系统的学习并整理该模块相关的知识

此外,你应该再次打开工程项目和引擎,开始尝试深入看一些成熟项目(引擎)的代码。在理解了一些专业的概念后,最好去代码里面再去看一下他的实现方式,这时候你的理解会比第一阶段更加深刻。比如一个组件是如何挂到对象上并生效的?动画蓝图本质上是一个什么东西?这些动画数据是如何传递的?这个时候你就可以尝试性的梳理和分析源码,逐个的解决你的问题。这里建议合理利用堆栈信息、画图工具、断点调试等手段进行辅助。

这个阶段其实比较艰难,除了专业知识外你还会遇到各个方面的难题。比如数学物理基础、语言特性、系统原理、编译调试方法以及各种Bug,一个一个攻破。

上面这些并不是只针对程序的,其实作为一名合格的策划/美术,即使不看源码至少也需要把官方文档研究透彻,通过一些视频或者书籍理解部分系统的基本原理。只有真正的理解了这些,你才会真实的感受到自己的进步和成长,以后在面对这些系统的时候也会更加游刃有余。

不过考虑到现代引擎如此的复杂和庞大,有必要逐个模块去学习么?答案是否定的,毕竟人的精力有限。即使我已经接触引擎5年了,还是有很多模块几乎没有碰过,不是说他不重要,而是他不在我的规划目标之内。所以要自己规划发展方向和感兴趣的内容,然后再进行相关资料的查阅和学习。

第三阶段:代码修炼(针对程序员)

这阶段的已经对引擎的某些模块有了专业的理解和思考,下一步就是动手去使用和完善。这个时候光看书籍和资料已经不够了,需要去看相关的源码或者Demo来加深理解,并尝试写一些复杂的代码模块。这一步其实和第二步是相辅相成的,你在查阅各种资料的同时,就可以动起手来仿写一些相关的代码并根据自己的需求进行拓展。

比如说你通过书籍《网络多人游戏架构与编程》理解了什么是帧同步和状态同步,那么在当前的引擎中使用的是什么方式?能否转换成另一种方式呢?难点都有哪些?你可能需要下面的能力

  • 计算机网络基础知识

  • TCP/UDP Socket编程

  • 序列化的实现和应用

  • 理解引擎Tick和各个模块的更新逻辑

  • C++一些常见的语言技巧

  • 操作系统内存知识

  • 复杂模型的抽象能力

再比如,你了解了AI中基本的寻路算法和行为树概念,你知道引擎里面是如何实现的么?A*算法在引擎里面有集成么?一个复杂的场景如何拆成格子类似来应用A*呢?能不能自己写一个简易的行为树呢这些都是我们在学习引擎以及拓展开思路后需要思考和解决的问题。

在编写这些代码的时候,你会遇到各种各样的问题,不仅是对编程能力的锻炼也是对你个人编程素养以及计算机素养的提升,以往许多看起来高端且理解不够透彻的知识点也会逐渐被消化和关联起来,比如内存池以及内存管理、无锁编程、异步编程、Hook技术、游戏安全等
 

另一方面,我们的大脑会不断地对其进行抽象,引擎的代码结构也会逐渐变得清晰,渐渐的我们就可以真正地理解模块的结构和意义。当然,平时如果保持一个画图分析、写笔记总结的习惯,这个过程会更顺利一些。

个人绘制的一些架构图

个人的一些笔记目录

第四阶段:脱离引擎(针对程序员)

这个阶段已经基本脱离引擎了,我们更多的是从程序的角度思考架构与实现方式,思考如何将更先进的理论思想(包括架构方式和专业的论文知识)应用到我们的环境中来。你可以尝试看不同的引擎源码,参考不同的开源项目与论文,开始对比不同引擎的优劣并尝试自己实现与优化,不断磨练自己编码能力的同时,也在深入着某个方向的专业能力以及架构能力。慢慢地,你会拥有属于自己的一套思考理论(比如我习惯先跑流程,梳理概念然后关注数据存储方式),可能打开一个引擎源码就能猜到哪些模块是干什么的,它的结构大致是什么样子的,运行时类型怎么获取、资源的管理方式是什么、GC的方式是什么、Tick更新的顺序是什么、多线程如何进行封装与应用等等,这时候他是Unity还是Unreal对你个人的技术来说似乎没有太大的差别了。

不过,你依然很难做到游戏开发领域全方向的专家,换一个方向可能还需要重新走一遍相似的路(当然会快很多)。另一方面,每一个领域的技术也一直在推进着,科研界从没有停止过论文的产出(比如每年的siggraph,近些年深度学习与游戏AI的结合),工业界也从来不会放慢对新技术投入生产的脚步(比如DX12、Vulkan的推进),我们的学习仍不能止步。

以上就是我关于引擎学习的一些经验分享。当然最后一个阶段某种程度上已经超过我的能力范畴,算是我后续发展的一个方向吧。总的来说,多思考、多提问、多查资料、多写代码、多总结,只要坚持下去每个人都可以成为一名优秀的开发者。

始于引擎最后又脱离引擎,这可能就是游戏开发领域的至高境界吧~

以上是关于我是如何学习游戏引擎的?的主要内容,如果未能解决你的问题,请参考以下文章

我是如何学习游戏引擎的?

我是如何学习游戏引擎的?

我是如何学习游戏引擎的?

游戏开发进阶Unity网格探险之旅(Mesh | 动态合批 | 骨骼动画 | 蒙皮 )

游戏开发进阶Unity网格探险之旅(Mesh | 动态合批 | 骨骼动画 | 蒙皮 )

游戏引擎打假系列一_学习c++语言_库引用