c++ unreal4 入门_unreal 4 c++ - CSDN
  • 摘要: 一位程序员网友小保哥分享自己的UE4快速上手过程,只是笔记,52VR做了一点更加适合阅读的修改,整理给大家。首先,本文只是针对有比较熟练C++技能的程序员,他可以没有任何图形学或游戏引擎方面的经验知识。...
    摘要: 一位程序员网友小保哥分享自己的UE4快速上手过程,只是笔记,52VR做了一点更加适合阅读的修改,整理给大家。

    1. 首先,本文只是针对有比较熟练C++技能的程序员,他可以没有任何图形学或游戏引擎方面的经验知识。
    2. 其次,本文只是偏重工程方面的介绍,没多少理论知识的介绍,目的纯粹就是让一个完全没有接触过UE4的C++程序员能够很快着手开发UE程序。
    3. 再次,本文只是个人的经验之谈,甚至有可能有理解错误的地方,因为我也只是学了UE4一个多月,但是确实能够让我很短时间就能从事UE4的开发了。
    4. 最后,源于以上几点,高手勿喷,如有不爽,绕行即可。若有闲情雅致,可以顺手指点指点,不吝感激。

    我研究的是UE4.10,因为电脑上只下载了这个,看的官方文档是4.9的。

    以下就按时间顺序排列我的学习过程:

    1)创建工程

    对程序员来说,甭管这个引擎如何如何,我如果用它开发一个什么东西,首先得创建一个工程,然后把所有相关的代码都写到这个工程里。这就是我们要知道的第一步。那么在UE4里如何创建一个工程呢?在启动引擎程序时,自己会蹦出一个窗口,让你选择打开电脑上已有的工程或者创建新的工程。UE4工程只有两种类型:蓝图的、C++的。这两种类型的工程其实没有任何实质性的区别。把UE4工程分成这两种类型,表现出来的唯一区别是:C++类型的工程创建的时候,会自动弹出visual studio来打开这个UE4工程。仅此而已。

    而对程序员来说,蓝图类型的工程创建好后,在该工程的UEditor的File菜单里会有一项[Create Visual studio Project],中文版是[生成Visual Studio项目],以后我只针对英文版来写了。点击一下这个菜单项,对应的Visual Studio工程文件就创建好了。相应的,File菜单里还有[Open Visual Studio]菜单项,作用就是在Visual Studio里打开该工程对应的代码文件。其他菜单项暂且放下,一会儿再回头说几句就懂了。

    2)UE4的工程配置

    甭管是蓝图类型还是C++类型的,工程反正是创建好了。

    到这里,我们先不管如何往这个工程里写代码添加新功能。我们直接Build一下这个工程:UEditor界面工具栏上的Build按钮或者VisualStudio的Build按钮。没有任何悬念,结果肯定是Build成功。

    哦,说到这里,提一下,UE4.10以上必须安装Visual Studio 2015。我们打开对应的Visual Studio工程(如果是蓝图类型,按照上面所述方法生成Visual Studio工程即可)。

    215337owpzs0wsovpwpqpp

    在VisualStudio里,我们能看到这个工程里的代码文件就很少的几个,如图,这张图片里VirtualCamera是我的工程名。注意看.Target.cs后缀的文件,这里所谓的Target就是Makefile文件里的Target的意思。我们知道手写Makefile文件在某些情况下是比较费劲的行为,因此程序员们造出了很多Automake工具用来自动生成Makefile文件。因此,UE4自己也造了一个Automake工具,用来生成Makefile文件。这个Automake工具是C#写的,用C#文件来描述Make的规则,比如这个Target.cs就是用来描述Makefile里最终的成品,可以有多个Target.cs,但它们不一定同时起作用。比如vs编译类型选为[Development]而不是[Development Editor]时,那个Editor.Target.cs文件描述的Target的Make规则就不会起作用,此时,即便你从硬盘上和vs里删掉这个.Editor.Target.cs文件,工程也能成功编译并运行。文件列表里还有类似.Build.cs文件,这个就描述类似Makefile里的中间目标文件的Make规则。这些cs文件是在添加蓝图类或者c++代码时自动生成的,不用鸟它们,只需要知道这些cs文件是UE4的Automake工具需要的就行了,只要有了这些cs文件,我们的UE4工程就能正确编译运行。我这句话里蕴含的意思还有:对于UE4工程的编译,完全不依赖visual studio的project文件,即.vcxproj等文件。也就是说UE4使用自己的AutomationTool来读取cs文件描述的Make规则来进行编译。然而,凡是用visual studio打开的工程,必然需要一个.vcxproj文件,结合刚才讲的,我们就能明确这里visual studio的作用仅仅是方便我们阅读和编写源代码,这里visual studio的方便性还是很巨大的,不是吗!因为vs为阅读编写源代码提供了强大的支持。上一节的最后我没讲UEditor的File菜单里还有一项[Refresh Visual Studio Project],这个选项的作用就是遍历我们的UE4工程目录结构,根据遍历的结果,刷新.vcxproj文件,然后让vs重新加载这个更新的proj文件,这样只要我们往工程目录里增加或删除了代码文件,只需点击一下这个菜单项,在vs里就能反映出这种变化。


    3) UnrealAutomationTool

    工程的Build是一个很长的过程,里面分成多个阶段,我只关心里面最重要的阶段,就是代码文件的Compile过程。这里先介绍几个名词:UBT(Unreal Build Tool)又叫UnrealAutomationTool,这个工具主要作用就是组织Build流程,直白点说就是按一定顺序调用不同的工具完成整个Build过程。首先调用的肯定是解析各个cs文件的工具,解析的结果就是Build的目标,先Build谁,再Build谁。Build的顺序和目标定下来之后,就要开始真正的Build动作了,也就是Compile代码文件,Link出目标。Compile的第一步是调用UHT(UnrealHeaderTool)工具,这个工具就类似于C++里的预处理器,UHT读取.h文件,解析里面的一些元信息(UE4定义的,比如[UCLASS],[USTRUCT][BlueprintCallable],UPROPERTY,UFUNCTION等等),这些元信息不是C++语言的一部分,C++编译器自然无法识别,所以需要UHT工具先解析这些元信息,生成对应的.generated.h文件,在这个.generated.h文件里的内容就是用合法C++代码模拟的刚才那些元信息。然后原先.h文件里的所有元信息文本都会被删除。这一步完成后,出来的就都是合法的C++的代码文件了,可以直接送给C++预处理器处理,进而编译器,链接器。最终产出Build的目标,完成Build过程。参考一下下图:

    (点击图片看大图)

    215337bawz3ltwachrvvlh215337jtlvozvoxztplvws

    4)还是要说说Blueprint

    到这里,对于C++程序员来说,算是掌握了总体的开发流程,知道如何开始,如何结束了。

    那么剩下的就是学习如何往工程里添加代码,并学习代码怎么写--学习有哪些api可以用,如何用。这是UE4开发里最重要的一块了,废话,前面说的都只能算是常识,不能算UE4开发。然而只有知道了这些常识之后,我们接下来才可以真正开始学习开发。

    首先开宗明义,学习UE4最快速的捷径就是Blueprint,这是我学了1个多月的UE4的最大感触。

    在UE4的官方文档里,讲Blueprint时首先就说到:在UE4里,Blueprint支持的功能涵盖了C++支持的几乎所有特性,即BP(Blueprint简写)几乎等价于C++。然而,话锋一转,其又说到,BP有其适用场合,不是所有场合都适合用BP,因为某些场合BP的性能比原生C++代码要慢。

    适合用BP的场合:主要就是对性能要求不是特别高的应用场景,比如绝大部分Event的响应等等。然而在我看来,大部分的开发任务不就是Event的响应么,这也就是说BP适用UE4开发的绝大部分场景。而且,众人所说BP太慢,纯粹是无理由的偏见,我承认某些BP可能没有原生手写C++代码快,但并不代表BP性能低。

    从开发效率上来看,能用BP的地方尽量用BP所带来的好处实在是不用多说了。尤其对新手来讲,写C++代码都不知道有哪些东西可以调用,更别谈写高效的C++代码了。因此,对新手来说,学习BP是必须的。其最重要的作用,就是让UE4新手能快速的掌握引擎在代码层面提供的功能。

    然而,在认识到这一点之后,我并没有立即开始BP的学习,而是先学习了一下如何让C++代码与BP交互,具体的知识少不了要自己去看官方文档,我这里只是列出我的经验。

    还要提一下:凡是能放到unreal场景里的东西都是Actor对象,对应C++里的AActor类型。Actor只是一个壳,它提供的所有功能都是由它包含的Component来提供的,不同的Component能提供不同的功能,最后表现出来的就是Actor具有所有这些Component提供的功能。Component的总分类,见链接,这个和Unity中的组件有些类似。我能保证这里的文档真正看懂的话,C++编程的部分从动手方面来讲不存在任何问题了。接下来看BP文档那一章,掌握BP也没有任何悬念,而且是很快乐的过程,不会有任何难度。

    215337nduj0u6qotdn6on6

    #5)GamePlay

    关于游戏模式,这里的文档也需要在看BP前提前阅读一遍 :

    215337fee8jelj5xjlj78b

    这里也有一张脑图,大家看看:

    (点击图片看大图)

    220522vfvwvt94ukm7vmvl

    展开全文
  • Unreal4 入门

    2015-07-16 10:16:39
    使用Unreal4引擎前需要安装 或者编译引擎。 下面就为同学们介绍下 Unreal4 安装配置。 一. 在Win7下安装Unreal4 在Win7下安装Unreal4需要以下几个步骤: 1. 打开“控制面板”的“程序和功能” 检查...

    http://blog.sina.com.cn/s/blog_7c5fd2e90101ku0j.html

    使用Unreal4引擎前需要安装 或者编译引擎。 下面就为同学们介绍下 Unreal4 安装配置。


    一. 在Win7下安装Unreal4

    在Win7下安装Unreal4需要以下几个步骤:

    1. 打开控制面板程序和功能 检查是否已安装 Microsoft Visual C++ 2010 Redistributable ,请同学们先卸载掉,否则下面安装DXSDK_Jun10时会出现Error Code:S1023错误。(卸载完成一定要重启电脑 不然还会出现Error Code:S1023的错误 如果没有安装的同学请继续下一步Unreal4 <wbr>入门(安装) 

    Unreal4 <wbr>入门(安装)


    2. 安装DXSDK_Jun10 如果出现下图所示错误Error Code:S1023 请先完成第一步。

    Unreal4 <wbr>入门(安装)


    3. Win7下还需要安装 Windows 7 SP1(Service Pack 1) KB976932 补丁(windows6.1-KB976932-X64.exe)补丁可以从微软上下载(大概903MB)
    附下载地址(http://windows.microsoft.com/zh-cn/windows7/learn-how-to-install-windows-7-service-pack-1-sp1


    4. 安装完Windows 7 SP1(Service Pack 1) KB976932 补丁后就接下需要安装10以上版本的InternetExplorer浏览器。大概就是ie11_windows6_1_x64_zh_cn.exe 的一个安装程序。
    附下载地址 Internet Explorer 11(http://windows.microsoft.com/zh-cn/internet-explorer/ie-11-worldwide-languages


    5. 以上4步完成后就可以安装高端大气上档次的VisualStudio2013,也可以选择安装VisualStudio2012看个人喜好但是VisualStudio2013是Unreal4Engine引擎开发IDE所以UE4对VS2013支持的最好,还有很多插件呦。


    6. 最后一步就是安装UE4了,直接安装UnrealEngineInstaller-1.0.0-2039063.msi文件。桌面或者安装路径的Unreal Engine\Launcher\Engine\Binaries\Win64\UnrealEngineLauncher.exe 可以直接运行啦。

    Unreal4 <wbr>入门(安装)


    7. UnrealEngineLauncher是一个引擎用户验证登陆器,使用了增量更新机制(哈哈 做游戏的更新机制已经给大家展现出来,具体能有多强大还需要好好研究一下Unreal4 <wbr>入门(安装))。在(https://www.unrealengine.com/blog/welcome-to-unreal-engine-4)Unreal4官网注册一个账号就可以登录。
    我在淘宝花了120大洋找人代付了1个月的会员,还购买了一个月的GreenVPN。准备好好研究下喽Unreal4 <wbr>入门(安装) 
    会员登陆后还需要更新一个4.0.2的包大概7个G左右(嘿嘿 知道为什么买VPN了吗 - -!)

    Unreal4 <wbr>入门(安装)


    二. 在Win8/Win8.1 下安装Unreal4

    1. 依然首要问题安装DXSDK_Jun10时会出现Error Code:S1023错误。只要按照Win7下安装的第一步解决就OK了,一定不要忘记卸载完要重新启动计算机呦。

    2. 安装Visual Studio 2013或者Visual Studio 2012,个人建议选择VS2013许多新特性很适合Unreal4,而且UE4对Visual Studio 2013支持的比较好。
     
    2. 就可以直接安装UnrealEngineInstaller-1.0.0-2039063.msi文件了。


    三. 其他方式安装Unreal4 Engine

    算是小福利喽,不想付费又对UE4感兴趣的同学可以看下面方法,但是不确保链接总是会有效喔。
    Unreal4源码包下载链接(http://pan.baidu.com/s/1qWCYkz
    引擎资源包(一)下载链接(http://pan.baidu.com/s/1eQzfwo
    引擎资源包(二)下载链接(http://pan.baidu.com/s/1dD5Tcn

    1. 下载好Unreal4源码后先将压缩包解压缩,得到UnrealEngine-4.0.1-release文件夹,然后需要把引擎资源包(一)和引擎资源包(二)下载后解压到UnrealEngine-4.0.1-release文件夹下覆盖相应目录文件。

    2. 安装DXSDK_Jun10.exe,如果出现下图所示错误Error Code:S1023 请同学们看一下上面Win7安装Unreal4的第一步骤。

    3. 安装完DXSDK后,双击UnrealEngine-4.0.1-release目录下的GenerateProjectFiles.bat文件,等待差不多1分钟后点击目录下的Ue4.SLN(VisualStudio2013的工程文件

    4. 然后就可以用VisualStudio2013打开工程文件可以进行编译了,编译时间会很长根据每位同学机器配置会有差异基本上15分钟就可以搞定,请同学们耐心等待。编译完成后就可以在 \UnrealEngine\Engine\Binaries\Win64目录找到UE4Editor.exe等运行文件啦。


    小结:官方说现在还是未优化版本,稳定版请等待几个月会推出4.1版本(版本更新说明已经在我博客上贴出来 感兴趣的可以去看下Unreal4 <wbr>入门(安装)),虚幻4运行配置较高,大家赶紧去体验吧。


    这次主要是简单介绍下Unreal4引擎使用前的配置 和 VisualStudio2013调试插件的配置


    1. 在Unreal4安装目录下找到路径为 Unreal Engine\4.0\Engine\Extras 的文件夹。如下图:
     
    Unreal4 <wbr>入门(配置)

    可以很清晰的看到有 Android ,FX_tools , Maya_AnimationRiggingTools , MayaVelocityGridExporter , UnrealVS 与 VisualStuaioDebugging 这6个插件。

    Android: 这个文件夹里主要是 安装AndroidSDK AndroidNDK 和 JDK 安装这些主要是为了在Win7平台下用Unreal4引擎直接打Android的apk包使用。

    FX_tools: 这个文件夹里主要是3DMax2012的插件。

    Maya_AnimationRiggingTools和MayaVelocityGridExporter: 这两个文件夹是Maya导出插件和编辑器工具

    UnrealVS: 这个文件中有VS2012和VS2013两个版本的UnrealVS.vsix插件,只需要双击就可以安装了。 附图:
    Unreal4 <wbr>入门(配置)
    VisualStudioDebugging: 文件夹下有一个UE4.natvis文件(.natvis 文件是带 .natvis 扩展名的 .xml 文件),同学们需要把这个文件拷贝到 安装VisualStudio2013的按照目录下,路径为Microsoft Visual Studio 12.0\Common7\Packages\Debugger\Visualizers的文件夹中。 这样同学们就可以再VisualStudio2013中的调试栏的监控里看到 Unreal4引擎自定义的特殊类型的值啦Unreal4 <wbr>入门(配置)      附图:

    Unreal4 <wbr>入门(配置)


    2. 为什么建议各位同学使用Visual Studio 2013呢,不仅仅是因为Unreal4引擎对VS2013支持的最好。在Unreal4中还有比较特殊的用途就是,当你想为你的项目添加C++代码的时候你需要点击File菜单中的Add Code to Project按钮。 下面附张图:


    Unreal4 <wbr>入门(配置)


    下面这张图 警告同学们啦,必须需要使用Visual Studio 2013才能创建新的Class。 Unreal4 <wbr>入门(配置)

    Unreal4 <wbr>入门(配置)

    大概就介绍到这里啦。

      对于大型游戏MMORPG游戏或是3D街景(虚拟现实)还有大型无缝地图都需要地图啊,关卡动态加载的机制来达到让用户感觉自己一直是在漫游,而不会出现Loading(读条),卡界面等情况。当然除非是垮区域无法依靠关卡和关卡中之间的关系做处理。


         UnrealEngine4 作为一个多年处于世界前矛的商业引擎,自然而然也为大家考虑到这个这种硬性需求。UnrealEngine4 中的动态加载大概分为3种。

         首先需要明确下几点概念。因为再同学们信息会等的前提下才会更有利于理解和相互交流。好了,不瞎扯了进入正题。

         1.地图(Map):地图这个概念在UnrealEngine4中基本上所示虚拟出来。当然我们编译完一个场景后会保存到自己的工程目录下 如:XXXX\Content\Maps\  保存的文件名叫做.umap。一个工程下可以有很多很多.umap文件,但是我们需要注意到,我们在单独保存场景时编辑器都是基于Level操作的。代码中只有一个函数是关于地图[UEngine::LoadMap]。  如下图:

    Unreal4 <wbr>入门(关卡动态加载)


        2.关卡(Level):关卡这个概念应该是在UnrealEngine4最常用使用的,在UE4编辑器中还有一个单独Levels编辑器。  如下图:

    Unreal4 <wbr>入门(关卡动态加载)


        3.世界(World):World这个概念之前在UnrealEngine3中一直跟地图的概念差不多,World下面会有很多的Levels还有八叉树场景管理器,以及一些寻路啊,对Level和Actor的管理函数。当然现在也差不多,不过没有看见八叉树,多了一种LevelActor的类,SpawnActor中创建对象为"ConstructObject"之前创建对象另一个函数需要Outer和Owner的"DuplicationObject"。


    言回正传:UnrealEngine4引擎提了我们有三种动态加载的方法,下面一一介绍。

    一. 通过使用LevelStreamingVolume的方法:

        通过Modes窗口下的Volumes找到LevelStreamingVolume,拖动到编辑器中让它覆盖住同学们两个Level,调节LevelStreamingVolume的StreamingUsage属性(比如有加载后锁定,加载,加载后显示等)。
        当我们的Pawn进入到这个LevelStreamingVolume后关卡就会对应的加载啦。  如图:

    Unreal4 <wbr>入门(关卡动态加载)

     加载类型设置属性图例

    Unreal4 <wbr>入门(关卡动态加载)

    二. 通过使用BluePrint的方法:

        通过打开关卡的Blueprints使用蓝图完成动态加载。那么在Blueprints中完成动态加载我们需要用到几个节点分别为 LoadStreamLevel和UnloadStreamLevel。 如图:

    LoadStreamLevel节点
    Unreal4 <wbr>入门(关卡动态加载)
    UnloadStreamLevel节点
    Unreal4 <wbr>入门(关卡动态加载)
        
        特别要注意的是LoadStreamLevel节点需要在MakeVisibleAfterLoad打勾,不然不会显示的呦。第二个暴露变量ShouldBlockonLoad打上勾会,不会被UnloadStreamLevel节点卸载(同学们自行按照需求选择呦)。还有一定要在Leves编辑器中把修改动态加载方法中的[总是加载]改成[蓝图]喔,不然通过Blueprints无法控制动态加载的。


    三. 通过写代码的方式加载

        在需要切换动态加载关卡的时候,调用[UGameplayStatics::LoadStreamLevel]函数来加载想要使用的关卡。
        大概流程是创建一个FStreamLevelAction,这个Action回去读暴露参数的包遍历所有Level关系找到指定关卡,然后ActivateLevel这个关卡激活的时候会有加载或者卸载关卡。

    PS:
        这几天一直在回忆之前使用UnrealEngine4学过的知识,也同时在看UnrealEngine4的新代码,如果出现概念混淆的情况或者叙述错误的情况,请各位同学指出并与我交流Unreal4 <wbr>入门(关卡动态加载)。  有机会请你们吃饭,喝咖啡。

    C++和蓝图

    概述

    蓝图可以继承C++类,从而使得程序员可以在代码中创建新的游戏性类,而关卡设计人员可以使用蓝图来继承该类并对其进行修改。 有很多种修饰符可以改变C++类和蓝图系统间交互方式,其中某些修饰符会在本示例中突出介绍。

    类设置

    在类设置的第一部分中,使用C++类向导创建一个名称为LightSwitchBoth 的类。

    LightSwitchBoth类中的大部分代码设置都和仅使用C++LightSwitch示例类似。尽管您可以让一个蓝图继承LightSwitchCodeOnly类,
    但蓝图图表并不能访问该类中创建的组件、属性及函数。该示例将使用 UPROPERTY() 和 UFUNCTION() 修饰符,这两个修饰符使得LightSwitchBoth作为继承它的蓝图的模板。

    您会发现首先参考下 仅使用C++LightSwitch示例是有用的,这样您可以看下如何设置头文件及源文件 来创建LightSwitchComponentSphereComponentDesiredBrightness属性及OnOverlap函数。

    这个头文件是从 仅使用C++LightSwitch示例 改编而来,添加了以下功能:

    PointLightComponentSphereComponentBlueprintReadOnly(仅蓝图可读的),并且将显示在 我的蓝图 选卡中的 Switch Components(切换组件) 类目中。

    OnOverlap现在是一个BlueprintNativeEvent,将会显示在 我的蓝图 选卡中的 Switch Functions(切换函数) 类目中。

    DesiredBrightnessBlueprintReadWrite(蓝图可读写的),将显示在 我的蓝图 选卡中的 Switch Properties(切换属性) 类目中。

    DesiredBrightness现在是EditAnywhere(随处可编辑的),而不是VisibleAnywhere(随处可见的)

    UCLASS() 宏有个 Blueprintable 修饰符。在这个示例中,该修饰符不是必须的,因为LightSwitchBoth直接继承Actor,而ActorBlueprintable(可蓝图化的),所以LightSwitchBoth会继承该修饰符。

    加上 UPROPERTY() 和 UFUNCTION() 宏中的额外修饰符,LightSwitchBoth类的头文件如下所示:

    LightSwitchBoth.h

    // Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.

     

    #pragma once

     

    #include "LightSwitchBoth.generated.h"

     

    UCLASS()

    class ALightSwitchBoth public AActor

    {

        GENERATED_UCLASS_BODY()

     

       

        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Switch Components")

        TSubobjectPtr PointLight1;

     

       

        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Switch Components")

        TSubobjectPtr Sphere1;

     

       

        UFUNCTION(BlueprintNativeEvent, Category="Switch Functions")

        void OnOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

     

       

        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Switch Properties")

        float DesiredBrightness;

    };

     

    在LightSwitchBoth的源文件中,构造器仍然是一样的。但是,需要对 OnOverlap 函数做一点修改。这个函数现在是一个BlueprintNativeEvent。这意味着 在继承这个类的蓝图中,可以放置一个覆盖 OnOverlap 的事件,当正常调用该函数时会执行此事件。如果该事件不存在,那么则是执行那个函数的 C++实现。要想使这个设置正常工作,该C++函数需要重命名为 OnOverlap_Implementation 。稍后在本示例中将介绍这个蓝图设置。对 OnOverlap 函数 进行了修改后,LightSwitchBoth 的源文件如下所示:

    LightSwitchBoth.cpp

    // Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.

     

    #include "BasicClasses.h"

    #include "LightSwitchBoth.h"

     

    ALightSwitchBoth::ALightSwitchBoth(const class FPostConstructInitializeProperties& PCIP)

        Super(PCIP)

    {

     

        DesiredBrightness 15.0f;

     

        PointLight1 PCIP.CreateDefaultSubobject(this, "PointLight1");

        PointLight1->Brightness DesiredBrightness;

        PointLight1->bVisible true;

        RootComponent PointLight1;

        Components.Add(PointLight1);

     

        Sphere1 PCIP.CreateDefaultSubobject(this, TEXT("Sphere1"));

        Sphere1->InitSphereRadius(250.0f);

        Sphere1->OnComponentBeginOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlap);        // set up notification for when this component overlaps something

        Sphere1->OnComponentEndOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlap);      // set up notification for when this component overlaps something

        Sphere1->AttachParent RootComponent;

        Components.Add(Sphere1);

    }

     

    void ALightSwitchBoth::OnOverlap_Implementation(AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)

    {

        if OtherActor && (OtherActor != this) && OtherComp )

        {

            PointLight1->ToggleVisibility();

        }

    }

    当创建类时,新的 UCLASS() UFUNCTION() /或 UPROPERTY() 宏意味着该代码必须在Visual Studio Xcode中进行编译,然后使用虚幻编辑器重新加载它们。 关闭虚幻编辑器,在Visual Studio Xcode中编译该项目,然后打开编辑器并重新加载该项目,以确保正确地重新加载该游戏模块。同时,需要注意的一点是, 要确保 Build Configuration(版本配置) 和您打开该项目使用的虚幻编辑器可执行文件的版本一致。 请在 编译游戏项目文档中阅读关于编译配置及编译项目的更多信息。

    当重新打开虚幻编辑器并重新打开您的项目后,便可以创建一个新的类蓝图了。 在本示例中,选择LightSwitchBoth作为该蓝图的父类,蓝图名称为LightSwitchBoth_BP 


    Unreal4 <wbr>入门 <wbr>使用C++和Blueprints

    在 C++代码中添加的PointLightComponentSphereComponent 也会显示在 Blueprint Editor(蓝图编辑器) 的 组件模式中的 Components(组件) 选卡内。 它们的图标是深蓝色,表示它们是从父类LightSwitchBoth类继承而来的原生组件。而刚刚添加到 LightSwitchBoth_BP 蓝图中的新组件的图标 是浅蓝色的。关于使用 Components(组件) 选卡添加及排列组件的更多信息,请参照 组件选卡文档。

    Blueprint Editor(蓝图编辑器) 的 图表模式是蓝图编辑的核心。在 Graph Mode(图表) 模式中,您可以在我的蓝图选卡中添加新变量、 函数。您也可以访问该类蓝图中包含的 所有 图表。在这些图表中,各种节点连接到一起,来创建由类属性、游戏事件、甚至Actor的周边环境 驱动的设计及游戏功能。

    在 Graph Mode(图标模式) 中, My Blueprint(我的蓝图) 选卡显示了在C++中添加到LightSwitchBoth类中的 PointLightComponent SphereComponent 。这是因为 BlueprintReadOnly 修饰符存在的缘故。 通过在 我的蓝图 选卡中点击并拖拽这些组件的名称到图表中,可以将这些组件的节点添加到图表中。然后,您可以把这些节点连接到改变像可见性 或光源颜色这样属性的节点上。DesiredBrightness 属性也会出现在 我的蓝图 选卡中。因为它是一个属性,而不是一个组件,所以可以使用 BlueprintReadWrite 修饰符。这意味着在蓝图图表中可以创建节点来获取及设置 DesiredBrightness 的值。请参照 我的蓝图文档来获得一般的应用信息。

    默认情况下,可能不会显示父类LightSwitchBoth的组件和属性。因为当选中 我的蓝图 选卡底部的 Show user-created variables only(仅显示用户创建的变量) 复选框时, 会隐藏从父类继承的属性。

                         显示所有变量

    Unreal4 <wbr>入门 <wbr>使用C++和Blueprints

                 仅显示用户创建的变量

    Unreal4 <wbr>入门 <wbr>使用C++和Blueprints

    有两个图表用于设置 LightSwitchBoth_BP 类的行为。第一个是构造脚本图表,它包含了一个专用的 Construction Script(构建脚本)
    事件。如果没有该 Construction Script 设置,那么新的 LightSwitchBoth_BP Actor 将仅使用LightSwitchBoth的构造函数。然而,当Actor在关卡中移动时,及当 Desired Brightness 发生改变时,都会执行 Construction Script 。使用 Construction Script 意味着,可以轻松地改变暴露给蓝图的Actor属性, 并且可以快速地看到这些修改的效果。

    在 LightSwitchBoth_BP 类中, Construction Script 事件连接到了 Set Brightness 节点上,以便当在关卡中添加或移动Actor时或者 Desired Brightness 发生改变时,将 Point Light 1 (PointLightComponent) 的亮度设置为 Desired Brightness 的值。


    Unreal4 <wbr>入门 <wbr>使用C++和Blueprints


    LightSwitch_BPOnly 类中设置的另一个图表是 事件图表 EventGraph的执行是由事件触发的。在这个示例中, 任何时候当调用C++函数 OnOverlap 时,OnOverlap 就会执行。在LightSwitchBoth的源文件中,设置了代理,以便当一个Actor进入或离开SphereComponent时会执行 OnOverlap 

    Sphere1->OnComponentBeginOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlap); // set up notification for when this component overlaps something Sphere1->OnComponentEndOverlap.AddDynamic(this, &ALightSwitchBoth::OnOverlap); // set up notification for when this component overlaps something

    OnOverlap 事件节点连接到了 Set Light Color 节点上。任何时候当执行该事件时,它都将会把PointLightComponent的光源颜色设置为一个随机颜色。这覆盖了 源码文件中用于切换的PointLightComponent可见性的 OnOverlap_Implementation 函数。

    关于事件及处理图表的更多信息,请参照事件、 事件图表事件模式 文档。


    Unreal4 <wbr>入门 <wbr>使用C++和Blueprints

    在变量的设置中, DesiredBrightness 变量设置为 EditAnywhere (随处可编辑) ,所以在 蓝图编辑器 默认模式中它是可见的,并且可以进行编辑。 这意味着对于类的每个实例,这个变量是可以变化的,所以每个Actor可以有其自己的 DesiredBrightness 。因为 DesiredBrightness 也是 BlueprintReadWrite(蓝图可读写) 的,且 Construction Script 中使用了它,所以更新它还会导致再次执行 Construction Script 

    其他Class Blueprints(类蓝图)可以继承由蓝图创建的类,通过以下两种方式实现:使用 Class Viewer(类别查看器) 中的类附近的下拉列表按钮来创建一个新蓝图, 或者通过右击该蓝图并选择 Create New Blueprint Based on This(基于此蓝图创建一个新蓝图) 

    类蓝图 LightSwitchBoth_BP 位于 内容浏览器中,您可以从那里将其拖拽到关卡内。它也存在于 类别查看器中。 关于使用 内容浏览器 或 类别查看器 在关卡放置Actor的更多信息,请参照放置Actors 文档。

     

     


    虚幻引擎4设置Visual Studio

    设置Visual Studio和虚幻引擎4协同工作有利于提高开发人员使用UE4 的效率和整体用户体验。

    推荐设置

    以下是为结合使用Visual Studio和虚幻引擎4的开发人员推荐的设置。

    • 关闭 Show Inactive Blocks(显示不活动的代码块) 。如果您不关闭此项,在文本编辑器中,很多代码块会呈现出灰掉 状态。(Options(选项) > Text Editor(文本编辑器) > C/C++ > Formatting(格式)) 

    • 打开IntelliSense(智能编码)和"squiggles(波浪线提示)"功能,让它们正常运行。(请参照Intellisense(智能编码), Live Errors(实时错误)和Squiggles(波浪线提示)部分)

    • 在Visual Assist X (VAX)中关闭 Format After Paste(粘帖后格式化) 功能。这个功能有时候会导致格式变得混乱。(VAX Options(VAX选项) > Advanced(高级) > Corrections(校正))

    • 在解决方案浏览器中停用 External(外部) 文件夹, 它们会扰乱视图。( 在 Options(选项) > Text Editor(文本编辑器) > C/C++ > Advanced(高级) Disable External Dependencies Folder(禁用外部依赖文件夹) )

    • 如果不需要 Edit & Continue(编辑&继续) 功能,请关闭它们。(Options(选项) > Debugging(调试) > Edit and Continue(编辑并继续))

    • 关闭 Error List(错误列表) 窗口。如果启用该功能,当您的代码中出现合法错误时 Error List(错误列表) 窗口会自动弹出 。但是,当和虚幻引擎结合应用时, Error List(错误列表) 会显示不正确的错误信息。建议您最好 禁用该窗口,并使用 Output(输出) 窗口来查看您的代码错误。这个窗口将仅显示 真正的错误。要想禁用Error List(错误列表)窗口:

      • 如果 Error List(错误列表) 窗口处于打开状态,请关闭它。

      • 从 Tools(工具) 菜单中, 打开 Options(选项) 对话框。

      • 选择 Projects and Solutions(项目和解决方案) 并取消选中 Always show error list if build finishes with error(如果编译中出现错误总是显示错误列表) 选项。

    Intellisense(智能编码)、Live Errors(实时错误)和Squiggles(波浪线提示)

    虚幻引擎4项目现在可以正常支持 IntelliSense(智能编码)功能,包括实时Error List(错误列表) 和 "squiggles(波浪线提示)"! (请参照以下介绍获得如何启用它的信息。)

    VC10的IntelliSense功能可以在您编写代码的过程中重新编译C++。这比仅检查 VAX的语法强大很多: VC10使用完整的C++编译器,可以验证每一行代码。这个功能非常强大并且将会 加快您的工作流程!

    VC++ Intellisense Squiggles

    当其和波浪线提示功能结合使用时,如果您正在查看的文件有任何IntelliSense 错误,都可以在Error List(错误列表)中看到。 您可以通过Error List(错误列表)的右击菜单来打开或关闭该功能。

    VS 2010 Error List

    由于Squiggles(波浪线提示)功能不能和虚幻引擎4项目协同工作,您可能已经禁用了它们。请确保点击 C/C++ Advanced(高级)选卡,并使用以下设置。

    VC++ Advanced Options

    当您打开一个C++文件时,您可以通过查找这个图标来判断IntelliSense编译器是否正在“工作”:

    Intellisense Progress Indicator


    实现细节

    • 当编写代码时显示波浪线提示有时候要花几秒钟的时间。

      • 这是因为我们有很多包含文件,且IntelliSense目前不使用预编译头文件。

    • 有时候您会看到“误报的”IntelliSense 错误。以下是几种可能的原因。

      • IntelliSense编译器(EDG)比MSVC编译器更严格。

      • 某些针对IntelliSense的#defines设置和正常编译时的设置不同。

      • IntelliSense编译的C++总是被当做32位对待。

    • 如果绝对需要,您可以把代码封装到 #ifdef __INTELLISENSE__ 中,以消除波浪线提示。

    • IntelliSense的错误的表达方式和VC++ 编译器的错误的表达方式略有不同。他们只是表达不同而已。

    • 头文件中的Squiggles(波浪线提示)功能通过编译包含它的已知 .cpp 对应的头文件来进行工作。

      • 有时候IntelliSense把这个功能搞乱了,导致您会在头文件中看到波浪线提示。

    • 如果需要,您可以增大 Max Cached Translation Units(最大缓存变换单元) 设置。

      • 它会使用更多的内存,但可能会提高一点反应速度。

    • 有少量C++文件还不能和IntelliSense相兼容。

    • Unreal Build Tool有一个新的 -IntelliSense 选项。

      • 这将为我们的所有项目文件产生IntelliSense属性表。

      • 当添加了新的模块或者项目包含发生改变时仅需要重新运行它即可。

    UnrealVS 插件

    Visual Studio的UnrealVS插件使您可以在使用虚幻引擎开发时轻松地访问常用操作。

    unrealvs_toolbar_cmd.png

    功能包括:

    • 设置启动项目

    • 编译启动项目的可绑定命令

    • 设置命令行参数

    UnrealVS插件不能和Visual Studio 2012精简版协同工作。它仅能和Visual Studio 2012 专业版相兼容。

    请参照UnrealVS插件页面 获得设置及使用该插件的信息。


    调试

    Visual Studio支持通过‘可视化查看器’来扩展调试器,从而轻松地查看常见的虚幻数据类型, 比如对象FNames 和动态数组。根据您所使用的Visual Studio 2010或Visual Studio 2012的不同, 这个功能的设置也有所区别。

    针对Visual Studio 2012的可视化查看器设置

    您会发现您的安装文件中包含了具备该可视化查看器逻辑的文件:

    [ROCKETINSTALL]/Engine/Extras/VisualStudioDebugging/UE4.natvis

    复制该文件到以下位置:

    [VSINSTALLDIR]/Common7/Packages/Debugger/Visualizers/UE4.natvis [USERPROFILE]/My Documents/Visual Studio 2012/Visualizers/UE4.natvis

    继续研究Blueprint,这次主要看看C++和Blueprint的结合方法。官方文档依然没有太大用处,但在wiki上还是有很多值得学习的文章的。当中有个叫Rama的家伙贡献了相当多的教程,他还写了一个很不错的插件,而且将源代码和实现的思路都写在了一个wiki页面里,对社区的帮助很大,MVP应该是没得跑了,要是多一些这样的人UE4就能更快地成熟并推广了。

    不过在动手写代码之前,我首先把那个忍无可忍的VS2013自带的Intellisense给关掉了,我是完全按照官方文档的指引配置了所有的参数,但实际用起来却奇慢无比,再小的工程敲几行代码后要等二十几秒自动完成才能蹦出来,右下角那个处理提示符就几乎没消失过。而且代码帮助还非常不稳定,时有时无,另外还经常给出一些错误的提示。忍不了了,还是装了Visual Assist,瞬间一切都那么顺手又顺眼了。

    工具搞定后,先来看看如何在C++中创建可以在Blueprint中使用的全局函数:

    • 创建一个继承自UBlueprintFunctionLibrary的C++类即可。不知道为什么在Editor中不能直接创建基于UBlueprintFunctionLibrary的C++类,但我们可以在VS中自己修改一下基类
    • 继承自UBlueprintFunctionLibrary类中,凡是具备BlueprintCallable属性的UFUNTION即可在Blueprint中被调用
    • 如果UFUNCTION还带有BlueprintPure属性,那么意味着这个函数不会修改任何游戏状态,因此无需exec链的触发(在Blueprint中体现为没有白线输入),可以在任何时刻被调用获取其结果
    • 作为随时可被调用的全局函数,都需要被声明成static函数

    下面是具体代码:

    MyBPLibrary.h:

    复制代码
     1 // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
     2 
     3 #pragma once
     4 
     5 #include "MyBPLibrary.generated.h"
     6 
     7 
    10 UCLASS()
    11 class UMyBPLibrary : public UBlueprintFunctionLibrary
    12 {
    13     GENERATED_UCLASS_BODY()
    14         
    15     UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Test")
    16         static FString GetHappyMessage();
    17 
    18     UFUNCTION(BlueprintCallable, Category = "Test")
    19         static bool SaveToFile(FString Dir, FString Name, FString Text, bool Overwrite = false);
    20 
    21     UFUNCTION(BlueprintCallable, Category = "Test")
    22         static bool MakeDir(FString Dir);
    23 };
    
    复制代码

    MyBPLibrary.cpp:

    复制代码
     1 // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
     2 
     3 #include "HelloWorld.h"
     4 #include "MyBPLibrary.h"
     5 
     6 
     7 UMyBPLibrary::UMyBPLibrary(const class FPostConstructInitializeProperties& PCIP)
     8     : Super(PCIP)
     9 {
    10 
    11 }
    12 
    13 FString UMyBPLibrary::GetHappyMessage() {
    14     return FString("Hello, I'm Happy!");
    15 }
    16 
    17 bool UMyBPLibrary::MakeDir(FString Dir) {
    18     return FPlatformFileManager::Get().GetPlatformFile().CreateDirectory(*Dir);
    19 }
    20 
    21 bool UMyBPLibrary::SaveToFile(
    22     FString Dir,
    23     FString Name,
    24     FString Text,
    25     bool Overwrite 
    26 ) {
    27     IPlatformFile& F = FPlatformFileManager::Get().GetPlatformFile();
    28     if (!F.DirectoryExists(*Dir))
    29     {
    30         F.CreateDirectoryTree(*Dir);
    31         if (!F.DirectoryExists(*Dir))
    32         {
    33             return false;
    34         }
    35     }
    36 
    37     Dir += "\\";
    38     Dir += Name;
    39 
    40     if (!Overwrite)
    41     {
    42         if (F.FileExists(*Dir))
    43         {
    44             return false;
    45         }
    46     }
    47 
    48     return FFileHelper::SaveStringToFile(Text, *Dir);
    49 }
    
    复制代码

    这个例子中实现了3个全局函数:GetHappyMessage,MakeDir以及SaveToFile,其中GetHappyMessage为无副作用的函数。它们在Blueprint中就可以这么用了:

    在调试的过程中遇到的一些问题在这里说一下:

    • 在Rama的例子中,对文件的操作都是基于GFileManager,但在实际写代码时发现这个全局变量不存在,只能通过FPlatformFileManager来实现相关操作,可能是Rama写教程之后UE4的代码又发生过变化
    • 在Blueprint中,那些紫色的节点代表一个String类型的输入,但是这里需要注意:在输入框里不要将字符串包围在双引号之间了,也不要对特殊字符转义,系统会帮你处理。一开始不清楚在这里卡了好久
    • 如果你自己的类是继承自PlayerController,那么可以使用ClientMessage来输出一些调试信息;但如果不是(比如上面的这个例子),则可以使用UE_LOG宏,宏的用法和Rama教程里的用法也不太一样了,需要自己去研究一下

    通过在C++中实现供Blueprint调用的全局函数,就实现了Blueprint和C++交互的一种常用途径。后面再写一些其他交互方式的实现方法。


    C++触发Blueprints事件

    如果想实现只供某一个类使用的Blueprint函数,方式是类似的,只是不要再继承UBlueprintFunctionLibrary类,同时函数也无需再声明成static即可。

    虽然能够在Blueprint中调用一个C++实现的方法是很不错,但在实际中我们还会需要其他的交互方式,比如由C++代码去触发一系列的Blueprint动作,以及让Blueprint能够和C++类的某些属性变量直接进行交互。

    我们先来看看如何将C++类中的某些属性变量暴露出去,让Blueprint(或Editor)能够看见、读或写这些变量,从而实现和C++的通信。

    其实非常简单:只需要在C++类的头文件中这样声明一下就可以了:

    1 
    2     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerMusicSkill")
    3     int32 MusicSkillLevel;
    

    只需要使用UPROPERTY宏,在加上一些枚举属性,就可以让一个变量以开发者希望的方式暴露给Blueprint,其中:

    • EditAnywhere表示该变量可以在Editor中任意进行修改,而VisibleAnywhere则表示Editor中只能看、但无法修改这个变量,还有几个其他的可选项供选择,可以自行研究代码
    • BlueprintReadWrite表示该变量可以在Blueprint中读或写,BlueprintReadOnly则表示在Blueprint中只能读
    • Category表示在Editor和Blueprint列表中这个变量归到那一分类,这主要是一个方便开发者寻找的功能,没有其他特别作用
    • 头部的注释不仅仅是代码中的注释,它也会作为这个参数的帮助提示显示在Editor的界面上

    上面的代码在编译后,只需要在Editor中基于这个类创建一个Blueprint,然后就能够在它的Default属性界面看到下面的内容:

    相当不错,而且简单。下面再来看看关键的:如何让C++去触发Blueprint,同时给Blueprint传递信息?

    其实也非常简单,主要是使用UFUNTION+BlueprintImplementableEvent属性:

    1 UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "Music skill is GOOD"))
    2         virtual void MusicSkillGood(int32 CurrentSkill);
    

    其中:

    • BlueprintImplementableEvent表示下面定义的函数会触发Blueprint里的一个事件,但事件触发后如何处理则由Blueprint自行实现,C++代码不负责,它只负责在适当的时候调用下面的函数并传递参数数据而已
    • meta相关内容和Category类似,主要是给用户提供一个更容易分辨的信息。在这里这个自定义事件在Blueprint中就会被显示为“Music skill is GOOD”,没有其他作用
    • MusicSkillGood就是用来在C++中触发Blueprint事件的函数,它一定要被定义为虚函数,而且返回值一定要为void,因为这个函数的实现不由C++来做,它只是提供一个触发的手段,且所有的数据都通过其参数传递给Blueprint

    完整的类代码如下:

    MyPlayerController.h:

    复制代码
     1 // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
     2 
     3 #pragma once
     4 
     5 #include "GameFramework/PlayerController.h"
     6 #include "MyPlayerController.generated.h"
     7 
     8 
    11 UCLASS()
    12 class AMyPlayerController : public APlayerController
    13 {
    14     GENERATED_UCLASS_BODY()
    15     
    16     
    17     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerMusicSkill")
    18     int32 MusicSkillLevel;
    19 
    20     UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "Music skill is GOOD"))
    21         virtual void MusicSkillGood(int32 CurrentSkill);
    22 
    23     virtual void PlayerTick(float DeltaTime) OVERRIDE;
    24 };
    
    复制代码

    MyPlayerController.cpp:

    复制代码
     1 // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
     2 
     3 #include "HelloWorld.h"
     4 #include "MyPlayerController.h"
     5 
     6 
     7 AMyPlayerController::AMyPlayerController(const class FPostConstructInitializeProperties& PCIP)
     8     : Super(PCIP)
     9 {
    10 
    11 }
    12 
    13 void AMyPlayerController::PlayerTick(float DeltaTime) {
    14     Super::PlayerTick(DeltaTime);
    15 
    16     if (MusicSkillLevel > 50)
    17     {
    18         MusicSkillGood(MusicSkillLevel);
    19     }
    20 }
    
    复制代码

    上面代码的主要逻辑就是在每个Tick检查当前类实例的MusicSkillLevel变量值是否大于50,如果是,则对Blueprint触发MusicSkillGood事件,并将MusicSkillLevel的值传递过去。最终在Blueprint中可以这样用:

    这个Blueprint的逻辑就是:

    • 每当用户按M键,就将MusicSkillLevel变量的值加1
    • 而如前所述,C++代码会在每个Tick检查MusicSkillLevel的值是否大于50,如果大于50了,那么就会在每个Tick都触发一次MusicSkillGood事件(由于meta的设置,这个事件被显示成“Music Skill is GOOD”)
    • 当用户按了足够多的M键导致MusicSkillLevel变量的值超过50时,在游戏中就能看到MusicSkillLevel的当前值在刷屏了

    到此为止,Blueprint已经和C++代码实现了完全的交互:Blueprint能够主动调用C++中的函数,C++也能主动触发Blueprint的事件,而且双方还能通过暴露的变量进行交互。这样一来,整个游戏的底层平台模块完全可以用C++实现,然后给上层的Blueprint提供调用接口,由Blueprint来利用、组织这些模块来实现上层的完整游戏逻辑。这种结合方式既保留了C++的性能优势,又充分利用了Blueprint的易用性和灵活性来让游戏开发保持快速地迭代。这应该就是UE4所推崇的最佳开发模式。

       接触UnrealEngine4大概有快两周了,从安装配置到编辑器的熟悉,再到官方实例的学习以及Blueprint的应用。从UE3的UnrealScript和各种classes到UE4现在的发开方式,昨天大概拟定了一个UE4引擎探究的计划,下周会围绕计划展开研究。

        这几天再看UnrealEngine4的代码,在写代码的过程中有些注意事项跟大家分享一下,也算给自己做个记录Unreal4 <wbr>C++使用注意事项

    一. 最好不要自己在UnrealEngine4的工程中添加代码文件,尤其是.h文件。因为UE4的UnrealHeaderTool会根据UnrealEngine4的反射机制自动生成一个.generated.h文件(应该是UnrealBuildTool需要注册并做反射用)。添加代码最好是通过编辑器的创建类向导创建。  如图例:

    Unreal4 <wbr>C++使用注意事项
        如果想用更多的类作为父类的话,可以点击“右上角”显示所有类。这样的话比如我们想做一个管理器类不需要其他逻辑业务功能我们就可以在 显示所有类 中选择一个UObject作为父类喽,配图如下:

    Unreal4 <wbr>C++使用注意事项
    点击"显示所有类"后,如图:

    Unreal4 <wbr>C++使用注意事项

    二. UnrealEngine4的C++代码有套自己的浅规则,如同Unity3D的限制版C#一样。请各位同学们不要忙着抱怨Unreal4 <wbr>C++使用注意事项,经过了13多年承载和UnrealScript的经验想必Epic不会自找苦吃把自己开发饭碗搞的很糟糕。目前笔者看到的优点是拥有GC机制,支持Blueprint和编辑器的反射机制,UnrealBuildTool的运行时编译,还有一些自动化生成功能。闲话不多说,来点干货先。

      1. 声明类时需要添加UCLASS()宏,可以带参数用来标示在编辑器中的名称,暴露类别,显示类别,类别构造,API类型,Blueprint类型,配置文件=名称。
    例如:

    Unreal4 <wbr>C++使用注意事项
      2. 声明变量时需要添加UPROPERTY()宏,可以带参数用来标示 在哪里时可见,高级显示类型,属于哪个类别,标签[类似注释]。
    例如:
    Unreal4 <wbr>C++使用注意事项
     3. 在XXXX.h文件中引用其他头文件,请各位同学一定要在把#include "xxx.h" 放到这个XXXX.h文件#include "XXXX.generated.h" 前,不然会报错呦。
    例如:
    Unreal4 <wbr>C++使用注意事项

    4. 下周UnrealEngine4就要更新4.1版本了,最近UE4还属于公测版有不少不稳定的地方,当然官方的更新的速度也很快。在目前这个情况下笔者比较建议采用Unity3D脚本开发的程序结构。做一个自己的逻辑模块聚合到自己的GameMode或者WordSettings下。再由自己的逻辑模块去驱动游戏逻辑调用或者驱动UnrealEngine4的其他模块,开发者把大部分精力放在逻辑模块的架构上和引擎功能模块的调度上,不要上来就想去从GamePlay的入口去改引擎底层的逻辑架构。

    原因如下:
    1). UnrealEngine4引擎目前还不是很健壮,可能会在开发流程和开发模式上做出变动。
    2). UnrealEngine4试图把很多精力放在把大家想Blueprints上去引导,大力推动开发者用Blueprints完成游戏开发。游戏逻辑和Blueprints关联很紧密,如果处理不好久有点得不偿失了会浪费大量时间和精力。


    预祝大家开发顺利,欢迎随时沟通 互相学习和进步Unreal4 <wbr>C++使用注意事项


    展开全文
  • epic games宣布ue4免费使用之后,吸引了大批看好VR和AR前景的游戏开发者。不过国内ue4教程和资料太少,而且一大部分资料都是关于蓝图(Blueprint)的,好在官网放出了guide和demo。更多讨论,可以前往讨论区:...

    转载自52VR 原文章链接http://www.52vr.com/article-639-1.html

    epic games宣布ue4免费使用之后,吸引了大批看好VRAR前景的游戏开发者。

    不过国内ue4教程和资料太少,而且一大部分资料都是关于蓝图(Blueprint)的,好在官网放出了guide和demo。更多讨论,可以前往讨论区:http://www.52vr.com/forum-93-1.html


    本文先演示一个如何在UnrealEngine上创建一个C++项目,然后实现一个可用按键控制物体的示例:

    1. 安装Unreal Engine,在此不做详细说明。从官网上下载安装,然后注册epic games账号。如果要下源码,需要绑定Github账号,等到EpicGames自动邀请之后才能浏览源码。


    2. 新建项目:

    安装好之后,启动UnrealEngine,选择 新建项目-> c++ -> 基础代码

     

    等加载完之后,选择文件->新建c++类,然后在如下界面选择继承Pawn(Pawn是可由玩家控制或者AI控制的物体的基类):


    我在创建的时候取类名为CollidingPawn,  创建完之后会自动打开vs2012(如果没装会提示你装一个,其他版本比如vs2015也不行,只能是2012),生成一个CollidingPawn.cpp和CollidingPawn.h。

    头文件如下所示, 我按照自己的理解加了注释:

    CollidingPawn.h:

      

    [代码]:

    01#pragma once
    02 
    03 
    04 
    05#include "GameFramework/Pawn.h"
    06 
    07#include "CollidingPawn.generated.h"
    08 
    09 
    10 
    11UCLASS()
    12 
    13class DEMO__API ACollidingPawn : public APawn
    14 
    15{
    16 
    17    GENERATED_BODY()
    18 
    19 
    20 
    21public:
    22 
    23    // 构造函数,可在此方法中放置物体和参数
    24 
    25    ACollidingPawn();
    26 
    27 
    28 
    29    // 游戏开始调用此方法
    30 
    31    virtual void BeginPlay() override;
    32 
    33     
    34 
    35    // 如果PrimaryActorTick.bCanEverTick设置为true,则每一帧都会调用此方法。如果处于性能的考虑,可以将其关闭。
    36 
    37    virtual void Tick( float DeltaSeconds ) override;
    38 
    39 
    40 
    41    // 在此函数中绑定按键和方法
    42 
    43    virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
    44 
    45};



    接下来,我们在原来的基础上,来实现按键控制物体的小程序

    先创建一个可见的球体:

    在CollidingPawn.cpp的构造函数ACollidingPawn::ACollidingPawn()中添加一个球体,一个网格组件(mesh),一个弹簧臂和相机,代码如下:


    [代码]:

    01//创建一个球体
    02 
    03    USphereComponent* SphereComponent = CreateDefaultSubobject(TEXT("RootComponent"));
    04 
    05    //设置为根组件
    06 
    07    RootComponent = SphereComponent;
    08 
    09    //设置半径
    10 
    11    SphereComponent->InitSphereRadius(40.0f);
    12 
    13    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));
    14 
    15 
    16 
    17    // 创建并放置网格物体组件,这样我们能看到球体的位置
    18 
    19    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject(TEXT("VisualRepresentation"));
    20 
    21    //如果不把网格附加到SphereComponent 就看不到球体
    22 
    23    SphereVisual->AttachTo(RootComponent);
    24 
    25    static ConstructorHelpers::FObjectFinder      SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
    26 
    27    if (SphereVisualAsset.Succeeded()){
    28 
    29        SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
    30 
    31        SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
    32 
    33        SphereVisual->SetWorldScale3D(FVector(0.8f));
    34 
    35    }
    36 
    37 
    38 
    39    //  使用弹簧臂来让相机获得一种平滑、自然的运动。
    40 
    41    //  弹簧臂的目的是让视角跟SphereComponent保持一定距离,如果不加,效果像fps游戏的第一视角一样
    42 
    43    USpringArmComponent* SpringArm = CreateDefaultSubobject(TEXT("CameraAttachmentArm"));
    44 
    45    SpringArm->AttachTo(RootComponent);
    46 
    47    SpringArm->RelativeRotation = FRotator(-45.f, 0.f, 0.f); //45度角
    48 
    49    SpringArm->TargetArmLength = 400.0f; //弹簧臂长度
    50 
    51    SpringArm->bEnableCameraLag = true;
    52 
    53    SpringArm->CameraLagSpeed = 3.f;
    54 
    55 
    56 
    57    // 创建相机并附加到弹簧臂
    58 
    59    // 如果没有相机 什么都看不到
    60 
    61    UCameraComponent* Camera = CreateDefaultSubobject(TEXT("ActualCamera"));
    62 
    63    Camera->AttachTo(SpringArm, USpringArmComponent::SocketName);



    然后配置按键: 打开ue编辑器, 选择编辑->项目设置-> 输入, 然后在右边的axis mappings加入如下设置:

    MoveForWard,MoveRight,Turn,Turn_Y 可自定义,表示跟各个按键的绑定关系。

    然后创建一个类CollidingPawnMovementComponent继承自PawnMovementComponent(控制pawn移动的组件),我们可以把WASD绑定的行为绑定到这个component上,然后把该component绑定到我们刚才创建的球体上:

    CollidingPawnMovementComponent.cpp


      

    [代码]:

    01#include "Demo.h"
    02 
    03#include "CollidingPawnMovementComponent.h"
    04 
    05 
    06 
    07void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
    08 
    09{
    10 
    11    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    12 
    13 
    14 
    15    // Make sure that everything is still valid, and that we are allowed to move.
    16 
    17    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
    18 
    19    {
    20 
    21        return;
    22 
    23    }
    24 
    25 
    26 
    27    // Get (and then clear) the movement vector that we set in ACollidingPawn::Tick
    28 
    29    FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;
    30 
    31    if (!DesiredMovementThisFrame.IsNearlyZero())
    32 
    33    {
    34 
    35        FHitResult Hit;
    36 
    37        SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);
    38 
    39 
    40 
    41        // If we bumped into something, try to slide along it
    42 
    43        if (Hit.IsValidBlockingHit())
    44 
    45        {
    46 
    47            SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
    48 
    49        }
    50 
    51    }
    52 
    53};


    然后在CollidingPawn.h中加入如下代码:

    [代码]:

    1class UCollidingPawnMovementComponent* OurMovementComponent;
    先将movementComponent绑定到刚才加的球体上,在CollidingPawn构造函数底部加入如下代码:

    [代码]:

    1// Create an instance of our movement component, and tell it to update the root.
    2    OurMovementComponent = CreateDefaultSubobject<ucollidingpawnmovementcomponent>(TEXT("CustomMovementComponent"));
    3    OurMovementComponent->UpdatedComponent = RootComponent;</ucollidingpawnmovementcomponent>
    为了让游戏中的其他类知道CollidingPawn目前正在使用CollidingPawnMovementComponent作为移动控制组件,需要在CollidingPawn.h中加入以下代码:

    [代码]:

    1virtual UPawnMovementComponent* GetMovementComponent() const override;
    然后在CollidingPawn.cpp中加入:

    [代码]:

    1UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const
    2{
    3    return OurMovementComponent;
    4}
    刚才我们已经将新创建的移动控制组件绑定到了球体上,现在需要把WASD触发的函数绑定到移动组件上,在CollidingPawn中实现往前移动,往左移动,转动视角的三个方法:

    [代码]:

    01// 往前(后)移动
    02void ACollidingPawn::MoveForward(float AxisValue)
    03{
    04    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
    05    {
    06        OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);
    07    }
    08}
    09 
    10// 往左(右)移动
    11void ACollidingPawn::MoveRight(float AxisValue)
    12{
    13    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
    14    {
    15        OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);
    16    }
    17}
    18 
    19// 左右转动视角
    20void ACollidingPawn::Turn(float AxisValue)
    21{
    22    FRotator NewRotation = GetActorRotation();
    23    NewRotation.Yaw += AxisValue;
    24    SetActorRotation(NewRotation);
    25}
    然后将这三个方法在ACollidingPawn::SetupPlayerInputComponent中注册:

    [代码]:

    1void ACollidingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
    2{
    3    Super::SetupPlayerInputComponent(InputComponent);
    4 
    5    InputComponent->BindAxis("MoveForward", this, &ACollidingPawn::MoveForward);
    6    InputComponent->BindAxis("MoveRight", this, &ACollidingPawn::MoveRight);
    7    InputComponent->BindAxis("Turn", this, &ACollidingPawn::Turn);
    8}
    以上就完成了一个可用WASD移动和鼠标控制左右视角的球体
    如果上下移动视角,可仿照以上的ACollidingPawn::Turn方法,将NewRotation.Yaw += AxisValue; 改为NewRotation.Pitch += AxisValue;即可


    展开全文
  • unreal4 中文入门教程,该系列浅显易懂,特别适合那些有些C++基础的同学作为unreal4入门教程。 区别于那些动辄几十集的视频教程,这套系列中文图文教程 能节省您大量的观看时间。

    首先要说的是,游戏开发是一项高度复杂的代码开发工作,编程语言只是最基本的知识,它涉及的内容还有计算机图形学、3D数学、物理学等复杂的学科。但是若需要学完这么多知识才能开发游戏,恐怕许多人都已经断气了,更谈不上开发游戏了。所以前人就把各种复杂的代码封装起来,使得一般的游戏开发者可以更加接近游戏的逻辑和功能性方面的代码,而无需接触最底层的知识。

    194023hhhqhbpcqpmpltad

    所以说游戏引擎,可以是引擎开发者已经写好的一堆代码框架,使得我们可以去调用这些底层代码,也可以是像虚幻4还附带可视化关卡编辑器的工具(Unity3D也是可视化的游戏引擎,后面会谈当今主流游戏引擎的对比)。

    为什么选用虚幻4引擎?

    首先,现在流行而且出名的商业引擎主要有cocos2dx,Unity3D,UE4,CryEngine等。但是这里选择UE4,也有笔者认为的独特优势。

    1) UE4是开源的。开源就是代码是完全开放的,为什么开源如此重要?一方面是因为只有我们看到源代码的实现细节,当出错了我们才能快速准确地判断出错的成因,节省被错误折腾的时间。(你想想像Unity3D这种闭源引擎,要是出错了,你是完全看不到为什么会发生错误的。除了不断盲目Debug,查文档和谷歌之外自己对于错误束手无策。)另一方面,开源可以使得我们深入学习引擎的原理,只知其然不知其所以然必然不能走得太远,而且会走得更痛苦。

    2) UE4的画质是世界上数一数二的。游戏的画质往往由游戏引擎来决定的,一个好的游戏引擎它可以模拟出极度逼真或者极具美感的画面。读者可以自己去看看Unity3D制作的游戏和UE4制作的游戏,其精美程度是相差甚远的。(这里并不是完全指责Unity3D,毕竟它们面对的是不同的层次。)作为一名追求极致的游戏程序员,当然要想看看最好的效果是怎么实现的。

    3) UE4免费!无需多言,还有比免费更好的事吗?

    下图为UE4游戏引擎制作出来的极度逼真游戏画面,你分得清这是不是现实吗?

    虚幻4游戏引擎有何强大之处?

    第一代虚幻游戏引擎(英文名是Unreal Engine,简写UE)在1998年由Epic Games公司发行。当时Epic Games公司为了适应游戏编程的特殊性需要而专门为虚幻系列游戏引擎创建了一种名为UnrealScript的编程语言,该语言让这个游戏引擎变得非常容易方便,因而这个游戏引擎开始名声大振。

    接着,2002年,Epic发布了下一代游戏引擎UE2。这时候,在虚幻引擎提供的关卡编辑工具UnrealEd中,能够对物体的属性进行实时修改。它也支持了当时的次世代游戏机,像PlayStation2,XBox等。

    到了2006年,Epic发布了下一代游戏引擎UE3,这可能是最受欢迎和广泛使用的游戏引擎。这时候的UE3又发布了一个极其重要的特性,那就是Kismet可视化脚本工具,Kismet工作的方式就是以用各种各样的节点来连接成一个逻辑流程图。其最牛逼的地方在于,使用Kismet你甚至不需要掌握任何编程知识。你可以借助Kismet使得不需要写一行代码来开发一个完整的游戏。 

    到了2014年5月19日,Epic发布了Unreal4,目前最新也是Unreal4。这次版本换代也是有了巨大的改变,它已经完全移除了UnrealScript语言,并且用C++语言来代替它。在之前的版本,如果你想修改这个引擎来开发你自己的游戏,你必须用UnrealScript,也就意味着你要学习一门新的语言。不过现在,如果你要修改这个引擎,你可以用C++来完成。这对于绝大部分习惯于C++的游戏引擎工程师来说,使用自己热爱的C++语言来工作,绝对是一件天大的喜事啊。 

    不但如此,游戏引擎的源代码已经可以从Github开源社区下载。这意味着开发者对游戏引擎有着绝对的控制权,实质上你可以修改任何任何东西,包括物理引擎、渲染和图形用户界面。 

    它也提供了一些叫热更新的功能。什么叫热更新呢?通常,如果你想对游戏的代码进行一些修改,你必须要停止游戏才能进行修改,然后再次运行看看修改后游戏的效果。然而,使用热更新功能,你可以修改游戏而不需要停止或暂停游戏。任何在游戏代码的改变会即时更新,并且你可以看见它会在游戏中实时反映出来。 

    UE4是跨平台的,你可以用来制作Xbox One、PlayStation4(包括索尼的Project Morpheus虚拟现实设备),Windows PC,Linux,Mac OSX,HTML5,iOS和安卓,就连虚拟现实设备Oculus Rift也支持。 

    另一个重大的改变是,在2015年初,虚幻4已经可以完全免费下载和使用了,之前的版本是需要支付一定费用的。现在,你可以用来开发游戏,并且发行,而且不需要为UE4游戏引擎支付一分钱。只有在你赚到了3000美元收益之后,你才需要支付5%的技术使用费。 

    另一个UE4提供的特性是商城,你可以在商城中购买和上传游戏资源。这些游戏资源可以包括动画,3D建模,材质,声音效果,预制游戏等等。这也是一个令没有游戏资源或者没有人力来开发资源的开发者振奋的消息。它们可以商场购买并直接应用于自己的游戏中。开发者也可以上传自己的工作成果到商城来赚钱。 

    这个虚幻4小白系列教程,是面向于没有使用过UE4的新手,但需要一点点C++的知识(但也无需太多,一般读过任何一本C++教材都能看懂本教程)。我们从非常基础的下载安装引擎开始,到更高级的上传作品到谷歌PlayStore,都会涉及。我们会使用UE4来一步一步地制作我们的游戏,Let’s Start From it,你的游戏开发之路!

    下图为UE4游戏引擎制作出来的官方示例宣传视频画面:



    展开全文
  • Unreal+Engine+4+AI+Programming+Essential....pdf Kindle 电子书文件: Unreal+Engine+4+AI+Programming+Essential....rar VR热门内容: 实时演算: 根据已知设备 头盔,两个手柄。 外加玩家的...

    PDF文件:

    Unreal+Engine+4+AI+Programming+Essential....pdf

    Kindle 电子书文件:

    Unreal+Engine+4+AI+Programming+Essential....rar


    VR热门内容:

    实时演算:

    根据已知设备 头盔,两个手柄。 外加玩家的几个测量参数 实时演算 玩家手,手臂,手肘,动作。

    如可以增加一些外设,如鞋子,腰带。可对玩家的四肢,腰部进行准确的实时演算。

    由此可以对游戏角色进行准确控制。

    真实的材质模型 + AI:

    不用说,模拟的就是人类。

    VR网络多人:

    与人沟通很重要。

    展开全文
  • 当你运行我们上次做完的项目,你可能会意识到我们移动的摄像机还是默认的那个摄像机,这个默认的摄像机可以自由飞翔。这一节,我们要使得开始的角色是我们的一个Avatar类的实例对象,并且使用键盘控制我们的角色。...
  • epic games宣布ue4免费使用(游戏发布之后,每个季度大于3000美元则收取收益的5%)之后,吸引了大批看好VR和AR前景的游戏...本人也是第一次接触ue4,甚至除了在大学学的c++基础,毕业3年还没碰过c++,所以先将官网的g...
  • 对于大型游戏MMORPG游戏或是3D街景(虚拟现实)还有大型无缝地图都需要地图啊,关卡动态加载的机制来达到让用户感觉自己一直是在漫游,而不会出现Loading(读条),卡界面等情况。...UnrealEngine4
  • Unreal Engine 4 初学者教程:开始 原文:Unreal Engine 4 Tutorial for Beginners: Getting Started 作者:Tommy Tran 译者:kmyhy Unreal Engine 4 是一个游戏开发工具集,能够开发从 2D 手机游戏到 3A ...
  • Unreal4 入门(安装)

    2017-09-25 15:23:50
    在Win7下安装Unreal4 在Win7下安装Unreal4需要以下几个步骤: 1. 打开“控制面板”的“程序和功能” 检查是否已安装 Microsoft Visual C++ 2010 Redistributable ,请同学们先卸载掉,否则下面安装...
  • 为什么使用UE4提供的容器类? 如果你用过C++的STL库,你就知道STL提供了各种各样的容器/数据结构,使得你对处理很多数据的时候非常快捷高效。UE4同样也提供了类似的库,库里面的类型是以T开头的,使用UE4提供的...
  • 在本教程的过程中,我们会创建新的 虚幻引擎 项目,向其添加新的C++类,然后编译项目并添加新类的实例到关卡中。 在完成后,我们会看到以C++来编程的 Actor 在屏幕上的移动。 =============================...
  • Unreal4 入门(配置)

    2019-10-07 04:44:42
    这次主要是简单介绍下Unreal4引擎使用前的配置 和VisualStudio2013调试插件的配置 1. 在Unreal4安装目录下找到路径为Unreal Engine\4.0\Engine\Extras 的文件夹。如下图: 可以很清晰的看到有 Android ,FX_...
  • 本想写一系列虚幻4引擎入门的博客,发现呢文字+图片的方式表达上...Unreal Engine 4开发快速入门 项目代码和资源下载:https://github.com/neil3d/UnrealVTM CSDN学院:http://edu.csdn.net/course/detail/1515 ...
  • 为了展示对话框,我们需要自定义一个HUD(heads-up display,即平视显示器)。 什么是HUD? HUD是平面显示界面,就是平时我们玩3D游戏提供给玩家的2D菜单界面。HUD类提供了渲染文字、贴图、矩形和材质的渲染,...
  • UE4 c++ 简要入门

    2019-02-01 11:00:28
    1. c++ 与蓝图 C++实现Gameplay的构建模块,蓝图用这些模块实现有意思的Gameplay 创建流程 通过UE4内的类向导生成,避免自己直接去VS里创建 指定适合的父类 UProperty(): 暴露变量给编辑器 EditAnywhere &...
  • UE4中,除了TArray动态数组外,还提供了各种各样的模板容器。这一节,我们就介绍集合容器——TSet。类似于TArray,尖括号里面的T是模板类型,可以是任何C++类型。一个集合表示了一组互不重复的数据元素。比如TSet...
  • 官方 官方文档 中文版 http://api.unrealengine.com/CHN/ 英文版 https://docs.unrealengine.com/en-us/ 虚幻学院(英文教程,未来可能有汉化) https://academy.unrealengine.com/ ...C++ 【吕鑫】【VS20...
  • 入门VR游戏开发者在Unreal Engine 4上开始VR设计所需要知道的 游戏开发者 VR2048(vr2048) · 2016-01-12 18:38 首先,不要被标题吓到,这其实是一篇面向游戏开发者的入门科普文章,对于有致于开发...
1 2 3 4 5 ... 20
收藏数 1,079
精华内容 431
关键字:

c++ unreal4 入门