第 10 天:UE5 交互系统,拾取物品 & 触发机关!

🎯 目标:

✅ 理解 UE5 交互系统(Interaction System)

✅ 使用 C++ 让玩家拾取物品

✅ 创建交互触发器(Trigger)激活机关

✅ 使用射线检测(Raycast)触发交互

1️⃣ UE5 交互系统概述

在 Unreal Engine 5 中,交互系统允许玩家 拾取物品、开门、触发机关、启动事件 等。常见的交互方式包括:

方式 描述 适用场景
Overlap(重叠检测) 进入某个区域时自动触发 触发机关、进入房间
Raycast(射线检测) 通过鼠标/键盘瞄准并触发 拾取物品、开门、射击
按键交互(Key Press) 按 E 或 F 触发 NPC 对话、拾取物品

今天,我们将实现 拾取物品 和 触发机关,并使用 E 键进行交互!🚀

2️⃣ 创建可拾取物品(PickupItem)

🔹 新建 PickupItem 类

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

🔹 修改 PickupItem.h

📌 添加 StaticMeshComponent 作为物品的模型,并设置重叠检测

cpp 复制代码
#pragma once

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

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

public:
    APickupItem();

protected:
    virtual void BeginPlay() override;

private:
    UPROPERTY(VisibleAnywhere)
    UStaticMeshComponent* MeshComponent;

    UFUNCTION()
    void OnOverlap(AActor* OverlappedActor, AActor* OtherActor);
};

🔹 修改 PickupItem.cpp

📌 初始化 MeshComponent,并绑定 Overlap 事件

cpp 复制代码
#include "PickupItem.h"
#include "GameFramework/Actor.h"

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

    // 创建 StaticMesh 组件
    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->SetCollisionProfileName(TEXT("OverlapAllDynamic"));
    OnActorBeginOverlap.AddDynamic(this, &APickupItem::OnOverlap);
}

void APickupItem::BeginPlay()
{
    Super::BeginPlay();
}

void APickupItem::OnOverlap(AActor* OverlappedActor, AActor* OtherActor)
{
    if (OtherActor && OtherActor != this)
    {
        UE_LOG(LogTemp, Warning, TEXT("%s 被 %s 拾取!"), *GetName(), *OtherActor->GetName());

        // 销毁物品(模拟拾取)
        Destroy();
    }
}

✅ 现在,玩家走近 PickupItem,物品会消失并打印拾取信息!

3️⃣ 使用射线检测(Raycast)拾取物品

有时候,我们希望 玩家按 E 键瞄准并拾取物品,可以使用 射线检测(Raycast) 来实现。

📌 修改 PlayerCharacter.h

cpp 复制代码
void Interact();

📌 修改 PlayerCharacter.cpp

cpp 复制代码
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    PlayerInputComponent->BindAction("Interact", IE_Pressed, this, &APlayerCharacter::Interact);
}

void APlayerCharacter::Interact()
{
    FVector Start = FirstPersonCamera->GetComponentLocation();
    FVector End = Start + (FirstPersonCamera->GetForwardVector() * 500.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());

            // 销毁物品
            HitResult.GetActor()->Destroy();
        }
    }
}

📌 修改 PickupItem.cpp

cpp 复制代码
MeshComponent->SetCollisionProfileName(TEXT("BlockAllDynamic"));

✅ 现在,按 E 键可以瞄准并拾取物品!

4️⃣ 创建触发机关(Trigger Mechanism)

我们将创建一个 TriggerSwitch,当玩家靠近时 打开机关(比如门)。

🔹 新建 TriggerSwitch 类

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

🔹 修改 TriggerSwitch.h

📌 添加 BoxComponent 作为触发区域

cpp 复制代码
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "TriggerSwitch.generated.h"

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

public:
    ATriggerSwitch();

protected:
    virtual void BeginPlay() override;

private:
    UPROPERTY(VisibleAnywhere)
    UBoxComponent* TriggerBox;

    UFUNCTION()
    void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,bool bFromSweep, const FHitResult& SweepResult);
};

🔹 修改 TriggerSwitch.cpp

📌 初始化触发器,并在玩家进入时触发事件

cpp 复制代码
#include "TriggerSwitch.h"
#include "GameFramework/Actor.h"

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

    // 创建 BoxComponent 作为触发区域
    TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));
    RootComponent = TriggerBox;
    TriggerBox->SetCollisionProfileName(TEXT("Trigger"));

    // 绑定重叠事件
    TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerSwitch::OnOverlap);
}

void ATriggerSwitch::BeginPlay()
{
    Super::BeginPlay();
}

void ATriggerSwitch::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,bool bFromSweep, const FHitResult& SweepResult)
{
    if (OtherActor)
    {
        UE_LOG(LogTemp, Warning, TEXT("触发机关: %s"), *OtherActor->GetName());
    }
}

✅ 当玩家进入 TriggerBox 区域,控制台会打印触发信息!

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

问题 解决方案
物品不消失 确保 Destroy() 被调用
E 键无效 确保 Interact() 正确绑定到 SetupPlayerInputComponent
触发器没反应 BoxComponent 需设置 Trigger 碰撞模式

🎯 总结

✅ 实现 Overlap 事件,让物品可拾取

✅ 使用 E 键 + 射线检测拾取物品

✅ 创建 TriggerSwitch 触发机关

✅ 使用 BoxComponent 检测玩家进入区域

🎮 明天我们将学习 AI 交互系统,创建一个智能 NPC! 🚀

相关推荐
Nuanyt1 天前
Agent 学习笔记(下篇三):上线工程、进阶选择与操作界面(Stage 7 / 7.5 / 8 + 延伸路线)
笔记·python·学习·memory·aiagent·harness
叼烟扛炮1 天前
Linux 学习笔记(四十一):TCP 并发演进——从单进程到多线程服务器
linux·运维·服务器·网络·笔记·学习·tcp/ip
叼烟扛炮1 天前
Linux 学习笔记(四十四):HTTP 协议解析与极简 Web 服务器实战
linux·服务器·学习
songyuc1 天前
【Manskill3】TableSceneBuilder学习笔记
pytorch·笔记·学习
外收内放1 天前
Python基础语法练习题(75)
开发语言·python·学习
kyrie_sakura2 天前
大模型学习20 大模型学习 - LangChain3 - Agents
人工智能·学习·langchain
zroooo2 天前
计算机学习-知识庞大而繁杂
笔记·学习
坤坤子吖2 天前
算法学习——单调队列
开发语言·c++·笔记·学习·算法
乌暮2 天前
请求进门先安检:Spring 拦截器与统一功能实战指南
java·开发语言·后端·学习·spring
技术人生0012 天前
DirectX修复工具下载安装教程-Windows系统游戏dll修复工具下载安装修复教程
windows·游戏