从Unity引擎过度到Unreal4引擎(最终版)
原文地址:http://demo.netfoucs.com/u011707076/article/details/44036839前言 寒假回家到现在已经有十多天了,这些天回家不是睡就是吃....哎╮(╯▽╰)╭,今天早上一觉醒来,突然得知,UE4免费了,这绝对是个好消息,前不久我还在纠结怎么申请校园账号呢o(╯□╰)o。迫不及待打
原文地址:http://demo.netfoucs.com/u011707076/article/details/44036839
前言
寒假回家到现在已经有十多天了,这些天回家不是睡就是吃....哎╮(╯▽╰)╭,今天早上一觉醒来,突然得知,UE4免费了,这绝对是个好消息,前不久我还在纠结怎么申请校园账号呢o(╯□╰)o。迫不及待打开电脑下载了UE引擎的一个类似管理的客户端,在里面最醒目的一栏,看到一个令人哭笑不得的导航,如下图:
EPIC这是要逆天的节奏吗?不过不管他了,接下来,我们便一同学习一下EPIC提供给我们的这篇从Unity过渡到UE4的经验之谈吧。说明一下,下面我将对这篇文章中的重点内容做翻译和一些自己的见解,仅供参考,若需更详细的内容,请访问官方提供的文档手册。
那我们就开始吧
The Editor 编辑器
两个编辑器的布局如下:
Editing Assets编辑资源
Detail面板就是负责编辑工程资源,类似于Unity里面的Inspector。
Quick Glossary(Glossary:术语)
两个引擎的部分术语对比:
Category | Unity | UE4 |
---|---|---|
Gameplay Types | Component | Component |
| GameObject | Actor, Pawn |
| Prefab | Blueprint Class |
Editor UI | Hierarchy Panel | World Outliner |
| Inspector | Details Panel |
| Project Browser | Content Browser |
| Scene View | Viewport |
Meshes | Mesh | Static Mesh |
| Skinned Mesh | Skeletal Mesh |
Materials | Shader | Material, Material Editor |
| Material | Material Instance |
Effects | Particle Effect | Effect, Particle, Cascade |
| Shuriken | Cascade |
Game UI | UI | UMG (Unreal Motion Graphics) |
Animation | Animation | Skeletal Animation System |
| Mecanim | Persona , Animation Blueprint |
2D | Sprite Editor | Paper2D |
Programming | C# | C++ |
| Script | Blueprint |
Physics | Raycast | Line Trace, Shape Trace |
| Rigid Body | Collision, Physics |
Runtime Platforms | iOS Player, Web Player | Platforms |
Projects and files工程和文件
So what are all these directories and files?工程目录和文件的具体内容?
Just like Unity projects, Unreal projects always exist in their own directory and have their own project file. You can double-click on .uproject files to load your game into the Unreal Editor, or right click for additional options. Project folders have various sub-folders that contain your game's content and source as well as various configuration files and binaries. The most important are the Content and Source sub-folders.就像Untiy的工程一样,Unreal4的每一个工程都有他们单独的工程文件夹。可以通过双击.uproject 文件打开工程,或者通过右键查看更多选项。UE4的工程文件夹包含很多子文件夹和文件,里面最重要的是Content和Source 文件夹。
Where do I put my assets?我应该把资源放在那里?
In UE4, each project has a Content folder. Similar to a Unity project's Assets folder, this is where your game assets are stored. To import assets into your game simply drop files into your project's Content directory and they will be automatically imported and appear in the Content Browser. The assets in the editor will update automatically as you make changes to the files using an external program.UE4的工程文件夹里面的Content文件夹和Unity的Asset文件夹类似,用来存放游戏资源。可以通过拖拽的方式,载入资源,对资源进行处理过后,UE4工程将会自动在Content文件夹和ContentBrowser面板中更新资源信息。
What common file formats are supported?支持的文件格式
UE4所能支持的一些文件格式
Asset Type | Supported Formats |
---|---|
3D | .fbx, .obj |
Texture | .png, .jpeg, .bmp ,.tga, .dds, .exr, .psd, .hdr |
Sound | .wav |
Fonts | .ttf, .otf |
Videos | .mov, .mp4, .wmv |
How is my Scene stored?场景文件是如何存储的呢?
In Unity you place GameObjects in a scene and save that as a Scene asset file. Unreal has a Map file that is similar to a Unity Scene. Map files store data about your Level and the objects in it, as well as lighting data and certain level-specific settings.Unity中我们把GameObject放置到场景里面,并以场景资源的形式存储。在UE4的工程中Map文件类似于Unity中的Scene文件。Map文件存储了关卡里面的物体,同样的包括光照信息,和关卡本身特定的属性。
How do I change my project's settings?如何更改工程设置
All project settings can be found from the main menu under Edit / Project Settings. Like Unity's project settings, these allow you to specify information about your project (such as project name and icons), configure game input bindings, and define how the engine behaves when running your project. You can learn more about individual project settings here. Unity also has what's called "player settings". In Unreal, these are "platform settings", and can be found under the "Platforms" category in your project settings.
可以在Edit / Project Settings 工程设置中更改工程的名字啊,图标啊,设置输入的绑定信息啊,定义引擎如何在你的项目中运行,还可以选择平台。
Where do my source files go?源文件是如何运行的
In Unity you're accustomed to placing C# source files in your assets folder.在Unity中,我们习惯于把C#文件放置在资源文件夹Assets里面。
UE4 works differently. For projects that have C++ code, you'll find a "Source" sub-folder under the project directory that has various files, including C++ source (.cpp) and header (.h) files, as well as some build scripts (.Build.cs, .Target.cs) However, Blueprint-only projects won't have a Source folder.但是UE4却不是这样的。对于用C++创建的UE4,你将会在游戏工程文件夹下找到Source子目录,里面存放了包含.h,.cpp和各种文件。然而通过蓝图创建的工程没有Source文件夹。
The easiest way to get started with C++ in UE4 is to use the editor to Add Code to Project (in the main File menu), or to simply create a new C++ project from scratch from one of the many templates. You can find C++ classes right in the Content Browser and can open the files in Visual Studio or Xcode by double-clicking on their icons.UE4中开始使用C++最简单的方式是通过编辑器中的 Add Code to Project 命令。或者通过C++工程模板创建的工程只需要在ContentBrowser里面双击代码就可以用VS打开了。
From GameObjects to Actors 从GameObjects到Actors
Where Is My GameObject?Unit中GameObject在UE4中如何体现?
In Unity, a GameObject is a "thing" that can be placed in the world. The UE4 equivalent(等价) is an Actor. In the Unreal Editor, you can drag a new Empty Actor into the viewport from the Placement panel:
在Unity中,GameObject是一个可以放置在世界里面的东西。UE4中的Actor与之等价,在编辑器里面,我们可以拖放一个空的actor到世界里面。
You could build a game out of Empty Actors, but UE4 also includes special(特定的) types of Actors with built-in features, such as a Pawn (for players or AI objects), or Character (for animated creatures.) Just like Empty Actors, you can drop these special types of Actors down, then add or customize their properties and components. You'll learn more about it later, but for now try to remember that UE4 has a Gameplay Frameworkthat works with these special Actors.
你可以使用一个空的Actor来创建自己的游戏,但是UE4内置了很多有特定功能的Actor类型,比如Pawn(是针对players和AI角色),Character(针对有动画的生物)。和普通的空Actor一样,我们可以拖拽这些Actors到场景试图,并且定制他们的属性和组件。稍后我们将学到这部分内容,但是最重要的是记住,UE4有一个 Gameplay Framework 系统来使用这些Actors工作。
Actors in UE4 are a bit different than GameObjects in Unity. In Unity, GameObject is C# class which you can't directly extend. In UE4, Actor is a C++ class which you can extend and customize using inheritance. We'll talk about this more later on!
UE4中的Actors和Unity中的GameObject有很多不同。Gameob是C#的类,不可以直接扩展。而在UE4中,Actors是c++的类,你可以扩展并且拖过继承的方式自定义。稍后我们将继续学到这部分内容。
Where Are My Components?Unity中的组件在UE4中如何体现?
In Unity, you add components to a GameObject to give it functionality.在Unity中我们可以通过给一个物体组件来给他添加功能。
In UE4, you add components to Actors. After you've dropped an Empty Actor in your level, click the Add Component button (in the Details panel) and choose a component to add. Here, we're creating a torch by dropping an empty actor, then adding a mesh component for the base, followed by a light source and then a particle system to create its flame.空物体--添加组件(mesh、light、particle )制作火把,看下图即可
1.拖放空Actor,为其添加StaticMesh组件
2.在Mesh组件的层级上,添加点光源组件
3.Mesh上添加例子Particle组件
In Unity, a GameObject hold a flat list of components, but in UE4 an Actor actually contains a hierarchy of components attached to one another. You can see this in the example above, where the Light and Particle are attached to the Mesh. This has some important implications discussed later in Complex Actors and GameObjects.
Unity中一个GameObject的所有组件的关系是平行的,但是在UE4中,一个Actor的组件之间可以存在层次关系。如上面火把的例子中,Light和Particle组件就是依附在Mesh组件上。等下将会在Complex Actors and GameObjects这一节中讨论更多重要的概念。
From Unity prefabs to UE4 Blueprint Classes Unity中的prefabs对应UE4中对应蓝图类
Unity's workflow is based on prefabs. In Unity you build a set of GameObjects with components, then create a prefab from them. You can then place instances of the prefab in your world, or instantiate them at runtime.
Unity的工作流程是基于prefabs的,我们创建一系列具有组件的GameObjects,然后通过他们创建预设,然后我们就可以拖放一个实例到世界中或者在运行的过程中动态生成实例。
UE4's corresponding workflow is based on Blueprint Classes. In UE4, you build an Actor with components, select it, and click the "Blueprint / Add Script" button (in the Details panel). Then, choose a place to save your Blueprint Class, and click "Create Blueprint" to save your new Blueprint Class!
UE4中相对应的工作流程是基于蓝图类的。在UE4中,你可以你可创建一个拥有组件的Actor,选中它,并且在Details面板中点击 "Blueprint / Add Script"按钮,然后选择一个位置存放蓝图类,最后点击保存。
Your new Blueprint Classes can be found in the Content Browser. You can double-click to edit them directly, or you can drag and drop them into any level.我们新创建的蓝图类可以再Content Browser面板中找到,我们可以通过双击他们直接打开,并且我们可以把它们拖放到任意的关卡之中。
Where is Script Component and MonoBehaviour? Unity中的脚本组件和MonoBehaviour中在UE4中如何体现?
In Unity you have Script Components that you drop on GameObjects to add C# scripting. You create a class that inherits from MonoBehaviour to define what that component does.
在Unity中,我们可以给GameObject添加C#脚本,这个脚本继承自MonoBehaviour 来定义组件的功能。
UE4 has something similar. You can create whole new Component classes of your own and drop those onto any Actor. You can create Component classes using either Blueprint Scripting or C++.
So how do you create your own component class in UE4? In the Detail panel's Add Component drop-down, you see you can create new components, or choose existing ones:
UE4中也有一些类似的东西。我们可以创建完全空的组件并且把它们赋给Actor(对比Unity中需继承MonoBehaviour )。我们可以通过C++或者蓝图的形式创建组件。在UE4中如何创建自己的独有的组件呢?答案是在Detail面板中的 Add Component 下拉选项中,我们可以创建新的组件或者选择已有的组件。
In Unity, when creating a new MonoBehaviour you, will be given a skeleton(概要?) class file with a Start() function and an Update() function.
在Unity中,当我们创建一个新的MonoBehaviour 时,会提供给我们一个包含Start()函数和Update()函数的类。
In UE4, you will also be given a skeleton class with a InitializeComponent() function and a TickComponent() function, which perform functions similar to Start and Update.
If you create a Blueprint Script Component you will be given these same functions as visual nodes:
在UE4中,系统也将提供给我们两个函数,他们分别是 InitializeComponent() 函数和 TickComponent()函数,这两个函数和Unity中Start()函数和Update()函数类似。当我们创建一个蓝图脚本组件的时候,系统也将提供给我们两个具有类似功能的可视化节点。
Scriptable Actor Blueprint Classes 可以编辑的Actor蓝图类
Here is a cool feature in UE4: Your new Actor Blueprint Class can have its own Blueprint Visual Scripting! This allows you to add logic to an entire object, not only an individual component. Combined with inheritance (explained below), this gives you a lot of flexibility when designing your game.UE4中有一个非常酷的功能:你新建的 Actor蓝图类(此处不是组件蓝图类)可以使用蓝图来实现可视化编辑。这意味着你可以对整个物体添加逻辑,而不仅仅是这个物体中一个特定的组件。这将在你设计自己的游戏中提供更大的灵活性。
In addition to Blueprint Classes supporting visual scripting, UE4 also supports C++ Classes implemented with code. Here are both, side-by-side.
除了可以可视化编辑的蓝图脚本之外,UE4也支持通过代码实现功能的C++类。下面给出了三个的对应关系。
Unity c#
- using UnityEngine;using System.Collections;public class MyComponent : MonoBehaviour{ int Count; // Use this for initialization. void Start () { Count = 0; } // Update is called once per frame. void Update () { Count = Count + 1; Debug.Log(Count); }}
- #pragma once#include "GameFramework/Actor.h"#include "MyActor.generated.h"UCLASS()class AMyActor : public AActor{ GENERATED_BODY() int Count; // Sets default values for this actor's properties. AMyActor() { // Allows Tick() to be called PrimaryActorTick.bCanEverTick = true; } // Called when the game starts or when spawned. void BeginPlay() { Super::BeginPlay(); Count = 0; } // Called every frame. void Tick(float DeltaSeconds) { Super::Tick(DeltaSeconds); Count = Count + 1; GLog->Log(FString::FromInt(Count)); }};
UE4 Blueprint Classes can be extended。 UE4的蓝图类可以被扩展
Unity prefabs and UE4 Blueprint Classes can be instantiated in your game similarly. However, Unity has complications related to nesting prefabs within other prefabs, which limit their role as extensible building blocks.
In UE4, you can create a new Blueprint Class which extends an existing Blueprint Class and augments it with new properties, components, and visual scripting functionality.Untiy的prefabs预设和UE4的蓝图类能够在你的游戏中相似的实例化出来。然而,Unity有一些并发机制,他们和预设与预设之间的嵌套相关,这些机制决定或者说限制了他们成为可以在构建时被扩展(这儿有点难理解,看下面的例子吧)。
For example, in UE4 you can create a Blueprint Class named Monster(怪物) which implements basic monster functionality such as chasing people. You can then create further Blueprint Classes which extend it, such as Dragon (a type of Monster which adds fire-breathing features), Grue (a Monster which is likely to eat you when it's dark), and for example 8 others. These subclasses of Monster all inherit the basic functionality from Monster, and add new capabilities on top.
In Unity, you would implement this by creating many different GameObject prefabs: one for Dragon, one for Grue, and so on. Now, say you want to add some new functionality to all monsters, such as the ability to speak using your new Speak Component. In Unity, you have to go and update all 10 prefabs to individually copy and paste the new functionality into it.
在Unity中,你的世界通过创建不同的GameObject实例(比如一个作为龙怪,一个作为雪怪等等)来实现这一功能。现在,如果你想给所有的这些怪物添加一些新的功能,比如使用你新创建的Speak组件让他们有能力说话,在Unity中,你不得不对这十个实例单独的更新,来为它们添加功能。
In UE4, you can simply modify the Monster Blueprint Class to add this new ability to speak. That's all! Dragon, Grue, and the 8 other subclasses of Monster automatically inherit the new speaking functionality, and you don't need to touch them.
在UE4中,你可以简单的修改最初的父类怪物蓝图脚本类添加新的说话功能,仅仅这么做就够了,无论是龙怪,雪怪或者其他八种Monster父类的子类都会自动的继承新的说话的功能,你都不用去单独的指定它们。
But there's more! Everything we have said here about Blueprint Classes also applies to C++ Classes, and everything is equally true of actors and components. These systems are designed to support large-scale development of extensible functionality, and can scale to projects with 10's or 100's of developers.但是不止如此,我们在这里说的一切蓝图类也适用于c++类,包括组件和Actor类。这些系统是为了扩展而被设计的,包括开发大规模可扩展的功能,以及项目开发10人到100人的开发人员人数的扩展。(一字一字的翻译就是:“这些系统是为了用来支持大规模开发可扩展的功能,并且可以扩展项目10或100的开发人员所设计的”,反正就是这么一个意思,容易扩展)。
Should I use Blueprint Scripting, C++, or both?我应该使用C++,蓝图还是都使用呢?
Blueprint Visual Scripting is ideal for simple in-game logic flow and sequencing of actions. It's a great system for designers, artists, and visually-oriented programmers, because it's easy to access and control in-game objects visually. You can even create small standalone-game using just Blueprints; see the Tappy Chicken sample for a full-fledged example.蓝图这种可视化的编辑脚本对于简单的游戏逻辑和一些简单操作的排序是理想的。对于设计者,艺术家和一些以视觉为导向的程序员来说,蓝图脚本是一个非常棒的系统,因为我们可以非常方便通过可视化的方式实现和控制游戏物体。甚至,你可以仅仅使用蓝图来创建小的单独的游戏。可以参考Tappy Chicken例子来查看这部分的具体实现。
C++ programming is for larger-scale tasks, such as building gameplay systems, complex AI, and new engine features. If you already have some C++ experience, check out the Introduction to C++ Programming in UE4 page.C++编码是用来做一些大规模的任务的,比如创建游戏的框架,复杂的AI和一些新的引擎的功能。如果你有一些C++的经验,可以之间去查看 Introduction to C++ Programming in UE4 这一页。
Most projects will use a mix of Blueprints and C++. Many developers prototype game functionality using Blueprints, because it is so easy and fun, and later move some or all of it to C++ for performance and engineering rigor.大多数的工程会混合使用蓝图脚本和C++脚本。许多开发者愿意使用蓝图脚本规范游戏的功能,因为它非常简单有趣,然后不就考虑到规范,和性能问题,会把其中的一部分甚至全部移植到C++程序。
Blueprint Classes can extend C++ Classes 蓝图类可以用C++类扩展
Much of the magic of UE4 game development comes from the interplay between programmers implementing new features in C++, with designers and artists utilizing them in Blueprints and then asking for more! Here's how a team might structure a UE4-based shooter game implementing pickups using a mix of C++ Classes systems programming, and Blueprint Classes for behaviour and appearance:UE4游戏开发的魔力来自蓝图脚本和C++脚本的共同作用。程序员使用C++实现新功能,设计师和艺术家在蓝图脚本中使用它们,实现新的功能,在需要新功能时再向程序员提出。下面是一个实例,展示了一个团队如何同时使用C++构建一个射击游戏的框架,使用蓝图类用来实现具体行为和一些外观等功能。
Transform Components Transform组件
In Unity each GameObject has a Transform component, which gives the GameObject a position, rotation, and scale in the world.
在Unity中,每一个GameObject都有一个Transform组件,它赋予了GameObject在世界里的位置、旋转和缩放属性。
Similarly in UE4, Actors have a Root Component, which can be any subclass of Scene Component. A Scene Component gives the Actor a location, rotation, and scale in the world which is applied hierarchically to all components underneath it. Many of the components that you'll use are subclassed from Scene Component, because it's really useful to have a position!同样的在UE4中,Actors有一个叫做RootComponent的组件,它可以是场景组件SceneComponent的任意一个子类。场景组件使得Actor在世界中拥有位置、旋转、缩放属性,而这些Acotor和属性是在Scene组件之下分层出现的。
Even if you place an Empty Actor, UE4 will create a "Default Scene Root" for that actor, which is just a plain(朴实无华,朴素) Scene Component. If you drop a new Scene component in of your own, it will replace the Default Scene Root.甚至,如果当你放置一个空的Actor,UE4都会为他创建一个没有其他特殊功能的默认的SceneRoot。如果你为它添加了一个新的自定义的场景组件,这个组件将会取代默认的SceneRoot。
Compound Objects 复合物体
In Unity, you create compound objects by constructing a hierarchy of GameObjects and parenting their transforms together:
在Unity中,你可以通过构造GameObject层级关系并且联合它们的transform属性来创建复合物体。
In UE4, you create compound game objects by nesting components hierarchically:
在UE4中,我们可以通过按照层级关系嵌套组件的方法来创建复合物体。
As you can see from the diagram, nested hierarchies can be created by attaching Scene Components to one another, since they have a transform - similar to parenting transforms in Unity. Actor Components (the base-class for all components) can only be attached directly to the Actor itself.就像图标中展示的一样,我们可以通过不断添加SceneComponent的方法来创建嵌套的层级关系,Actor组件(所有组件中最基础的组件)可以直接添加到Actor物体本身上。
Do I build everything out of Components? 我是通过使用各种Components来创建任何东西吗?
Its really up to you, but most often you'll use a combination(组合) of custom component types along with actor classes that use those components. We mentioned this earlier, but UE4 has many special types of Actors that guarantee(保证) a certain level of capability and always include certain components. For example, a Character always contains a Character Movement Component.这就要看自己的使用习惯了,但是最常规的方法,是结合Actor类的功能使用一些常规组件的组合。我们之前就提到过,但是Ue4也内置了很多特定类型的Actor,他们保证这些Actor拥有制定的功能并且包含了所需的组件。比如说,Character 这个Actor会包含Character Movement Component组件。
There are several sub-classed Actor types you'll quickly encounter(遇到) in the engine and are useful in almost every type of game. Here's a list of our most common built-in Actors:在UE4的引擎里你马上会遇到很多特定的Actor的子类,无论对于什么类型的游戏他们都是非常重要的,下面列出的是非常重要的内置Actor:
-
Pawn - A type of Actor representing a controllable game object, typically the player's avatar. Pawns are moved by Players and AI alike through an owning Controller.
- Pawn代表的是一种可以被控制的游戏物体,对于玩家和AI他们通过自己独有的Controller来移动。
-
Character - A more specialized version of Pawn designed for biped avatars that handles a lot of the complexity of those kinds of game objects.
- Character是Pawn的一个专门的版本,是针对能掌控各种复杂物体的人形动物设计的。
-
Controller - Possesses and controls a Pawn. By separating the Pawn from the controller, you can write AI Controllers that can manipulate a pawn using the same interface the player would.
- Controller 拥有并控制一个对应Pawn,通过把Pawn从controller中分离出来,我们可以写一些AI的控制使用相同的借口操纵pawn。
-
Player Controller - A more specialized Controller designed for getting input from a player's Gamepad, Touch, or Mouse/Keyboard, and using that input to drive the Pawn or Character they possess.
- 是一种特殊的Controller,它可以接收用户输入来控制他们所拥有的Character或者Pawn。(就是我们可以控制的)
So is everything an Actor? 难道所有的东西都是Actor吗?
Not everything. Actors are most common class used for gameplay in UE4 and the only type that can be Spawned into the World. So everything you place in your level will be an Actor.并不是这样的,Actor是UE4中用来作为游戏设置最常规的并且唯一一个可以在世界中生产的类,所以你在关卡中放置的物体都是Actor。
The other important type to know about is Object. Object is actually the base class of all Unreal classes, including Actor and many others. This is a much lower-level construct than Actor, but still has features that you'll expect from a Unreal class, such as reflection and serialization. Object is a very basic class we use when we need to define a new type that just doesn't fit the mold of an Actor. For example, Actor Component is the base class for all Components, and derives from Object instead of Actor.另外一个需要了解的重要的概念是Object。Object事实上是UE4类中最基础的类,它包含了Actor和其他很多东西,它比Actor更低级的被构造,但是也有一些你需要的功能,比如反射reflection和序列化serialization。当我们需要定义一种新的不符合Actor类型的东西的时候,Object将会作为一种最基础的类出现。比如Actor组件就是所有组件中最基础的类,他就是来源于Object,而不是Actor。
What is this Gameplay Framework thing in UE4? UE4中的GameplayFramework是什么?
Okay, so this is where things get a little crazy (in sort of an awesome way.) Unity gives you a clean slate to start designing your game, and Unreal does the same. In Unity you can build everything out of basic GameObjects and components, and in Unreal you can build everything out of Actors and components.好吧,这正是事情变得有点疯狂的时候了(一个很棒的方法)。Unity给你一张白纸开始设计你的游戏,虚幻也是如此。在Unity中你通过Gameobject和组件来构建所有的需要的东西,同样,UE4中对应的是Actor和UE4的组件。
However Unreal has this extra layer on top called the Gameplay Framework. This doesn't really exist in Unity at all. You don't have to use it in Unreal, but it's actually super cool! Basically, if you make use of some basic primitive(原始) classes and follow certain established conventions, your game will acquire some awesome features automatically that would be otherwise very difficult to implement or retrofit (such as full multiplayer support!)。然而UE4有额外的上层叫做 Gameplay Framework。在Unity中根本不存在它。你在虚幻中并不需要必须使用它,但是他的功能非常棒!基本上,如果你使用一些基本的原始类和遵循一定的既定惯例,你的游戏将自动获得一些很棒的功能,否则将很难实现或改造(如多人联网的支持)。
Countless awesome(极好的) games have been designed on top of Unreal's Gameplay Framework, and its worth taking some time to understand how it works. Yes, you could roll your own version of this. That's totally fine if you want to! But hundreds of awesome Unreal developers have made great use of this framework in UE4 today, so it's worth taking some time to learn.虚幻引擎下很多非常好的游戏都是基于虚幻的Gameplay Framework这个框架下设计的,我们非常有必要花费一些时间来了解他究竟是如何工作的。是的,你可以使用自己的方法,这是完全没有问题,但现在数百名很棒的虚幻开发人员使用这个框架的UE4,所以值得花一些时间去学习。
To use the Gameplay Framework, you really just need to learn the customized built-in actor classes included with Unreal, such as Pawn,Character and Player Controller, and eventually learn about how Unreal replication and networking features work. For now, let's get back to the basics though.为了使用到Gameplay Framework框架,我们必须学习虚幻所包含的一些自定义的Actor类,比如Pawn,Character和Player Controller,甚至学习虚幻是如何工作的,但是现在呢,我们还是回顾整体了解一些基本的概念。
How to write code in UE4 如何在UE4中编码?
So, I'm used to programming in MonoDevelop� 在Unity中我已经习惯了使用MonoDevelop编译器编码
For Blueprint scripting you'll only need Unreal Editor -- everything is built in! To write code in C++, download the free version of Visual Studio on Windows, or install Xcode on Mac. When you first create a new project (or add code to an existing project), UE4 will automatically create Visual Studio project files for you. You can open Visual Studio by double-clicking on a C++ class inside Content Browser, or by clicking the "Open Visual Studio" button in the main File menu.
蓝图脚本的编码是在UE4的编辑器中就可以完成,C++编码使用最新版的vs。苹果用户使用Xcode。如何打开就不用多说了把....(⊙﹏⊙)b
One important difference in UE4: You'll sometimes have to manually(手动) refresh your Visual Studio project files (for example, after downloading a new version of UE4, or when manually making changes to source file locations on disk.) You can do this by clicking "Refresh Visual Studio Project" in the main menu, or by right clicking on the .uproject file in your project's directory and selecting "Generate Visual Studio project files"。有一点得注意,我们有时候需要手动去更新vs文件。(比如下载了新版本的UE4,或者是做了修改)。右键点选.uproject文件选中生成文件就行,如下图。
Writing Event Functions (Start, Update, etc.) 写事件函数
If you are used to working with MonoBehaviours you are used to such methods as Start, Update, and OnDestroy. Here is a comparison between a Unity behaviour and its counterpart in UE4 Actors and components.
使用Unity我们都清楚一些start(),update(),OnDestroy()这些函数,下面我们就做一个UE4和Unity的比较。
In Unity, we might have a simple component that looks like this:
Unity中简单的组件看上去张这个样子:
- public class MyComponent : MonoBehaviour{ void Start() {} void OnDestroy() {} void Update() {}}
But remember, in UE4 you can write code right on the Actor than only coding new component types. This is actually very common and useful.
但是请记住,在UE4中,我们可以直接在Actor本身上写代码,而不是创建新的组件类型,这非常重要。
Similar to Unity's Start, OnDestroy and Update functions, we have a similar set of methods for Actors in UE4:
UE4中和Unity里面的那三个函数类似的函数:
C++ :
- UCLASS()class AMyActor : public AActor{ GENERATED_BODY() // Called at start of game. void BeginPlay(); // Called when destroyed. void EndPlay(const EEndPlayReason::Type EndPlayReason); // Called every frame to update this actor. void Tick(float DeltaSeconds);};
Components in UE4 contain different functions. Here is a simple example:
UE4中的组件包含一些不同的函数,下面列举了一些简单例子:
C++ :
- UCLASS()class UMyComponent : public UActorComponent{ GENERATED_BODY() // Called after the owning Actor was created void InitializeComponent(); // Called when the component or the owning Actor is being destroyed void UninitializeComponent(); // Component version of Tick void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction);};
Remember in UE4 It's important to call the parent class' version of method.
请记住,在UE4中,调用父类的函数的版本是非常重要的。
For example in Unity C# this would be called base.Update(), but in UE4 C++ we'll use Super::TickComponent():
比如说,在unity里面这样写:base.Update();而在UE4中则需要这样写:Super::TickComponent();
- void UMyComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction){ // Custom tick stuff here Super::TickComponent(DeltaTime, TickType, ThisTickFunction);}
You may have noticed some things begin with "A" and others with "U" in C++. The prefix "A" indicates an Actor sub-class. Where as the prefix "U" indicates an Object sub-class. There are some other prefixes too, for example "F" is used for most plain data structures or non-UObject classes.UE4的C++代码中,字母前缀'A'表示是Actor的子类,'U'表示Object的子类。当然还有一些其他的前缀,比如‘F’,表示是一些空白的数据结构或者不是Object类。
Writing gameplay code in UE4 在UE4中编写游戏代码
Okay, things are going to get a bit deeper from here on out. We'll be talking about programming topics that are critical for creating games. Because you know Unity, we'll be explaining features with slant toward C# users learning Unreal C++, but you can use Blueprint Scripting for pretty much everything if you want! We've added examples in both C++ and Blueprint where possible.
Let's talk about some of the most common gameplay programming patterns and how you'd approach them in Unreal. Many functions in Unity have a comparable function in Unreal that should seem familiar. We'll go through the most common functions one by one.
好的,从这里开始我们将更加深入了。下面我们一一介绍一些最常用的函数。
Instantiating GameObject / Spawning Actor 实例化一个物体
In Unity, we use the Instantiate function to create new instances of objects.
This function takes any UnityEngine.Object type (GameObject, MonoBehaviour, etc.), and makes a copy of it.
Unity中使用Instantiate ()函数实例化对象,如下:
- public GameObject EnemyPrefab;public Vector3 SpawnPosition;public Quaternion SpawnRotation;void Start(){ GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation); NewGO.name = "MyNewGameObject";}
In UE4, there are a couple different functions to instantiate objects, depending on your needs. NewObject is used for creating new UObject types, and SpawnActor is used for spawning AActor types.
First we will briefly talk about UObjects and NewObject. Subclassing UObject in Unreal is much like subclassing ScriptableObject in Unity. They are useful for gameplay classes that don't need to spawn into the world or have attached components like Actors do.
在UE4中,有很多不同的函数来实例化物体,需要根据你的需求来决定用哪一个。NewObject()函数是用来创建UObject类型的物体,SpawnActor()函数是用来创建AActor类型的物体。首先我们简单的谈一下UO不UObject类型和NewObject()函数。子类UObject非常像Unity中的脚本化对象类ScriptableObject(这对于只是为了存储数据的资源是很有用的),他们对于一些不需要再世界中实例化或者不像Actor一样需要添加组件的物体来说非常有用。
In Unity, if you created your own subclass of ScriptableObject, you may instantiate it like this:
Unity中这样写:
- MyScriptableObjectNewSO=ScriptableObject.CreateInstance<MyScriptableObject>();
And in Unreal, If you created your own UObject derived type, you may instantiate it like this:
UE4中,这样写:
- UMyObject*NewObj=NewObject<UMyObject>();
So what about Actors? Actors are spawned using the SpawnActor method on a World (UWorld in C++) object. How do you get the World object? Some UObjects provide a GetWorld method for you, as an example, all Actors do.
You'll notice instead of passing in another Actor, we pass in the "class" of the Actor we want to spawn. In our example the class can be any subclass of AMyEnemy.
But what if you want to make a "copy" of another object, like what Instantiate allows you to do?
The NewObject and SpawnActor functions can also be given a "template" object to work with. Unreal will make a copy of that object, instead of making one "from scratch(从头开始)". This will copy over all of its UPROPERTYs and components.
那对于Actor类型的物体如何实例化呢?Actors物体是通过使用一个UWorld类型的World物体上的SpawnActor()函数来实例化的。(也就是说如果我们想实例化一个Actor物体,首先要得到对应的UWrold类型的World物体)。那又如何得到这个World物体呢?一些UObject提供了GetWorld()函数,比如所有的Actors类就可以给你提供这个函数。观察下面的函数,我们发现,我们需要传递进来的第一个参数是我们想要实例化的Actor的类,而不是Actor本身。在我们的实例中,这个类可以使AMyEnemy的任何子类。
但是如果我想复制一个物体,我该使用哪一种盛丽华的函数呢?NewObject()函数和SpawnActor()函数都个可以提供一个“template(模板)”物体来使用。虚幻引擎将会从这个物体来复制,而不是从头开始实例化对象,这样做将会把他的所有的UPROPERTYs(属性特性)和组件拷贝到。
- AMyActor* CreateCloneOfMyActor(AMyActor* ExistingActor, FVector SpawnLocation, FRotator SpawnRotation){ UWorld* World = ExistingActor->GetWorld(); FActorSpawnParameters SpawnParams; SpawnParams.Template = ExistingActor; World->SpawnActor<AMyActor>(ExistingActor->GetClass(), SpawnLocation, SpawnRotation, SpawnParams);}
You might be wondering what "from scratch" means in this context. Each object class you create has a default template that contain default values for its properties and components. If you don't override these properties and don't provide your own template, Unreal will use these default values to construct your object. To help illustrate this, let's first look at a MonoBehaviour for example:
你也许对上面提到的“从头开始”不是很了解。其实,你创建的每一个物体的类都有一个默认的模板,它包含了物体属性和组件的默认的值,如果你不重写这些特性,不提供你的模板,虚幻引擎将使用默认的值来构造你的物体。为了更好的理解这些内容,我们首先来看看Unity中的MonoBehavior是怎么做的。
- public class MyComponent : MonoBehaviour{ public int MyIntProp = 42; public SphereCollider MyCollisionComp = null; void Start() { // Create the collision component if we don't already have one if (MyCollisionComp == null) { MyCollisionComp = gameObject.AddComponent<SphereCollider>(); MyCollisionComp.center = Vector3.zero; MyCollisionComp.radius = 20.0f; } }}
In the above example we have an int property that defaults to 42, and a SphereCollider component that defaults to a radius of 20.
We can achieve the same thing in Unreal using the object's constructor.
在上面的例子中,我们有一个整形的参数默认值为42,并且生成了一个球形碰撞器,它默认的半径是20.我们可以在UE中,使用物体的构造函数来实现相同的功能。
- UCLASS()class AMyActor : public AActor{ GENERATED_BODY() UPROPERTY() int32 MyIntProp; UPROPERTY() USphereComponent* MyCollisionComp; AMyActor() { MyIntProp = 42; MyCollisionComp = CreateDefaultSubobject<USphereComponent>(FName(TEXT("CollisionComponent")); MyCollisionComp->RelativeLocation = FVector::ZeroVector; MyCollisionComp->SphereRadius = 20.0f; }};
In the constructor of AMyActor we have set the default property values for the class. Note the use of the CreateDefaultSubobject function. We can use it to create components and assign default properties to them. All the subobjects we create using this function act as a default template, so we can modify them in a subclass or Blueprint.在AMyActor的构造函数中,我们给这个类设置了默认的参数值,要记住使用CreateDefaultSubobject()函数。我们可以使用这个函数来创建组件并且为其制定默认的参数。我们使用这个函数创建的所有子物体实际上就是一个默认的模板,因此我们可以在一个子类中或者蓝图中修改他们。
Casting from one Type to Another 类型转换
In this case we get a component we know we have, then cast it to a specific type and conditionally do something.
就是根据已有的组件转换成另一种类型来有条件的处理一些事情。
Unity C#:
- Collider collider = gameObject.GetComponent<Collider>;SphereCollider sphereCollider = collider as SphereCollider;if (sphereCollider != null){ // ...}
- UE4 C++:UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);if (SphereCollider != nullptr){ // ...}
Destroying GameObject / Actor 销毁物体
ity | C++ | Blueprint |
---|---|---|
| | |
Destroying GameObject / Actor (With 1 Second Delay) 1秒延迟销毁物体
Unity | C++ | Blueprint |
---|---|---|
| |
|
Disabling GameObjects / Actors 使物体处于不激活状态
Unity | C++ | Blueprint |
---|---|---|
|
| |
Accessing the GameObject / Actor from Component 通过组件访问物体
Unity | C++ | Blueprint |
---|---|---|
| |
|
Accessing a Component from the GameObject / Actor 通过物体访问组件
- MyComponentMyComp= gameObject.GetComponent<MyComponent>();
- UMyComponent*MyComp=Cast<UMyComponent>(MyActor->GetComponentByClass(UMyComponent::StaticClass()));
Finding GameObjects / Actors 查找物体
- // Find GameObject by nameGameObject MyGO = GameObject.Find("MyNamedGameObject");// Find Objects by typeMyComponent[] Components = Object.FindObjectsOfType(typeof(MyComponent)) as MyComponent[];foreach (MyComponent Component in Components){ // ...}// Find GameObjects by tagGameObject[] GameObjects = GameObject.FindGameObjectsWithTag("MyTag");foreach (GameObject GO in GameObjects){ // ...}// Find Actor by name (also works on UObjects)AActor* MyActor = FindObject<AActor>(nullptr, TEXT("MyNamedActor"));// Find Actors by type (needs a UWorld object)for (TActorIterator<AMyActor> It(GetWorld()); It; ++It){ AMyActor* MyActor = *It; // ...}
- // Find UObjects by typefor (TObjectIterator<UMyObject> It; It; ++it){ UMyObject* MyObject = *It; // ...}// Find Actors by tag (also works on ActorComponents, use TObjectIterator instead)for (TActorIterator<AActor> It(GetWorld()); It; ++It){ AActor* Actor = *It; if (Actor->ActorHasTag(FName(TEXT("Mytag")))) { // ... }}
Adding tags to GameObjects / Actors 给物体添加标签
- MyGameObject.tag = "MyTag";// Actors can have multiple tagsMyActor.Tags.AddUnique(TEXT("MyTag"));
Adding tags to MonoBehaviours / ActorComponents 给组件添加标签
- // This changes the tag on the GameObject it is attached toMyComponent.tag = "MyTag";// Components have their own array of tagsMyComponent.ComponentTags.AddUnique(TEXT("MyTag"));
Comparing tags on GameObjects / Actors and MonoBehaviours / ActorComponents 使用物体和组件的标签
- if (MyGameObject.CompareTag("MyTag")){ // ...}// Checks the tag on the GameObject it is attached toif (MyComponent.CompareTag("MyTag")){ // ...}// Checks if an Actor has this tagif (MyActor->ActorHasTag(FName(TEXT("MyTag")))){ // ...}
- // Checks if an ActorComponent has this tagif (MyComponent->ComponentHasTag(FName(TEXT("MyTag")))){ // ...}
Physics: RigidBody vs. Primitive Component 物理部分:RigidBody 对比 Primitive 组件
In Unity to give any GameObject physics characteristics(特性) you first give it a RigidBody component. In Unreal any PrimitiveComponent (UPrimitiveComponent in C++) can be a physical object. Some common Primitive Components are ShapeComponents (Capsule, Sphere, Box), StaticMeshComponent, and SkeletalMeshComponent.在Unity中,我们需要首先给物体一个RigidBody组件才可以给他物理的特性。在虚幻引擎中,一个 Primitive组件可以当成是一个物理的物体。一些常用的 Primitive组件有形状组件(胶囊,球体,立方体),静态网格组件和骨骼网格组件。
Unlike Unity which separates the responsibilities of collision and visualizations into separate components. Unreal combines the concepts of the potentially physical and the potentially visible into PrimitiveComponent. Any component that would have any geometry(集合) in the world, that could either be rendered or interacted(相互作用) with physically sub-classes from PrimitiveComponent.
和Unity把物理碰撞和可视化的调节分开不同,虚幻引擎把可能的物理和可视化组合在PrimitiveComponent组件中。任何一个组件都在世界中拥有集合属性,他们可以被渲染出来也可以和拥有PrimitiveComponent组件的物体相互作用。
Layers vs Channels Unity中的Layers和UE4中的Channels
In Unity, they are called "Layers". UE4 uses Collision Channels, and they work in a similar way. You can read up on them here.
他们二者很相似,你可以在这里 here阅读它们。
RayCast vs RayTrace 光线投射
Unity C#:
- GameObject FindGOCameraIsLookingAt(){ Vector3 Start = Camera.main.transform.position; Vector3 Direction = Camera.main.transform.forward; float Distance = 100.0f; int LayerBitMask = 1 << LayerMask.NameToLayer("Pawn"); RaycastHit Hit; bool bHit = Physics.Raycast(Start, Direction, out Hit, Distance, LayerBitMask); if (bHit) { return Hit.collider.gameObject; } return null;}
- APawn* AMyPlayerController::FindPawnCameraIsLookingAt(){ // You can use this to customize various properties about the trace FCollisionQueryParams Params; // Ignore the player's pawn Params.AddIgnoredActor(GetPawn()); // The hit result gets populated by the line trace FHitResult Hit; // Raycast out from the camera, only collide with pawns (they are on the ECC_Pawn collision channel) FVector Start = PlayerCameraManager->GetCameraLocation(); FVector End = Start + (PlayerCameraManager->GetCameraRotation().Vector() * 1000.0f); bool bHit = GetWorld()->LineTraceSingle(Hit, Start, End, ECC_Pawn, Params); if (bHit) { // Hit.Actor contains a weak pointer to the Actor that the trace hit return Cast<APawn>(Hit.Actor.Get()); } return nullptr;}
Triggers 触发器
Unity C#:
- public class MyComponent : MonoBehaviour{ void Start() { collider.isTrigger = true; } void OnTriggerEnter(Collider Other) { // ... } void OnTriggerExit(Collider Other) { // ... }}
- UCLASS()class AMyActor : public AActor{ GENERATED_BODY() // My trigger component UPROPERTY() UPrimitiveComponent* Trigger; AMyActor() { Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("TriggerCollider")); // Both colliders need to have this set to true for events to fire Trigger.bGenerateOverlapEvents = true; // Set the collision mode for the collider // This mode will only enable the collider for raycasts, sweeps, and overlaps Trigger.SetCollisionEnabled(ECollisionEnabled::QueryOnly); } void BeginPlay() { // Register to find out when an overlap occurs OnActorBeginOverlap.AddDynamic(this, &AMyActor::OnTriggerEnter); OnActorEndOverlap.AddDynamic(this, &AMyActor::OnTriggerExit); Super::BeginPlay(); } void EndPlay(const EEndPlayReason::Type EndPlayReason) { OnActorBeginOverlap.RemoveDynamic(this, &AMyActor::OnTriggerEnter); OnActorEndOverlap.RemoveDynamic(this, &AMyActor::OnTriggerExit); Super:EndPlay(EndPlayReason); } UFUNCTION() void OnTriggerEnter(AActor* Other); UFUNCTION() void OnTriggerExit(AActor* Other);};
更多碰撞触发信息,参阅 here.
Kinematic Rigidbodies 运动学
Unity C#:
- public class MyComponent : MonoBehaviour{ void Start() { rigidbody.isKinimatic = true; rigidbody.velocity = transform.forward * 10.0f; }}
In UE4, The collision component and rigidbody component are one. The base class for this is UPrimitiveComponent, which has many subclasses (USphereComponent, UCapsuleComponent, etc.) to suit your needs.
在UE4中,碰撞组件和刚体组件是一个东西。他们的父类是UPrimitiveComponent,他又很多子类来满足你的需求,比如USphereComponent,UCapsuleComponent等等。
UE4 C++:
- UCLASS()class AMyActor : public AActor{ GENERATED_BODY() UPROPERTY() UPrimitiveComponent* PhysicalComp; AMyActor() { PhysicalComp = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionAndPhysics")); PhysicalComp->SetSimulatePhysics(false); PhysicalComp->SetPhysicsLinearVelocity(GetActorRotation().Vector() * 100.0f); }};
Input events 输入事件
Unity C#:
- public class MyPlayerController : MonoBehaviour{ void Update() { if (Input.GetButtonDown("Fire")) { // ... } float Horiz = Input.GetAxis("Horizontal"); float Vert = Input.GetAxis("Vertical"); // ... }}
- UCLASS()class AMyPlayerController : public APlayerController{ GENERATED_BODY() void SetupInputComponent() { Super::SetupInputComponent(); InputComponent->BindAction("Fire", IE_Pressed, this, &AMyPlayerController::HandleFireInputEvent); InputComponent->BindAxis("Horizontal", this, &AMyPlayerController::HandleHorizontalAxisInputEvent); InputComponent->BindAxis("Vertical", this, &AMyPlayerController::HandleVerticalAxisInputEvent); } void HandleFireInputEvent(); void HandleHorizontalAxisInputEvent(float Value); void HandleVerticalAxisInputEvent(float Value);};
This is what your input properties in your Project Settings might look like:
在你的项目设置中可以设置输入的参数。
You can read more about how to setup input here.在这里here阅读更多输入的信息。
FAQ 常见问题
How do I load my last project automatically? 我怎么才能自动加载我上一次的工程呢?
If you are used to Unity automatically loading the last project you were working on, the same is possible in UE4. To enable, check "Always load last project on Startup" when opening a project. You can also toggle the setting at any time from the main Edit menu under Edit?Editor Preferences? Loading and Saving?Startup.
在UE4中,打开一个工程的时候选中“Always load last project on Startup”选项。
Where do I set Input Bindings for my game? 我在什么地方设置输入的绑定信息?
In Unity you're used to using the Input Manager settings for Project to setup default bindings. In UE4 it works similarly. You'll open your Project Settings then select the Input category. There, you can add various buttons (actions) and analog controls (axes). Give each control a name and default binding. Then, you can get callbacks to your game's Pawn when the input events are triggered. Check out the Input documentation pagefor the details.
How do I change the starting scene of my project? 我怎么才能改变启动场景?
You can change the startup map of your project from the project settings tab. From the main menu choose Edit?Project Settings->Maps & Modes to change the starting map.
Edit?Project Settings->Maps & Modes这里既可以设置
How do I run my game? 我怎么才能运行我的游戏?
The easiest way to run your game is to click the "Play" button on the the main editor toolbar, which will run the game right inside the editor's process. If you want to run it as a standalone application, click the dropdown arrow next to "Play" and choose "Standalone Game". Finally, if you want to run on a mobile device or in a web browser, you'll use the "Launch" button on the toolbar (after installing any prerequisites that are needed for that platform.)
What units are these? 应该使用什么样的单位?
In Unity the primary unit of measurement is one meter. In UE4 the primary unit of measurement is one centimeter.UE4中最基本的单位是厘米。
So if you move something 1 unit (meter) in unity that is equivalent to moving something 100 units (centimeters) in UE4.
If you want to move something 2 Feet in Unity that would be 0.61units (meter) and in UE4 is 61 units (centimeters).
What is with this coordinate system? Which way is up? 坐标系统怎么使用?
Both Unity and UE4 use a left-handed coordinate system, but the axes are swapped around. In UE4, positive X is "forward", positive Y is "right" and positive Z is "up". This can't be changed, so you'll have to get used to it.UE4中,x轴:前;Y:右,Z:上。
How do I see Log Output from my game? 怎么看调试输出信息?
In the UE4 editor you can open the "Output Log" from the "Window -> Developer Tools" menu. You can also run your game with the "-log" command-line parameter to summon a dedicated log window alongside your game, which is really useful!
UE4编辑器中:Window -> Developer Tools
Speaking of Log Output, where is my Debug.Log? 我的Debug.Log()函数去哪里了?
Logging in UE4 is highly customizable. Read up on how to log messages here.
How do I throw exceptions? 我怎么才能抛出异常错误?
In Unity you're used to throwing exceptions when things go wrong. UE4 doesn't use exception handling. Instead use the 'check()' function to trigger a critical assertion error. You can pass in an error message. If you want to report an error but not halt the program, use 'ensure()' instead. This will log an error with a full call stack, but program execution will continue. If you had a debugger attached, both functions will break into the debugger.
UE4中没有这样的机制,而是使用check()函数。
Where is the .NET Framework? .NetFramework在哪里?
Unlike Unity, UE4 does not use the .NET framework. UE4 has it's own set of container classes and libraries. Common container comparisons:
.Net Framework | UE4 |
---|---|
String | FString, FText |
List | TArray |
Dictionary | TMap |
HashSet | TSet |
You can learn more about other UE4 containers here.
Does Unreal automatically reload code changes? 虚幻引擎能热更新代码吗?
Yes! You can leave the editor open while you write code. Simply kick off a compile from Visual Studio after you've finished editing code, and the editor will "hot reload" your changes automatically. You can also click the Compile button on the editor's main toolbar. That can be useful when you have the Visual Studio debugger attached.
当然可以。
Where to go from here 从这里继续深入研究
Thanks for reading the guide! This was created for the Unreal community with the help of Unreal developers everywhere, and we very much appreciate any feedback and corrections you can offer. We'll try to keep improving this document as we learn more about what's most helpful when transitioning to UE4!
We have many additional UE4 learning resources available!
-
Documentation
-
Getting Started - GettingStarted
-
-
Tutorial Videos - Videos
-
API - API
-
AnswerHub - https://answers.unrealengine.com
-
Forums - https://forums.unrealengine.com
-
Wiki - https://wiki.unrealengine.com
-
Wiki page about learning UE4 coming from Unity
-
![Logo](https://devpress.csdnimg.cn/0eaa3f4efff14b1ab0a46fbad1f275ab.jpg)
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐
所有评论(0)