На этой странице описаны концепции создания игр в Unreal Engine (UE) для пользователей Unity. Тем, кто знаком с Unity C# и хочет изучить C++ и Blueprint для UE, будет проще со всем разобраться.
В примерах ниже представлены некоторые сценарии разработки игр на C# в Unity и способы их реализации в UE.
Создание экземпляров GameObject / возрождение актора
В Unity для создания новых экземпляров объектов используется функция Instantiate. Она создаёт копии любого типа UnityEngine.Object (GameObject, MonoBehaviour и т. д.).
public GameObject EnemyPrefab;
public Vector3 SpawnPosition;
public Quaternion SpawnRotation;
void Start()
{
GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation);
NewGO.name = "MyNewGameObject";
}В UE для этой цели существуют две функции:
NewObjectсоздаёт новые типыUObject.SpawnActorсоздаёт типыAActor.
UObjects и NewObject
Процесс создания подклассов UObject в UE аналогичен процессу создания подклассов ScriptableObject в Unity. Он используется для игровых классов, которым не нужно появляться в мире или иметь прикреплённые компоненты (как в случае с акторами).
Для создания подкласса ScriptableObject в Unity можно использовать следующий код:
MyScriptableObject NewSO = ScriptableObject.CreateInstance<MyScriptableObject>();Для создания подкласса UObject в UE можно использовать следующий код:
UMyObject* NewObj = NewObject<UMyObject>();AActors и SpawnActor
Для создания акторов можно использовать метод SpawnActor для объекта мира (UWorld в C++). Для некоторых объектов UObject и для всех акторов предусмотрен метод GetWorld для получения объекта мира.
В приведённом ниже примере мы используем эти методы с параметрами создания существующего актора для эмуляции функциональности метода Instantiate в Unity.
Пример
Ниже приведён пример подкласса AActor — AMyActor. Конструктор по умолчанию инициализирует int32 и USphereComponent*.
Обратите внимание на использование функции CreateDefaultSubobject. Она создаёт компоненты и назначает им свойства по умолчанию. Подобъекты, созданные с помощью этой функции, выступают в качестве шаблона по умолчанию, поэтому их можно изменять в подклассе или в схеме Blueprint.
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
int32 MyIntProp;
UPROPERTY()
USphereComponent* MyCollisionComp;
При этом создаётся клон AMyActor, включающий все переменные-составляющие, свойства UPROPERTY и компоненты.
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);
}Переход от одного типа к другому
Здесь мы берём компонент (который у нас уже есть), а затем приводим его к определенному типу и выполняем нужную операцию.
Unity
Collider collider = gameObject.GetComponent<Collider>;
SphereCollider sphereCollider = collider as SphereCollider;
if (sphereCollider != null)
{
// ...
}UE C++
UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());
USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);
if (SphereCollider != nullptr)
{
// ...
}Сценарий Blueprint
Вы можете выполнить приведение типов в Blueprint, используя узел Cast to (Привести к типу). Подробнее см. в разделе Casting Quick Start Guide (Краткое руководство по приведению типов).
Уничтожение GameObject/актора
Уничтожение GameObject/актора (с 1-секундной задержкой)
Отключение GameObjects/акторов
Unity C# C# | UE C++ C++ | Blueprint |
Доступ к GameObject/актору из компонента
Unity C# C++ | UE C++ C++ | Blueprint |
Доступ к компоненту из GameObject/актора
Unity
MyComponent MyComp = gameObject.GetComponent<MyComponent>();UE C++
UMyComponent* MyComp = MyActor->FindComponentByClass<UMyComponent>();Сценарий Blueprint
Поиск GameObjects/акторов
Unity
// Find GameObject by name
GameObject MyGO = GameObject.Find("MyNamedGameObject");
// Find Objects by type
MyComponent[] Components = Object.FindObjectsOfType(typeof(MyComponent)) as MyComponent[];
foreach (MyComponent Component in Components)
{
// ...
}
UE C++
// Find UObjects by type
for (TObjectIterator<UMyObject> It; It; ++it)
{
UMyObject* MyObject = *It;
// ...
}
// Find Actor by name (also works on UObjects)
AActor* MyActor = FindObject<AActor>(nullptr, TEXT("MyNamedActor"));
Сценарий Blueprint
Добавление тегов к GameObjects/акторам
Unity
MyGameObject.tag = "MyTag";UE C++
// Actors can have multiple tags
MyActor.Tags.AddUnique(TEXT("MyTag"));Сценарий Blueprint
Добавление тегов к MonoBehaviours/ActorComponents
Unity
// This changes the tag on the GameObject it is attached to
MyComponent.tag = "MyTag";UE C++
// Components have their own array of tags
MyComponent.ComponentTags.AddUnique(TEXT("MyTag"));Сравнение тегов для GameObjects/акторов и MonoBehaviours/ActorComponents
Unity
if (MyGameObject.CompareTag("MyTag"))
{
// ...
}
// Checks the tag on the GameObject it is attached to
if (MyComponent.CompareTag("MyTag"))
{
// ...
}UE C++
// Checks if an Actor has this tag
if (MyActor->ActorHasTag(FName(TEXT("MyTag"))))
{
// ...
}Сценарий Blueprint
UE C++
// Checks if an ActorComponent has this tag
if (MyComponent->ComponentHasTag(FName(TEXT("MyTag"))))
{
// ...
}Сценарий Blueprint
Физика: RigidBody и компонент примитива
Чтобы задать GameObject физические характеристики в Unity, нужно прикрепить к нему компонент RigidBody.
В UE любой компонент примитива (UPrimitiveComponent в C++) может быть физическим объектом. Вот распространённые примеры компонентов примитива:
Компоненты формы (
USphereComponent,UCapsuleComponentи т. д.)Компоненты со статичной сеткой
Компоненты с каркасной сеткой
В отличие от Unity, где задачи коллизии и визуализации разделяются на отдельные компоненты, в UE понятия «потенциально физический» и «потенциально видимый» объединяются в едином компоненте примитива. Любой компонент с геометрией в мире, который можно визуализировать или с которым можно взаимодействовать физически, является подклассом UPrimitiveComponent.
Каналы коллизии в UE — это аналог слоёв в Unity. Для получения дополнительной информации обратитесь к разделу Collision Filtering (Фильтры коллизии).
Рейкастинг и трассировка лучей
Unity
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);
UE C++
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;
Сценарий Blueprint
Триггерные объемы
Unity
public class MyComponent : MonoBehaviour
{
void Start()
{
collider.isTrigger = true;
}
void OnTriggerEnter(Collider Other)
{
// ...
}
UE C++
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
// My trigger component
UPROPERTY()
UPrimitiveComponent* Trigger;
AMyActor()
Сценарий Blueprint
Подробнее о настройке коллизий: Collision (Коллизия).
Кинематические твердые тела
Unity
public class MyComponent : MonoBehaviour
{
void Start()
{
rigidbody.isKinematic = true;
rigidbody.velocity = transform.forward * 10.0f;
}
}UE C++
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
UPrimitiveComponent* PhysicalComp;
AMyActor()
{
События ввода
Unity
public class MyPlayerController : MonoBehaviour
{
void Update()
{
if (Input.GetButtonDown("Fire"))
{
// ...
}
float Horiz = Input.GetAxis("Horizontal");
float Vert = Input.GetAxis("Vertical");
UE C++
UCLASS()
class AMyPlayerController : public APlayerController
{
GENERATED_BODY()
void SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAction("Fire", IE_Pressed, this, &AMyPlayerController::HandleFireInputEvent);
Сценарий Blueprint
Пример свойств ввода в настройках проекта:
Подробнее о том, как настроить ввод для проекта UE см. в разделе Input (Ввод).
Подробнее
Для получения дополнительной информации, связанной с описанными выше концепциями, рекомендуем ознакомиться со следующими разделами:
Gameplay Framework (Инфраструктура игрового процесса) — охватывает основные игровые системы, такие как игровой режим, состояние игрока, контроллеры, пешки, камеры и проч.
Gameplay Architecture (Архитектура игрового процесса) — справочник по созданию и реализации классов игрового процесса.
Gameplay Tutorials (Обучающие материалы по игровому процессу) — обучающие материалы для воссоздания распространённых элементов игрового процесса.