ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
On Component Hit とは
OnComponentHit は、物理シミュレーション中のコンポーネント (RigidBody) が他のオブジェクトと衝突した瞬間に呼ばれるイベントです。手榴弾の爆発、弾丸の命中、転がる物理オブジェクトの音再生など、衝突を契機としたゲームロジックの起点になります。
イベント発火の前提条件
| 設定 | 必要な値 | 場所 |
|---|---|---|
| Simulate Physics | true | Component → Physics |
| Simulation Generates Hit Events | true | Component → Collision |
| Collision Enabled | Query and Physics | Component → Collision |
| 相手 Collision Response | Block | 相手側のチャンネル応答 |
Blueprint での使い方
- Components → 物理シミュレーションする Mesh を選択
- Details パネル右上の + Add Event → On Component Hit
- Event Graph に新しいイベントノードが追加される
- 必要に応じて Hit Result を分解して使用
イベントの引数
| 引数 | 型 | 意味 |
|---|---|---|
| HitComponent | PrimitiveComponent | 自分のコンポーネント(衝突した側) |
| OtherActor | Actor | 衝突した相手アクター |
| OtherComp | PrimitiveComponent | 相手のコンポーネント |
| NormalImpulse | Vector | 衝突時に加わった力 (運動量変化) |
| Hit | FHitResult | 衝突詳細(位置・法線・物理マテリアル等) |
C++ で OnComponentHit にバインド
// Projectile.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Projectile.generated.h"
UCLASS()
class MYGAME_API AProjectile : public AActor
{
GENERATED_BODY()
public:
AProjectile();
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* Mesh;
UPROPERTY(EditAnywhere, Category = "Damage")
float BaseDamage = 50.0f;
protected:
virtual void BeginPlay() override;
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComp,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
FVector NormalImpulse,
const FHitResult& Hit);
};// Projectile.cpp
AProjectile::AProjectile()
{
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
RootComponent = Mesh;
Mesh->SetSimulatePhysics(true);
Mesh->SetNotifyRigidBodyCollision(true); // ★ Hit Events 有効
Mesh->SetCollisionProfileName(TEXT("PhysicsActor"));
}
void AProjectile::BeginPlay()
{
Super::BeginPlay();
Mesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);
}
void AProjectile::OnHit(UPrimitiveComponent* HitComp,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
FVector NormalImpulse,
const FHitResult& Hit)
{
if (!OtherActor || OtherActor == this) return;
UE_LOG(LogTemp, Log, TEXT("Hit %s at %s, impulse=%s"),
*OtherActor->GetName(),
*Hit.ImpactPoint.ToString(),
*NormalImpulse.ToString());
// ダメージ計算 (運動量に比例)
const float Damage = BaseDamage * (NormalImpulse.Size() / 10000.0f);
UGameplayStatics::ApplyDamage(OtherActor, Damage, nullptr, this, nullptr);
// 衝突パーティクル
UGameplayStatics::SpawnEmitterAtLocation(
GetWorld(), ImpactEffect, Hit.ImpactPoint, Hit.ImpactNormal.Rotation());
// 自分は消滅
Destroy();
}
Hit Result の主要フィールド
| フィールド | 型 | 意味 |
|---|---|---|
| ImpactPoint | Vector | 衝突したワールド座標 |
| ImpactNormal | Vector | 衝突面の法線ベクトル |
| Location | Vector | 命中時の自分の位置 |
| Normal | Vector | 進行方向の法線 |
| BoneName | FName | 当たったボーン名 (SkeletalMesh) |
| PhysMaterial | PhysicalMaterial | 当たった面の物理マテリアル |
| bBlockingHit | bool | ブロック衝突か(Overlap でなく) |
Notify Rigid Body Collision 設定の重要性
C++ では SetNotifyRigidBodyCollision(true)、Blueprint では Details → Collision → Simulation Generates Hit Events にチェックを入れないと、物理衝突しても OnComponentHit が呼ばれません。
// 動的に切替
Mesh->SetNotifyRigidBodyCollision(true); // = bGenerateHitEvents = true
Mesh->BodyInstance.bNotifyRigidBodyCollision = true; // 内部フラグ
OnComponentHit vs OnActorHit
| イベント | 対象 | 用途 |
|---|---|---|
| OnComponentHit | 個別の Primitive Component | 細かい制御(特定パーツのみ判定) |
| OnActorHit | アクター全体 | 大まかな衝突検知 |
Sweep Hit との違い
キャラ移動 (MoveComponent) や AddActorWorldOffset(Sweep=true) で動かしたときの衝突は、物理シミュレーションではなくスイープテストです。これも OnComponentHit を発火させるには NotifyRigidBodyCollision 相当の設定が必要です:
// Sweep 移動でも OnComponentHit を発火させる
FHitResult Hit;
SetActorLocation(NewLocation, /*bSweep=*/true, &Hit);
if (Hit.bBlockingHit)
{
// 手動で同等の処理
OnHit(GetRootComponent(),
Hit.GetActor(),
Hit.GetComponent(),
FVector::ZeroVector,
Hit);
}
サンプル: 弾の命中処理
[Blueprint: BP_Bullet]
Event BeginPlay
→ Set Notify Rigid Body Collision (Mesh, true)
Event On Component Hit (Mesh)
├ Other Actor → Cast to BP_Enemy
│ └ Apply Damage (Damage=20)
│
├ Spawn Emitter At Location
│ Template: P_Impact
│ Location: Hit Result → Impact Point
│ Rotation: Hit Result → Impact Normal → Make Rot From X
│
├ Spawn Sound At Location (Hit Result → Impact Point)
│
└ Destroy Actor (Self)
サンプル: 衝突強度でダメージを変える
void AMyVehicle::OnHit(... FVector NormalImpulse, const FHitResult& Hit)
{
const float Speed = GetVelocity().Size(); // cm/s
const float ImpactMag = NormalImpulse.Size();
// 5 m/s 未満は無視
if (Speed < 500.0f) return;
// ImpactMag が大きいほどダメージ
const float Dmg = FMath::Clamp(ImpactMag / 5000.0f, 0.0f, 100.0f);
if (AActor* Hit_ = Hit.GetActor())
{
UGameplayStatics::ApplyDamage(Hit_, Dmg, nullptr, this, nullptr);
}
// 物理マテリアルで音を変える
if (Hit.PhysMaterial.IsValid())
{
UPhysicalMaterial* PM = Hit.PhysMaterial.Get();
if (PM == MetalPhysMat)
UGameplayStatics::PlaySoundAtLocation(this, MetalHitSound, Hit.ImpactPoint);
else if (PM == WoodPhysMat)
UGameplayStatics::PlaySoundAtLocation(this, WoodHitSound, Hit.ImpactPoint);
}
}
よくあるトラブル
| 症状 | 原因 | 対処 |
|---|---|---|
| イベントが発火しない | Notify Rigid Body Collision OFF | true に |
| キャラを撃っても無反応 | Capsule の Collision が Overlap | Block に変更 or 弾を Trace 方式に |
| 高速の弾が貫通 | Tunneling | CCD 有効化 or Projectile Component の Sweep 使う |
| 同じ衝突で何度も発火 | 跳ね返り中も呼ばれる | 一度処理したらフラグ立てる / Destroy |
| NormalImpulse が常にゼロ | 物理シミュレーションでない | Simulate Physics 有効に |
FAQ
Q: Projectile Movement Component の場合は?
A: UProjectileMovementComponent の OnProjectileBounce / OnProjectileStop イベントを使うのが一般的。OnComponentHit も併用可能。
Q: ImpactNormal が思った方向と違う
A: ImpactNormal は衝突面の法線(壁の向き)です。弾の進行方向と反対側を向きます。粒子効果の向きには Impact Normal をそのまま使うのが正解。
Q: マルチプレイで二重ダメージになる
A: OnComponentHit はサーバとクライアント両方で発火します。HasAuthority() でサーバ側だけで ApplyDamage を実行してください。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- Event BeginPlay
- Event ActorBeginOverlap
- Event Tick
- on component begin overlap
- On Component Hit
- CameraBoom(Spring Arm)
- Get Player Character
- Nav Mesh Bounds Volume
- AI MoveTo
- Pawn
- Create Render Target 2D
- Take High Res Screenshotノード
- Sphere Reflection Capture
- Event Tickノード
- ウィジェットのキャンバスパネル
- DefaultSceneRoot
- FloatingPawnMovement
- Set World Rotation
- Event Any Damage
- Set World Rotation
- VInterp To
- Get Socket Transform
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?