第 9 天:UE5 物理系统 & 碰撞检测全解析!

🎯 目标:

✅ 理解 UE5 物理系统和碰撞检测的核心概念

✅ 使用 C++ 为 Actor 启用物理模拟

✅ 实现碰撞检测,处理物体交互

✅ 使用射线检测(Raycast)感知环境

1️⃣ UE5 物理系统概述

Unreal Engine 5 提供了强大的 物理引擎(Physics Engine) ,允许我们对游戏对象进行 重力、碰撞、力学计算,从而实现逼真的物理效果。

🔹 物理系统的核心组件

组件 作用
UStaticMeshComponent 允许物体在场景中显示
UPhysicsConstraintComponent 限制物体移动,如铰链、弹簧
URigidBodyComponent 处理刚体物理模拟
UCollisionComponent 处理碰撞检测

💡 启用 Simulate Physics,UE5 就会自动计算物理交互,例如掉落、碰撞等。

2️⃣ 让物体受重力影响

我们可以创建一个 PhysicsActor,使其受物理引擎控制。

🔹 创建 PhysicsActor

  1. 在 UE5 中 ,点击 "工具" → "新建 C++ 类"
  2. 选择 Actor 作为父类,命名为 PhysicsActor
  3. 点击"创建并添加到项目",等待 UE5 生成代码

🔹 修改 PhysicsActor.h

📌 为 Actor 添加 UStaticMeshComponent,并启用物理模拟

cpp 复制代码
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h"
#include "PhysicsActor.generated.h"

UCLASS()
class MYGAME_API APhysicsActor : public AActor
{
    GENERATED_BODY()

public:
    APhysicsActor();

protected:
    virtual void BeginPlay() override;

private:
    UPROPERTY(VisibleAnywhere)
    UStaticMeshComponent* MeshComponent;
};

🔹 修改 PhysicsActor.cpp

📌 初始化 StaticMeshComponent 并启用物理模拟

cpp 复制代码
#include "PhysicsActor.h"
#include "UObject/ConstructorHelpers.h"

APhysicsActor::APhysicsActor()
{
    PrimaryActorTick.bCanEverTick = true;

    // 创建静态网格组件
    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    RootComponent = MeshComponent;

    // 加载默认立方体模型
    static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/Engine/BasicShapes/Cube.Cube"));
    if (MeshAsset.Succeeded())
    {
        MeshComponent->SetStaticMesh(MeshAsset.Object);
    }

    // 启用物理模拟
    MeshComponent->SetSimulatePhysics(true);
    MeshComponent->SetMassOverrideInKg(NAME_None, 10.0f, true); // 设置质量
}

✅ **现在,这个 Actor 具有物理属性,并会在场景中掉落!**🎮

3️⃣ 处理碰撞检测(Overlap 和 Blocking)

在 UE5 物理系统中,碰撞检测分为 重叠检测(Overlap) 和 阻挡检测(Blocking)。

🔹 什么是 Overlap?

Overlap 用于检测 两个对象是否接触 ,适用于 触发器(Triggers)、拾取物品 等。

🔹 什么是 Blocking?

Blocking 用于 阻挡其他物体移动 ,适用于 墙壁、地面 等。

4️⃣ 实现碰撞检测

我们可以让 PhysicsActor 在 接触玩家时打印日志,以检测碰撞。

📌 修改 PhysicsActor.h

cpp 复制代码
UFUNCTION()
void ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor);

📌 修改 PhysicsActor.cpp

cpp 复制代码
void APhysicsActor::BeginPlay()
{
    Super::BeginPlay();

    // 绑定 Overlap 事件
    OnActorBeginOverlap.AddDynamic(this, &APhysicsActor::OnActorBeginOverlap);
}

// 触发重叠事件
void APhysicsActor::ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor)
{
    if (OtherActor && OtherActor != this)
    {
        UE_LOG(LogTemp, Warning, TEXT("%s 与 %s 发生了重叠!"), *GetName(), *OtherActor->GetName());
    }
}

✅ 当玩家接触 PhysicsActor 时,控制台会打印碰撞信息!

5️⃣ 使用射线检测(Raycast)

射线检测(Raycast)是一种 从 A 点向 B 点发射一条不可见的光线 ,用于检测 是否击中某个物体(如子弹检测)。

📌 修改 PlayerCharacter.h

cpp 复制代码
void PerformRaycast();

📌 修改 PlayerCharacter.cpp

cpp 复制代码
void APlayerCharacter::PerformRaycast()
{
    FVector Start = FirstPersonCamera->GetComponentLocation();
    FVector End = Start + (FirstPersonCamera->GetForwardVector() * 1000.0f);

    FHitResult HitResult;
    FCollisionQueryParams CollisionParams;

    if (GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, CollisionParams))
    {
        if (HitResult.GetActor())
        {
            UE_LOG(LogTemp, Warning, TEXT("射线击中了: %s"), *HitResult.GetActor()->GetName());
        }
    }
}

✅ 按下 E 键,角色将发射射线,并检测是否击中物体!

6️⃣ 在 UE5 调整碰撞

为了更好地控制物体的碰撞,我们可以在 UE5 修改 Actor 的碰撞属性:

  1. 选中 PhysicsActor
  2. 在 Details(细节)面板 ,找到 Collision
  3. 将 Collision Preset 设为 Custom
  4. 启用 Simulate Physics
  5. 确保 Overlap 或 Block 设置正确

7️⃣ 常见问题 & 解决方案

问题 解决方案
物体没有掉落 确保 SetSimulatePhysics(true) 启用
碰撞没有触发 Collision Preset 需设置为 OverlapAll
射线检测无效 确保 LineTraceSingleByChannel 使用 ECC_Visibility

🎯 总结

✅ 使用 C++ 启用物体的物理模拟

✅ 实现 Overlap(重叠)和 Blocking(阻挡)检测

✅ 使用射线检测(Raycast)感知环境

✅ 在 UE5 进行碰撞调整,优化物理交互

🎮 明天我们将学习 UE5 交互系统,打造拾取物品和触发机关的功能! 🚀

相关推荐
weixin_460443562 小时前
2026年新修订《网络安全法》实施:Java私有化考试系统如何做好SBOM、漏洞治理与安全升级?
java·开发语言·在线考试系统·企业培训考试系统·宏远培训考试系统·国企培训考试系统·国产化培训系统
Cc.Y5 小时前
Java零基础入门:可变字符串与包装类:StringBuilder、StringBuffer 与 通讯录管理系统实战
java·开发语言·python
阿森_dev5 小时前
2027 届毕设选题怎么选:30 个 Java 方向选题的实现难度排序
java·开发语言·spring boot·毕业设计·课程设计
by209995 小时前
C++ 多态:同一个基类接口,调用不同的函数
开发语言·c++·经验分享·多态
笔墨登场说说5 小时前
flink bin/start-cluster.sh 帮我做成开机启动
开发语言·python
Sarvartha5 小时前
Lambda 表达式和函数式接口
java·开发语言
辣知6 小时前
辣知·化智77 三千年接力写就的一本书
学习
梦想平凡6 小时前
棋牌游戏技术实战(五):从对局事件重新执行规则,核对棋盘和最终状态
数据库·游戏·oracle
小白学大数据6 小时前
拼多多反爬对抗实战:Scrapy 中间件化采集架构解析
开发语言·scrapy·中间件·架构
一木 之林6 小时前
Dify学习笔记 01 · 平台入门与实战:部署、五类应用、RAG与MCP(第1-16集)
人工智能·笔记·学习·计算机视觉