タイトル: キャラクター同士がすり抜けてしまう問題の解決方法
SEOタイトル: UE5 キャラ同士がすり抜ける原因と解決|CapsuleComponent / Collision Profile
| この記事の要点 |
|
「すり抜ける」現象の症状
- キャラクター同士がぶつからずに重なる / 通り抜ける
- NPC が PlayerCharacter を素通りする
- マルチプレイで他プレイヤーをすり抜ける
- 高速移動 (ダッシュ / 投擲) で壁・敵を貫通する
原因の切り分け
| 確認 | 方法 | 該当時の対処 |
|---|---|---|
| Capsule の Collision Enabled | Details → Collision | No Collision → Query and Physics に |
| Collision Profile | Capsule の Collision Presets | Pawn → BlockAll / Custom |
| Pawn チャンネルの応答 | Collision Responses | Pawn = Block に |
| Object Type | Capsule の Object Type | Pawn であること |
| Movement Mode | CharacterMovement の Walking 等 | 正常な Mode か |
| 高速移動でのトンネリング | 移動速度 / Tick 間隔 | CCD 有効化 |
解決1: Collision Profile を「Pawn」→ ブロック寄りに変更
デフォルトの 「Pawn」プリセットは Pawn チャンネルへの応答が Overlap になっているため、Pawn 同士は重なって通り抜けます。これを Block に変えれば衝突します。
方法 A: プリセットを変える
- Character Blueprint を開く
- Components → CapsuleComponent を選択
- Details → Collision → Collision Presets
Pawn→BlockAllに変更
ただし BlockAll はカメラまでブロックしてしまうので、カスタムプリセットを作る方が実用的です。
方法 B: カスタムプリセットを作る
- Project Settings → Engine → Collision
- Preset → New
- 名前
CharacterBlockerなど - Object Type:
Pawn - Collision Responses:
- WorldStatic: Block
- WorldDynamic: Block
- Pawn: Block ← ここを変更
- PhysicsBody: Block
- Vehicle: Block
- Destructible: Block
- Visibility: Ignore(カメラトレースを妨げないため)
- Camera: Ignore
解決2: Blueprint / C++ で動的に応答変更
// Blueprint: BeginPlay
Get Capsule Component
└→ Set Collision Response To Channel
Channel: ECC_Pawn
New Response: ECR_Block// C++ (MyCharacter.cpp)
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
UCapsuleComponent* Cap = GetCapsuleComponent();
Cap->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block);
// または全プリセット切替
Cap->SetCollisionProfileName(TEXT("CharacterBlocker"));
}
解決3: 高速移動でのトンネリング (CCD)
キャラの移動速度が速いと、1 フレームで相手の向こう側に飛び越して当たり判定をすり抜けます (Tunneling)。Continuous Collision Detection (CCD) を有効化します:
// CapsuleComponent or 物理シミュレーション付きのコンポーネントで
GetCapsuleComponent()->SetUseCCD(true);
// CharacterMovementComponent の場合
GetCharacterMovement()->bForceMaxAccel = false;
GetCharacterMovement()->MaxStepHeight = 45.0f;
// 投擲物 (StaticMeshComponent + SimulatePhysics) の場合
ProjectileMesh->SetUseCCD(true);
CCD は計算コストが高いため、必要なオブジェクトだけに限定します。
解決4: Pawn vs Character の違い
| クラス | Collision | 備考 |
|---|---|---|
| APawn | 独自実装が必要 | 軽量だが衝突制御が手動 |
| ACharacter | CapsuleComponent + CharacterMovement | 2 足歩行に最適化、推奨 |
APawn 派生で歩行キャラを作る場合は自前で SetCollision を組む必要があります。通常は ACharacter を使ってください。
解決5: Movement Mode を確認
// 異常な MovementMode になっているとコリジョン無視で動くことがある
UCharacterMovementComponent* MC = GetCharacterMovement();
switch (MC->MovementMode)
{
case MOVE_None: UE_LOG(LogTemp, Warning, TEXT("None - 動かない")); break;
case MOVE_Walking: /* 正常 */ break;
case MOVE_NavWalking: /* Nav Mesh 移動 */ break;
case MOVE_Falling: /* 落下 */ break;
case MOVE_Swimming: /* 水中 */ break;
case MOVE_Flying: /* 空中(Walking より衝突弱め) */ break;
case MOVE_Custom: /* カスタム */ break;
}
解決6: Push Force でぶつかった相手を押す
ブロックだけだと相手が動かない場合、押し出す力を有効に:
// CharacterMovementComponent
GetCharacterMovement()->bPushForceUsingZOffset = false;
GetCharacterMovement()->StandingDownwardForceScale = 1.0f;
GetCharacterMovement()->InitialPushForceFactor = 500.0f;
GetCharacterMovement()->PushForceFactor = 750000.0f;
// 物理シミュレーション対象を押すなら
GetCharacterMovement()->bEnablePhysicsInteraction = true;
GetCharacterMovement()->bPushForceScaledToMass = true;
マルチプレイヤーでの注意点
- Server の Capsule のコリジョン設定が権威。クライアントだけ書き換えると同期ずれが発生
- Replicated Movement が有効か確認:
SetReplicates(true)+SetReplicateMovement(true) - クライアント予測でガクつく場合は
NetUpdateFrequencyを 30〜60 に上げる
デバッグ用ビジュアライズ
// コリジョン形状を表示
// コンソールコマンド
ShowFlag.Collision 1
// 特定アクターのみ
DrawDebugCapsule(GetWorld(),
GetActorLocation(),
GetCapsuleComponent()->GetScaledCapsuleHalfHeight(),
GetCapsuleComponent()->GetScaledCapsuleRadius(),
GetActorRotation().Quaternion(),
FColor::Green, false, 5.0f);
FAQ
Q: NPC だけプレイヤーをすり抜ける
A: NPC 側の Capsule の Collision Profile を確認。Pawn プリセットだと Pawn 同士は Overlap のままです。
Q: 弾だけはキャラを貫通させたい
A: 弾の Object Type を Projectile 用 Trace Channel にして、Pawn への応答を Block に。または弾の Visibility を Ignore に。
Q: BlockAll に変えるとカメラがキャラ越しに見えない
A: カスタムプリセットで Camera チャンネルだけ Ignore に。SpringArm の Trace チャンネルも合わせる。