Операции с актёрами в целом[]
Динамическое создание актёра из класса C++[]
ACharacter *Character = NewObject<ACharacter>( GetWorld()->GetCurrentLevel(), TEXT("New_Character"));
Позиционирование актёра на текущем уровне[]
bool b = Character->TeleportTo( FVector(-40520.0f, -4770.0f, 200.0f), FRotator(0.0f, 0.0f, 0.0f), false, true);
Первые два параметра определяют положение и поворот актёра.
Третий параметр определяет, производится ли настоящее перемещение актёра (false, как в данном случае) или же лишь пробное перемещение (true; может применяться, например, в процессе поиска пути). В последнем случае движок не выдаёт уведомлений о выполненном перемещении и т.п.
Четвёртый параметр должен быть равен false, если необходимо проверить, не «втыкается» ли актёр в мир или других актёров; true (используется в данном примере) отключает такую проверку.
Возвращается значение true, если позиционирование прошло успешно.
Создание актёра прямо на уровне[]
Хотя эту задачу можно решить, используя создание экземпляра класса актёра с помощью функции NewObject с последующим его позиционированием методом AActor::TeleportTo, это можно сделать и другим, более прямым для данного случая образом.
UWorld *World = GetWorld();
ULevel *Level = World->GetCurrentLevel();
FActorSpawnParameters Parms;
Parms.bAllowDuringConstructionScript = true;
Parms.bDeferConstruction = false;
Parms.bNoCollisionFail = true;
Parms.bNoFail = true;
Parms.bRemoteOwned = false;
Parms.Instigator = nullptr;
Parms.Name = TEXT("Player_Character");
Parms.ObjectFlags = RF_NoFlags;
Parms.OverrideLevel = Level;
Parms.Owner = nullptr;
Parms.Template = nullptr;
FVector Loc(-40520.0f, -4770.0f, 200.0f);
FRotator Rot(0.0f, 0.0f, 0.0f);
AMy_Character Character = (AMy_Character*) World->SpawnActor(
AMy_Character::StaticClass(),
&Loc,
&Rot,
Parms);
Полное заполнение структуры Parms обычно не требуется, достаточно указать лишь параметры, отличающиеся от устанавливаемых по умолчанию. Во многих случаях её вообще можно не создавать, а соответствующий параметр методу SpawnActor не передавать — движок в этом случае возмёт значения по умолчанию.
Создание актёра из блупринтового класса[]
UWorld *World = GetWorld(); FVector Loc(-40520.0f, -4770.0f, 200.0f); FRotator Rot(0.0f, 0.0f, 0.0f); UBlueprint *BP_Char = (UBlueprint*) StaticLoadObject( UBlueprint::StaticClass(), NULL, L"Blueprint'/Game/Characters/BP_Test_Humanoid.BP_Test_Humanoid'"); TSubclassOf<AHumanoid_Character> Char = (UClass*) BP_Char->GeneratedClass; Player_Character = World->SpawnActor<AHumanoid_Character>( Char, Loc, Rot);
По сути, этот код выполняет те же действия, что и предыдущий (при необходимости здесь тоже можно создать и заполнить структуру типа FActorSpawnParameters — это не сделано потому, что обычно её стандартные значения всех устраивают). Для загрузки блупринтового класса применяется вызов функции StaticLoadObject, поскольку она способна работать везде, а не только в конструкторах.
Операции с компонентами актёров[]
Обычно компоненты актёров создаются и настраиваются в редакторе, однако иногда это необходимо делать программно во время выполнения. Ниже приведены примеры кода, используемые для этой цели.
Масштабирование капсулы, заключающей персонажа[]
((UCapsuleComponent*) RootComponent)->InitCapsuleSize(45.0f, 100.0f);
Предполагается, что капсула является корневым компонентом персонажа, как это сделано, например, в демонстрационном персонаже Ue4ASP_Character.
Загрузка скелетного меша из ассета и назначение его персонажу[]
ConstructorHelpers::FObjectFinder<USkeletalMesh> New_Mesh( TEXT("SkeletalMesh'/Game/AnimStarterPack/UE4_Mannequin/Mesh/SK_Mannequin.SK_Mannequin'")); GetMesh()->SetSkeletalMesh(New_Mesh.Object);
Изменение положения меша в актёре[]
GetMesh()->RelativeLocation = FVector(0.0f, 0.0f, -100.0f); GetMesh()->RelativeRotation = FRotator(0.0f, -90.0f, 0.0f); GetMesh()->RelativeScale3D = FVector(1.0f, 1.0f, 1.0f);
Загрузка и назначение блупринта анимации[]
ConstructorHelpers::FObjectFinder<UAnimBlueprint> BP_Anim( TEXT("AnimBlueprint'/Game/AnimStarterPack/UE4ASP_HeroTPP_AnimBlueprint.UE4ASP_HeroTPP_AnimBlueprint'")); GetMesh()->SetAnimInstanceClass(BP_Anim.Object->GetAnimBlueprintGeneratedClass());
Создание и прикрепление к персонажу камеры, размещённой на выносном «рычаге»[]
USpringArmComponent *Camera_Boom = OI.CreateDefaultSubobject<USpringArmComponent>(this, TEXT("CameraBoom")); Camera_Boom->AttachTo(RootComponent); Camera_Boom->bAbsoluteRotation = false; Camera_Boom->TargetArmLength = 200.0f; Camera_Boom->SocketOffset = FVector(0.0f, 0.0f, 0.0f); Camera_Boom->RelativeLocation = FVector(0.0f, 0.0f, 30.0f); Camera_Boom->RelativeRotation = FRotator(0.0f, 0.0f, 0.0f); UCameraComponent *Camera = OI.CreateDefaultSubobject<UCameraComponent>(this, TEXT("SideViewCamera")); Camera->AttachTo(Camera_Boom, USpringArmComponent::SocketName); Camera->RelativeLocation = FVector(0.0f, 0.0f, 10.0f); Camera->bUsePawnControlRotation = true;
В этом примере OI — стандартный параметр конструктора типа FObjectInitializer.
Приваивание Camera_Boom->bAbsoluteRotation = true; необходимо для того, чтобы вращение персонажа не влияло на поворот «рычага». Значения, присваиваемые свойствам bUsePawnControlRotation и bAbsoluteRotation, определяют связь между вращением персонажа и камеры (при указанных в примере значениях горизонтальное направление камеры всегда будет совпадать с направлением персонажа, однако вертикальное направление может изменяться).
Если необходимо создать камеру не в конструкторе, вместо вызова метода CreateDefaultSubobject следует использовать функцию NewObject, например:
Camera_Boom = NewObject<USpringArmComponent>( this, TEXT("Camera_Boom"));
Управление движением пешек[]
Пешки (Pawns) — экземпляры класса APawn или его потомков. Основным отличием пешек от базовых актёров (класс AActor) является возможность передачи их в обладание тем или иным игроком (включая искусственный интеллект), благодаря чему обеспечивается возможность стандартным образом управлять их движением в игровом мире.
Привязка актёра к игроку[]
World->GetFirstPlayerController()->Possess(Player_Character);
Этот вызов передаст управление персонажем Player_Character первому (или единственному) игровому контроллеру, т.е. игроку.
Связывание действий игрока с методами актёра[]
Input->BindAxis("Camera_Lookup", this, &AMy_Character::Camera_Lookup); Input->BindAction("Jump", IE_Pressed, this, &AMy_Character::Jump_Pressed);
Эти два вызова осуществляют привязку соответственно «осевого» контроллера и события нажатия кнопки к заданным методам пользовательского класса. Метод, вызываемый в результате действий с «осевым» контроллером, получает на входе единственный параметр типа float, который определяет текущую степень воздействия контроллера (например, угол отклонения ручки джойстика). Camera_Lookup и Jump являются именами действий, связанных с контроллерами или клавишами в настройках проекта. Input — переменная типа UInputComponent. Поскольку привязка обычно осуществляется в виртуальном методе, перекрывающем стандартный метод APawn::SetupPlayerInputComponent, этим значением, как правило, будет параметр, переданный при вызове данного метода.
В роли «осевого» контроллера может выступать и клавиатура; в этом случае нажатие той или иной заданной в свойствах проекта клавиши вызывает вызов привязанного к данному контроллеру метода с заранее определённым значением параметра.