Choose your operating system:
Windows
macOS
Linux
実装方法を選んでください。
Blueprints
C++
概要
ダイレクト アクタ通信はレベルのアクタ間で情報を共有する一般的な方法です。 この方法では、使用中のアクタからターゲットへアクセスするための参照が必要です。この通信メソッドは、使用中のアクタとターゲット アクタ間で 1 対 1 の関係性を使用します。 このクイック スタート ガイドでは、機能を使用するためにダイレクト アクタ通信をを使用して基本のプロシージャルな音楽システムを作成する方法を学習します。
1 - 必要な設定
メニューの [New Project Categories] セクションで[Games] を選択して [Next] をクリックします。
Third Person (サードパーソン) テンプレートを選択して [Next] をクリックします。
Blueprint と With Starter Content (スターターコンテンツ有り) オプションを選択して Create Project をクリックします。
このセクションの結果
サードパーソン プロジェクトを作成したので、ダイレクト アクタ通信について学習する準備ができました。
2 - ダイレクト アクタ通信を追加する
コンテンツ ブラウザ で [Starter Content] > [Blueprints] の順に選んで Blueprint_CeilingLight アクタをレベルにドラッグします。
レベルで ThirdPersonCharacter アクタを選択してランプの近くに配置します。
選択して ThirdPersonCharacter を使って、ワールド アウトライナー へ移動して Edit ThirdPersonCharacter をクリックしてブループリント エディタを開きます。
[Variables] セクションに移動し、 [Variables (変数)] ボタンをクリックして新しい変数を作成します。
変数の名前を「LampReference」にします。
[Details] パネルに移動し、 [Variable Type (変数の型)] ドロップダウンをクリックします。以下のように、Blueprint Ceiling Light で Object Reference を選択します。
最後に、[Instance Editable (インスタンスを編集可能)] チェックボックスを有効にして、ブループリントを コンパイル して、保存 します。
イベントグラフ を右クリックして、F キーを選択して入力ノードを作成します。
F Key ノードの Pressed ピンからドラッグし、 Flip Flop を検索して選択します。
Lamp Reference 変数を イベント グラフ にドラッグして、Get LampReference を選択します。ピンからドラッグし、 Get Point Light 1 を検索して選択します。
Point Light 1 ピンからドラッグし、Set Visibility を検索して選択します。以下のように Flip Flop ノードから A pin を Set Visibility ノードに接続します。
Lamp Reference ノード、Point Lamp 1 ノード、Set Visibility ノードをコピーして、Flip Flop ノードの B ピンに接続します。以下のように New Visibility チェックボックスを有効にします。
ブループリントを コンパイル して、保存 します。
このセクションの結果
このセクションでは、ランプ アクタへの参照を使用して F キーの押下によりランプを付けたり消したりするために、ThirdPersonCharacter ブループリント アクタを修正しました。
3 - ランプ アクタとインタラクトする
レベル内の ThirdPersonCharacter アクタを選択し、[Details] パネルから [Lamp Reference] ドロップダウンをクリックします。Blueprint_CeilingLight ブループリントを選択します。
Play を押して Play Mode にし、F key を押してランプのスイッチのオンオフを行います。
このセクションの結果
このセクションでは、Ceiling Lamp Actor の参照を ThirdPersonCharacter ブループリント アクタへ追加し、F キーを押してライトのスイッチの入切ができるようにしました。
次のステップ
ダイレクト アクタ通信を理解したので、「アクタ通信」ドキュメントで参照されている他の種類の通信を見てみましょう。
概要
ダイレクト アクタ通信はレベルのアクタ間で情報を共有する一般的な方法です。 この方法では、使用中のアクタからターゲットへアクセスするための参照が必要です。この通信メソッドは、使用中のアクタとターゲット アクタ間で 1 対 1 の関係性を使用します。 このクイック スタート ガイドでは、機能を使用するためにダイレクト アクタ通信をを使用して基本のプロシージャルな音楽システムを作成する方法を学習します。
1 - 必要な設定
メニューの [New Project Categories] セクションで[Games] を選択して [Next] をクリックします。
Third Person (サードパーソン) テンプレートを選択して [Next] をクリックします。
C++ と With Starter Content (スターターコンテンツ有り) オプションを選択して Create Project をクリックします。
このセクションの結果
サードパーソン プロジェクトを作成したので、ダイレクト ブループリント通信について学習する準備ができました。
2 - シーリング ライト アクタを作成する
C++ Class Wizzard から CeilingLight という名前で新しいアクタ クラスを作成します。
CeilingLight.h のクラス デフォルトで以下のコードを実行します。
protected: UPROPERTY(EditInstanceOnly, BlueprintReadWrite) USceneComponent* SceneComp; UPROPERTY(EditInstanceOnly, BlueprintReadWrite) class UPointLightComponent* PointLightComp; UPROPERTY(EditInstanceOnly, BlueprintReadWrite) UStaticMeshComponent* StaticMeshComp; UPROPERTY(EditInstanceOnly, BlueprintReadWrite) float Brightness; UPROPERTY(EditInstanceOnly, BlueprintReadWrite) float SourceRadius; UPROPERTY(EditInstanceOnly, BlueprintReadWrite) FLinearColor Color; UPROPERTY(EditInstanceOnly, BlueprintReadWrite) bool IsLightOn;
CeilingLight.Cpp で、以下の include ライブラリを宣言します。
#include "Components/PointLightComponent.h"
コンストラクタ ACeilingLight::CeilingLight で、以下を宣言します。
ACeilingLight::ACeilingLight() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; SceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComp")); PointLightComp = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLightComp")); StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComp")); SceneComp = RootComponent; PointLightComp->AttachToComponent(SceneComp,FAttachmentTransformRules::KeepRelativeTransform); StaticMeshComp->AttachToComponent(SceneComp, FAttachmentTransformRules::KeepRelativeTransform); PointLightComp->SetWorldLocation(FVector(0, 0, -130)); Brightness = 1700.f; Color = FLinearColor(1.f, 0.77f, 0.46f); SourceRadius = 3.5f; PointLightComp->SetIntensity(Brightness); PointLightComp->SetLightColor(Color); PointLightComp->SetSourceRadius(SourceRadius); }
コードを コンパイル します。
完成コード
CeilingLight.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CeilingLight.generated.h"
UCLASS()
class BPCOMMUNICATION_API ACeilingLight : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACeilingLight();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
USceneComponent* SceneComp;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
class UPointLightComponent* PointLightComp;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
UStaticMeshComponent* StaticMeshComp;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
float Brightness;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
float SourceRadius;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
FLinearColor Color;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
bool IsLightOn;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION()
void TurnOffLight();
};
CeilingLight.cpp
//Copyright Epic Games, Inc. All Rights Reserved.
#include "CeilingLight.h"
#include "Components/PointLightComponent.h"
// Sets default values
ACeilingLight::ACeilingLight()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComp"));
PointLightComp = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLightComp"));
StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComp"));
SceneComp = RootComponent;
PointLightComp->AttachToComponent(SceneComp,FAttachmentTransformRules::KeepRelativeTransform);
StaticMeshComp->AttachToComponent(SceneComp, FAttachmentTransformRules::KeepRelativeTransform);
PointLightComp->SetWorldLocation(FVector(0, 0, -130));
Brightness = 1700.f;
Color = FLinearColor(1.f, 0.77f, 0.46f);
SourceRadius = 3.5f;
PointLightComp->SetIntensity(Brightness);
PointLightComp->SetLightColor(Color);
PointLightComp->SetSourceRadius(SourceRadius);
}
// Called when the game starts or when spawned
void ACeilingLight::BeginPlay()
{
Super::BeginPlay();
}
void ACeilingLight::TurnOffLight()
{
if (IsLightOn)
{
PointLightComp->SetVisibility(false);
IsLightOn = false;
}
else
{
PointLightComp->SetVisibility(true);
IsLightOn = true;
}
}
// Called every frame
void ACeilingLight::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
「C++ Classes」フォルダで CeilingLight アクタを右クリックし、[C++ Class Actions] ドロップダウン メニューから [Create Blueprint class based on CeilingLight] を選択します。ブループリントに「BP_CeilingLight」と名前を付けます。
BP_CeilingLight クラス デフォルトから [Components] パネルに移動し StaticMeshComp を選択します。
[Details] パネルから Static Mesh カテゴリに移動し、 Static Mesh 変数の横にあるドロップダウン矢印を選択して SM_Lamp_Ceiling を検索して選択します。
ブループリントをコンパイルして保存します。
コンテンツ ブラウザ から BP_CeilingLight Actor のインスタンスをレベルにドラッグします。
ThirdPersonCharacter クラスを修正する
「C++ Classes」フォルダへ移動して BPCommunicationCharacter クラスをダブルクリックして BPCommunicationCharacter.h を開き、クラスデフォルトで以下のコードを宣言します。
protected: UPROPERTY(EditInstanceOnly, BlueprintReadWrite) class ACeilingLight* CeilingLightToToggle; void ToggleCeilingLight();
BPCommunicationCharacter.cpp に移動して以下のインクルードを宣言します。
#include "CeilingLight.h"
ABPCommunicationCharacter::ToggleCeilingLight メソッドを実行します。
void ABPCommunicationCharacter::ToggleCeilingLight() { if (CeilingLightToToggle) { CeilingLightToToggle->TurnOffLight(); } }
ABPCommunicationCharacter::SetupPlayerInputComponent メソッドへ移動して以下を宣言します。
PlayerInputComponent->BindAction("Use", IE_Pressed, this, &ABPCommunicationCharacter::ToggleCeilingLight);
エディタ で [Edit] > [Project Settings] > [Input] の順に移動します。Bindings カテゴリの Action Mappings で [Add (+)] ボタンをクリックして Use という名前の新規 Action mapping を作成し、キー値 に E キーを選択します。
コードを コンパイル します。
完成コード
BPCommunicationCharacter.h
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "BPCommunicationCharacter.generated.h"
UCLASS(config=Game)
class ABPCommunicationCharacter : public ACharacter
{
GENERATED_BODY()
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
public:
ABPCommunicationCharacter();
/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseTurnRate;
/** Base look up/down rate, in deg/sec. Other scaling may affect the final rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseLookUpRate;
protected:
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
class ACeilingLight* CeilingLightToToggle;
void ToggleCeilingLight();
/** Resets HMD orientation in VR. */
void OnResetVR();
/** Called for forwards/backward input */
void MoveForward(float Value);
/** Called for side to side input */
void MoveRight(float Value);
/**
* Called via input to turn at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void TurnAtRate(float Rate);
/**
* Called via input to turn look up/down at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void LookUpAtRate(float Rate);
/** Handler for when a touch input begins. */
void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);
/** Handler for when a touch input stops. */
void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// End of APawn interface
public:
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** Returns FollowCamera subobject **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
};
BPCommunicationCharacter.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
#include "BPCommunicationCharacter.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "CeilingLight.h"
ABPCommunicationCharacter::ABPCommunicationCharacter()
{
// Set size for collision capsule
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// set our turn rates for input
BaseTurnRate = 45.f;
BaseLookUpRate = 45.f;
// Don't rotate when the controller rotates. Let that just affect the camera.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Configure character movement
GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
GetCharacterMovement()->JumpZVelocity = 600.f;
GetCharacterMovement()->AirControl = 0.2f;
// Create a camera boom (pulls in towards the player if there is a collision)
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
// Create a follow camera
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
// Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character)
// are set in the derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}
void ABPCommunicationCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Set up gameplay key bindings
check(PlayerInputComponent);
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAction("Use", IE_Pressed, this, &ABPCommunicationCharacter::ToggleCeilingLight);
PlayerInputComponent->BindAxis("MoveForward", this, &ABPCommunicationCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &ABPCommunicationCharacter::MoveRight);
// We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turn rate" is for devices that we choose to treat as a rate of change, such as an analog joystick
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("TurnRate", this, &ABPCommunicationCharacter::TurnAtRate);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
PlayerInputComponent->BindAxis("LookUpRate", this, &ABPCommunicationCharacter::LookUpAtRate);
// handle touch devices
PlayerInputComponent->BindTouch(IE_Pressed, this, &ABPCommunicationCharacter::TouchStarted);
PlayerInputComponent->BindTouch(IE_Released, this, &ABPCommunicationCharacter::TouchStopped);
// VR headset functionality
PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &ABPCommunicationCharacter::OnResetVR);
}
void ABPCommunicationCharacter::ToggleCeilingLight()
{
if (CeilingLightToToggle)
{
CeilingLightToToggle->TurnOffLight();
}
}
void ABPCommunicationCharacter::OnResetVR()
{
// If BPCommunication is added to a project via 'Add Feature' in the Unreal Editor the dependency on HeadMountedDisplay in BPCommunication.Build.cs is not automatically propagated
// and a linker error will result.
// You will need to either:
// Add "HeadMountedDisplay" to [YourProject].Build.cs PublicDependencyModuleNames in order to build successfully (appropriate if supporting VR).
// or:
// Comment or delete the call to ResetOrientationAndPosition below (appropriate if not supporting VR)
UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();
}
void ABPCommunicationCharacter::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
{
Jump();
}
void ABPCommunicationCharacter::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
{
StopJumping();
}
void ABPCommunicationCharacter::TurnAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}
void ABPCommunicationCharacter::LookUpAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}
void ABPCommunicationCharacter::MoveForward(float Value)
{
if ((Controller != nullptr) && (Value != 0.0f))
{
// find out which way is forward
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get forward vector
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
}
void ABPCommunicationCharacter::MoveRight(float Value)
{
if ( (Controller != nullptr) && (Value != 0.0f) )
{
// find out which way is right
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get right vector
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// add movement in that direction
AddMovementInput(Direction, Value);
}
}
3 - ランプ ブループリントとインタラクトする
レベルで ThirdPersonCharacter ブループリントを選択してランプの近くに配置します。
ThirdPersonCharacter を選択したまま、[Details] パネルに移動し、BPCommunication Character カテゴリで Ceiling Light To Toggle 変数を探して、横にある矢印を選択します。ドロップダウン メニューで BP_CeilingLight アクタを探して選択します。
Play を押して PlE (Play-in Editor) にし、E key を押してランプのスイッチのオンオフを行います。
このセクションの結果
このセクションでは、Ceiling Light Actor の参照を ThirdPersonCharacter ブループリントへ追加し、E キーを押してライトのスイッチの入切ができるようにしました。
次のステップ
ダイレクト ブループリント通信を理解したので、「アクタ通信」ドキュメントで参照されている他の種類の通信を見てみましょう。