Актёры и их компоненты

```

```

Первые два параметра определяют положение и поворот актёра.

Третий параметр определяет, производится ли настоящее перемещение актёра (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, этим значением, как правило, будет параметр, переданный при вызове данного метода.

В роли «осевого» контроллера может выступать и клавиатура; в этом случае нажатие той или иной заданной в свойствах проекта клавиши вызывает вызов привязанного к данному контроллеру метода с заранее определённым значением параметра.