Choose your operating system:
Windows
macOS
Linux
実装方法を選んでください。
Blueprints
C++
概要
イベント ディスパッチャーは、あるアクタがイベントをディスパッチし、それをリスニングしている別のアクタが通知を受けるようなアクタ通信手段です。
この方法を使い、通知を発信するアクタは、リスニングしているアクタがサブスクライブする イベント ディスパッチャー を作成します。この通信方法では、1 対多の関係を使用しており、作業アクタがイベント ディスパッチャーをトリガーし、リスニングしている多数のアクタが通知を受けます。
目標
このクイック スタート ガイドでは、レベル内で 2 つのアクタをトリガーする OnBossDied イベントをデリゲート イベントで作成する方法を学習します。
目的
-
イベント ディスパッチャーを作成する BossDied アクタを作成する。
-
OnBossDied イベントにバインドするためにドア アクタを作成する。
-
Blueprint_Effect_Explosion ブループリントを修正し、 OnBossDied イベントにバインドする。
1 - 必要な設定
-
メニューの [New Project Categories (新規プロジェクトカテゴリ)] セクションにある [Games (ゲーム)] を選択して [Next (次へ)] をクリックします。
-
[Third Person (サードパーソン)] テンプレートを選択し、 [Next (次へ)] をクリックします。
-
[Blueprint (ブループリント)] と [With Starter Content (スターター コンテンツあり)] オプションを選択し、 [Create Project (プロジェクトの作成)] をクリックします。
このセクションの結果
新規のサードパーソン プロジェクトが作成され、イベント ディスパッチャーについて学ぶ準備ができました。
2 - OnBossDied イベントを作成する
-
コンテンツ ブラウザ を右クリックして、 [Create Basic Asset (基本アセットの作成)] セクション内の [Blueprint Class (ブループリント クラス)] をクリックします。
-
[Actor (アクタ)] クラスを親クラスとして選択し、ブループリントに「 BP_BossDied 」という名前を付けます。
-
ブループリント エディタ内の [Viewport (ビューポート)] から [BP_BossDied] を開いて [Add Component (コンポーネントを追加)] ボタンをクリックし、「 Box Collision 」を検索して選択します。
-
「 Box Collision」を選択した状態で、スケーリングを「X = 4 」、「Y = 4 」、「 Z = 2 」に変更します。
-
「 Box Collision」を選択した状態で、 [Details (詳細)] パネルの [Rendering (レンダリング)] セクションに異動し、 [Hidden in Game (ゲーム内で非表示)] のチェックボックスを無効にします。これで、ゲームプレイ中にコリジョン ボックスが表示されます。
-
「 Box Collision」を右クリックして [Add OnComponentBeginOverlap (OnComponentBeginOverlap を追加)] を選択します。すると、ノードに イベント グラフ が表示されます。
-
左にある [My Blueprint (マイ ブループリント)] パネルから [Event Dispatchers (イベント ディスパッチャー)] セクションに移動し、 [+ Add New (新規追加)] をクリックして新規イベントを追加します。このイベントに「 OnBossDied 」という名前を付けます。
-
OnBossDied を イベント グラフ にドラッグし、 [Call (コール)] を選択してノードを追加します。
-
On Component Begin Overlap ノードを Call OnBossDied ノードに接続します。ブループリントを コンパイル して、 保存 します。
-
BP_BossDied ブループリントをレベルにドラッグします。
このセクションの結果
このセクションでは、 BP_BossDied アクタを作成し、ゲームでボスのキャラクターが死んだときに発生することをシミュレートしました。このアクタに、 OnBossDied イベント ディスパッチャーを作成しました。このイベント ディスパッチャーは、イベントがトリガーされたときに他のアクタに信号を送信するのに使用されます。
3 - インタラクティブなドアを作成する
-
コンテンツ ブラウザ**を右クリックして、 [Create Basic Asset (基本アセットの作成)]** セクション内の [Blueprint Class (ブループリント クラス)] をクリックします。
-
[Actor (アクタ)] クラスを親クラスとして選択し、ブループリントに「 BP_BossDoor 」という名前を付けます。
-
[Viewport (ビューポート)] から [BP_BossDoor] を開いて [Add Component (コンポーネントを追加)] のドロップダウンをクリックし、「 Static Mesh 」を検索して選択します。コンポーネントに「 Frame 」という名前を付けます。
-
別の Static Mesh コンポーネントを追加し、「 Door 」という名前を付けます。
-
[Details (詳細)] パネルから、 Frame コンポーネントを選択し、 [Static Mesh (スタティック メッシュ)] のドロップダウンをクリックし、「 SM_DoorFrame 」を検索し、選択します。
-
Door コンポーネントに対しても上の手順を繰り返し、 SM_Door スタティック メッシュを追加します。
-
Door コンポーネントを選択した状態で、以下のように Y の位置を「45」に設定します。すると、ドアが枠にぴったり合っている状態で表示されるはずです。
-
[Event Graph (イベント グラフ)] を右クリックして、「 Add Custom Event 」を検索、選択します。イベントに「 OpenDoor 」という名前を付けます。
-
OpenDoor ノードからイベントをドラッグして、「 Add Timeline 」 を検索、選択します。タイムラインの名前を 「 TM_Door 」 にします。
-
TM_Door をダブルクリックして開きます。 [Add Float Curve (Float カーブを追加)] ボタンをクリックして、Float トラックを追加し、「 Alpha 」という名前を付けます。[Length (長さ)] を「 1.0 」に設定します。
-
グラフを右クリックし、 [Add key to CurveFloat_1 (CurveFloat_1 にキーを追加する)] を選択し、新しいポイントを追加します。 [Time (時間)] と [Value (値)] を 「 0.0 」に設定します。
-
上の手順を繰り返して別のポイントを追加し、 [Time (時間)] と [Value (値)] を 「 1.0 」に設定します。
-
*イベント グラフ** に戻って **Door **Static Mesh コンポーネントを **イベント グラフ** にドラッグし、ノードを作成します。**Door** ノードからドラッグして、「**SetRelativeRotation**」を検索、選択します。
-
TM_Door から Update ピンを接続し、 SetRelativeRotation ノードにつなげます。 New Rotation ピンを右クリックして「 Split Struct Pin 」を選択します。
-
イベント グラフ を右クリックして、「 Lerp Float 」を検索、選択します。 [Return Value (戻り値)] を SetRelativeRotation ノードの Yaw ピンに接続します。 TM_Door の Alpha ピンを Lerp ノード上の Alpha に接続します。最後に、 B の値を以下のように「 90.0 」に設定します。
-
[Variable (変数)] セクションの横にある [+] ボタン**をクリックして新しい変数を追加します。この変数に「 BossDiedReference**」という名前を付けます。
-
[Details (詳細)] パネルから、 [Variable Type (変数の型)] のドロップダウンをクリックし、 BP_BossDied の「 Object Reference 」を検索し、選択します。 [Instance Editable (インスタンス編集可能)] チェックボックスをオンにします。
-
BossDiedReference を イベント グラフ にドラッグして、 Get BossDiedRerence を選択します。ノードからドラッグして、「 Bind Event to On Boss Died 」を検索、選択します。
-
Bind Event to On Boss Died の 赤い Event ピンからドラッグして 「 Add Custom Event 」を検索、選択します。イベントに「 BossDied 」という名前を付けます。
-
BossDied ノードからドラッグして、「 Open Door 」を検索、選択します。以下のように、 Event Begin Play を Bind Event to On Boss Died ノードに接続します。
-
ブループリントを コンパイル して、 保存 します。
このセクションの結果
このセクションでは、 BP_BossDied クラス内にある On Boss Died イベント ディスパッチャーにバインドするインタラクティブな Door アクタを作成しました。このバインディングは、 Begin Play 時に発生しますが、 BP_BossDied によってイベントがトリガーされた時はいつでもランタイム時に実行されます。
4 - インタラクティブな爆発音を作成する
-
[Starter Content (スターター コンテンツ)] > [Blueprints (ブループリント)] に移動して 「 Blueprint_Effect_Explosion 」を選択します。それを「Gameplay」フォルダにドラッグして 「 Copy Here 」を選択します。
-
ブループリント エディタで Blueprint_Effect_Explosion を開きます。 [Viewport (ビューポート)] から P_Explosion コンポーネントを選択し、 [Details (詳細)] パネルから [Activation (アクティベーション)] セクションに移動して [Auto Activate (自動アクティベート)] を無効にします。
-
Explosion Audio コンポーネントに対しても上の手順を繰り返します。
-
[Variable (変数)] セクションの横にある [+] ボタン**をクリックして新しい変数を追加します。この変数に「 BossDiedReference**」という名前を付けます。
-
[Details (詳細)] パネルから、 [Variable Type (変数の型)] のドロップダウンをクリックし、 BP_BossDied の「 Object Reference」を検索し、選択します。 [Instance Editable (インスタンス編集可能)]** チェックボックスをオンにします。
-
イベント グラフ を右クリックして「 Event Begin Play 」を検索し、選択します。
-
BossDiedReference を イベント グラフ にドラッグして、「 Get BossDiedReference 」を選択します。ノードからドラッグして、「 Assign On Boss Died 」を検索、選択します。カスタム イベントに「 BossDied 」という名前を付けます。
-
Event Begin Play を Bind Event to Boss Died ノードに接続します。
-
P_Explosion と Explosion Audio コンポーネントを イベント グラフ にドラッグします。 P_Explosion をドラッグし、「 Activate 」を検索、選択します。 Explosion Sound を Activate ノードの Target ピンに接続します。
-
BossDied イベント ノードを Activate ノードに接続します。
-
ブループリントを コンパイル して、 保存 します。
このセクションの結果
このセクションでは、 OnBossDied イベントが実行されたときにアクティベートするように Blueprint_Effect_Explosion を変更しました。
5 - イベント ディスパッチャーをテストする
-
BP_BossDoor アクタをレベルにドラッグします。 [Details (詳細)] パネルに行き、 [Boss Reference Died] のドロップダウンをクリックし、「 BP_BossDied 」を検索、選択します。
-
Blueprint_Effect_Explosion の複数インスタンスをレベルにドラッグします。 [Details (詳細)] パネルに行き、 [Boss Reference Died] のドロップダウンをクリックし、「 BP_BossDied 」を検索、選択します。
-
[Play (プレイ)] を押して BP_BossDied に近づき、ゲーム内のボスが死ぬシミュレートをトリガーします。
このセクションの結果
このセクションでは、レベル内で BP_BossDoor と Blueprint_Effect_Explosion アクタをテストしました。 BP_BossDied アクタがそれをトリガーしたときに発生する OnBossDied イベントに各アクタが反応することを確認しました。
このガイドでは、イベント ディスパッチャーを使用して 1 つの作業アクタから多数のターゲット アクタに通信する方法を学習しました。有効であるまた、イベント ディスパッチャーを作成する方法と、特定の関数をトリガーするためにアクタをバインドする方法も学習しました。
次のステップ
イベント ディスパッチャーの使い方が分かったところで、今度は「 アクタ通信 」のドキュメント ページで参照されている他の通信手段を見てみましょう。
概要
デリゲートは、型安全な方法でアクタ クラス ブループリント内の方法を呼び出すことができます。ダイナミックにバインドし、あるアクタがリスニングしている別のアクタにイベントをトリガーして通信を確立することができます。
注記:詳細については、「 デリゲート 」を参照してください。
目標
このクイック スタート ガイドでは、レベル内で 2 つのアクタ クラス ブループリントをトリガーする OnBossDied イベントをデリゲートで作成する方法を学習します。
目的
-
OnBossDied デリゲートを含む Boss アクタを作成する。
-
OnBossDied イベントにバインドするタイムライン コンポーネントでインタラクティブなドア アクタを作成する。
1 - 必要な設定
-
メニューの [New Project Categories] セクションで [Games] を選択して [Next] をクリックします。
-
Third Person (サードパーソン) テンプレートを選択して [Next] をクリックします。
-
[C++] と [With Starter Content (スターター コンテンツあり)] オプションを選択し、 [Create Project (プロジェクトの作成)] をクリックします。
このセクションの結果
新規のサードパーソン プロジェクトが作成され、デリゲートについて学ぶ準備ができました。
2 - Boss アクタと OnBossDied デリゲートを作成する
-
C++ Class Wizard から、新規アクタ クラスを「BossActor」という名前で作成します。
-
BossActor.h へ移動します。ライブラリ インクルードで以下のデリゲートを宣言します。
DECLARE_DELEGATE(FOnBossDiedDelegate);
-
クラス デフォルトに以下を宣言します。
protected: UFUNCTION() void HandleBossDiedEvent(); UPROPERTY(EditInstanceOnly, BlueprintReadWrite) class UBoxComponent* BoxComp; virtual void NotifyActorBeginOverlap(AActor* OtherActor); public: FOnBossDiedDelegate OnBossDied;
-
BossActor.cpp に移動し、次のクラス ライブラリを追加します。
#include "Components/BoxComponent.h"
-
次のクラス定義を実装します。
ABossActor::ABossActor() { BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComp")); BoxComp->SetBoxExtent(FVector(128, 128, 64)); BoxComp->SetVisibility(true); } void ABossActor::HandleBossDiedEvent() { OnBossDied.ExecuteIfBound(); } void ABossActor::NotifyActorBeginOverlap(AActor* OtherActor) { HandleBossDiedEvent(); }
-
コードを コンパイル します。
-
「 C++ Classes 」フォルダで BossActor アクタを右クリックし、 [C++ Class Actions] ドロップダウン メニューから [Create Blueprint class based on BossActor] を選択します。ブループリントに「 BP_BossActor 」と名前を付けます。
-
BossActor のインスタンスをレベルにドラッグします。
完成コード
BossActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BossActor.generated.h"
DECLARE_DELEGATE(FOnBossDiedDelegate);
UCLASS()
class BPCOMMUNICATION_API ABossActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ABossActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UFUNCTION()
void HandleBossDiedEvent();
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
class UBoxComponent* BoxComp;
virtual void NotifyActorBeginOverlap(AActor* OtherActor);
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
FOnBossDiedDelegate OnBossDied;
};
BossActor.cpp
#include "BossActor.h"
#include "Components/BoxComponent.h"
#include "BPCommunicationGameMode.h"
// Sets default values
ABossActor::ABossActor()
{
// 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;
BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComp"));
BoxComp->SetBoxExtent(FVector(128, 128, 64));
BoxComp->SetVisibility(true);
}
// Called when the game starts or when spawned
void ABossActor::BeginPlay()
{
Super::BeginPlay();
}
void ABossActor::HandleBossDiedEvent()
{
OnBossDied.ExecuteIfBound();
}
void ABossActor::NotifyActorBeginOverlap(AActor* OtherActor)
{
HandleBossDiedEvent();
}
// Called every frame
void ABossActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
このセクションの結果
このセクションでは、Box コンポーネントを含む BossActor クラスと、イベントが実行されたときに他のアクタ クラスにシグナルを送るのに使用される OnBossDied イベントのデリゲートを作成しました。
3 - インタラクティブなドアを作成する
-
C++ クラス ウィザード で、新規 Actor クラスを「 DoorActor 」という名前で作成します。
-
「DoorActor.h」ファイルに移動し、次のように宣言します。
include "Components/TimelineComponent.h"
-
次に以下のクラス定義を宣言します。
// Variable to hold the Curve asset UPROPERTY(EditInstanceOnly) UCurveFloat* DoorTimelineFloatCurve; protected: void BossDiedEventFunction(); UPROPERTY(EditInstanceOnly,BlueprintReadWrite) class ABossActor* BossActorReference; //MeshComponents to represent Door assets UPROPERTY(VisibleAnywhere, BlueprintReadWrite) UStaticMeshComponent* DoorFrame; UPROPERTY(VisibleAnywhere, BlueprintReadWrite) UStaticMeshComponent* Door; //TimelineComponent to animate Door meshes UPROPERTY(VisibleAnywhere, BlueprintReadWrite) UTimelineComponent* DoorTimelineComp; //Float Track Signature to handle our update track event FOnTimelineFloat UpdateFunctionFloat; //Function which updates our Door's relative location with the timeline graph UFUNCTION() void UpdateTimelineComp(float Output);
-
「 DoorActor.cpp 」内に、次のクラス ライブラリを宣言します。
include "BossActor.h"
-
次のクラス定義を実装します。
ADoorActor::ADoorActor() { //Create our Default Components DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh")); Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh")); DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp")); //Setup our Attachments DoorFrame->SetupAttachment(RootComponent); Door->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform); Door->SetRelativeLocation(FVector(0, 35, 0)); } // Called when the game starts or when spawned void ADoorActor::BeginPlay() { Super::BeginPlay(); //Binding our float track to our UpdateTimelineComp Function's output UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp); //If we have a float curve, bind it's graph to our update function if (DoorTimelineFloatCurve) { DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat); } if (BossActorReference) { BossActorReference->OnBossDied.BindUObject(this, &ADoorActor::BossDiedEventFunction); } } void ADoorActor::BossDiedEventFunction() { DoorTimelineComp->Play(); } void ADoorActor::UpdateTimelineComp(float Output) { // Create and set our Door's new relative location based on the output from our Timeline Curve FRotator DoorNewRotation = FRotator(0.0f, Output, 0.f); Door->SetRelativeRotation(DoorNewRotation); }
-
コードを コンパイル します。
-
コンテンツ ブラウザ で [Add/Import] > [Miscellaneous] > [Curve] を選択します。
-
[CurveFloat] を選択して CurveFloat アセットに「 DoorCurveFloat 」という名前を付け、DoorCurveFloat アセットをダブルクリックします。2 つのキーを Float カーブに追加し、1 つのキーに時間の値「(0,0)」を、もう 1 つ のキーに時間の値「(4,90)」を割り当てます。
-
Shift キーを押しながら 2 つのキーを選択して Auto Cubic interpolation に設定し、カーブを保存します。
-
DoorCurveFloat を保存します。
-
コンテンツ ブラウザから「 C++ Classes 」フォルダに移動して DoorActor クラスを右クリックし、 [Create Blueprint Class based on Door Actor] を選択します。ブループリント アクタに「 BP_DoorActor 」という名前を付けます。
-
BP_DoorActor の [Class Defaults (クラスのデフォルト)] 内で [Components (コンポーネント)] タブを探し、 DoorFrame Static Mesh コンポーネント を選択して [Details (詳細)] パネルに移動して [Static Mesh (スタティック メッシュ)]を「 SM_DoorFrame 」に変更します。
-
[Components (コンポーネント)] パネルで DoorMesh コンポーネントを選択します。 [Details] パネルに移動し、スタティックメッシュを SM_Door に変更します。
-
[Details (詳細)] パネルの [Door Timeline Float Curve (ドア タイムライン フロート カーブ)] から [DoorCurveFloat] を選択します。
-
ブループリントを コンパイル して 保存 します。
完成コード
DoorActor.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TimelineComponent.h"
#include "DoorActor.generated.h"
UCLASS()
class BPCOMMUNICATION_API ADoorActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ADoorActor();
// Variable to hold the Curve asset
UPROPERTY(EditInstanceOnly)
UCurveFloat* DoorTimelineFloatCurve;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
void BossDiedEventFunction();
UPROPERTY(EditInstanceOnly,BlueprintReadWrite)
class ABossActor* BossActorReference;
//MeshComponents to represent Door assets
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UStaticMeshComponent* DoorFrame;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UStaticMeshComponent* Door;
//TimelineComponent to animate Door meshes
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
UTimelineComponent* DoorTimelineComp;
//Float Track Signature to handle our update track event
FOnTimelineFloat UpdateFunctionFloat;
//Function which updates our Door's relative location with the timeline graph
UFUNCTION()
void UpdateTimelineComp(float Output);
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
DoorActor.cpp
#include "DoorActor.h"
#include "BossActor.h"
// Sets default values
ADoorActor::ADoorActor()
{
// 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;
//Create our Default Components
DoorFrame = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorFrameMesh"));
Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));
DoorTimelineComp = CreateDefaultSubobject<UTimelineComponent>(TEXT("DoorTimelineComp"));
//Setup our Attachments
DoorFrame->SetupAttachment(RootComponent);
Door->AttachToComponent(DoorFrame, FAttachmentTransformRules::KeepRelativeTransform);
Door->SetRelativeLocation(FVector(0, 35, 0));
}
// Called when the game starts or when spawned
void ADoorActor::BeginPlay()
{
Super::BeginPlay();
//Binding our float track to our UpdateTimelineComp Function's output
UpdateFunctionFloat.BindDynamic(this, &ADoorActor::UpdateTimelineComp);
//If we have a float curve, bind its graph to our update function
if (DoorTimelineFloatCurve)
{
DoorTimelineComp->AddInterpFloat(DoorTimelineFloatCurve, UpdateFunctionFloat);
}
if (DoorTimelineFloatCurve)
{
BossActorReference->OnBossDied.BindUObject(this, &ADoorActor::BossDiedEventFunction);
}
}
void ADoorActor::BossDiedEventFunction()
{
DoorTimelineComp->Play();
}
void ADoorActor::UpdateTimelineComp(float Output)
{
// Create and set our Door's new relative location based on the output from our Timeline Curve
FRotator DoorNewRotation = FRotator(0.0f, Output, 0.f);
Door->SetRelativeRotation(DoorNewRotation);
}
// Called every frame
void ADoorActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
このセクションの結果
このセクションでは、 BossActor クラス内にある OnBossDied イベント ディスパッチャーにバインドするインタラクティブな DoorActor を作成しました。このバインディングは、 Begin Play 時に発生しますが、BossActor の Box コンポーネント 内のオーバーラップによってイベントがトリガーされた時はいつでもランタイム時に実行されます。
5 - イベント ディスパッチャーをテストする
-
BP_Door ブループリントをレベルにドラッグします。 [Details(詳細)] パネルに行き、 [Boss Reference Died] のドロップダウンをクリックし、 BP_BossDied を検索し、選択します。
-
Bp_DoorActor を選択した状態で、 [Details (詳細)] パネルに移動し、 [Boss Actor Reference (ボス アクタ参照)] ドロップダウンの矢印をクリックして、「 BP_BossActpr 」を検索して選択します。
-
[Play (プレイ)] を押して BP_BossActor に近づき、ゲーム内のボスが死ぬシミュレートをトリガーします。
このセクションの結果
このセクションでは、レベル内で BP_DoorActor をテストしました。 BP_BossActor's Box コンポーネント が別のアクタに重なってデリゲートをトリガーしたときに発生する OnBossDied イベントにアクタが反応することを確認しました。
このガイドでは、デリゲートを使用して複数のアクタ クラス ブループリント間で通信する方法を学習しました。
次のステップ
デリゲートの使い方が分かったところで、今度は「 ブループリント通信 」ドキュメント ページで参照されている他の通信手段を見てみましょう。