UE5开发——射击武器类拾取

整体框架:

拾取武器

要在 Unreal Engine 5 (UE5) 中实现一个按 E 键拾取武器的功能,您可以遵循以下步骤:

步骤 1: 创建拾取物品的基础类

  1. 在 Content Browser 中创建一个新的 C++ 类,继承自 `AActor` 或者 `AStaticMeshActor`。

  2. 在该类中定义必要的变量,例如物品的类型、名称等。

  3. 添加事件处理器,用于检测玩家角色与物品之间的交互。

步骤 2: 实现拾取逻辑

  1. 在玩家角色的类中添加一个方法,用于处理与拾起物品相关的逻辑。

  2. 使用 `Overlap` 事件来检测玩家是否靠近物品。

  3. 当玩家按下 E 键时,调用上述方法。

步骤 3: 设置输入绑定

  1. 在项目的 `Input Settings` 中添加一个新的动作绑定,比如命名为 `Interact`。

  2. 将 `Interact` 动作绑定到 E 键。

  3. 在玩家控制器类中处理 `Interact` 输入事件。

示例代码

这里是一个简单的示例代码片段,展示了如何实现上述功能:#### 创建一个基础的拾取物品类 `APickupBase`

```cpp

cpp 复制代码
// APickupBase.h
#pragma once

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

UCLASS()
class YOURGAME_API APickupBase : public AActor
{
    GENERATED_BODY()

public:    
    APickupBase();

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Mesh")
    UStaticMeshComponent* Mesh;

    UFUNCTION()
    void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:    
    // Called every frame
    virtual void Tick(float DeltaTime) override;
};
```
cpp 复制代码
// APickupBase.cpp
#include "PickupBase.h"

APickupBase::APickupBase()
{
    Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    SetRootComponent(Mesh);
}

void APickupBase::BeginPlay()
{
    Super::BeginPlay();
    Mesh->OnComponentBeginOverlap.AddDynamic(this, &APickupBase::OnOverlapBegin);
}

void APickupBase::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

void APickupBase::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
    // 检测到玩家时,触发拾取逻辑
    if (OtherActor != this && OtherActor->ActorHasTag("Player"))
    {
        APlayerController* PlayerController = Cast<APlayerController>(OtherActor->GetController());
        if (PlayerController)
        {
            PlayerController->ClientStartCursorMode();
        }
    }
}
```

#### 在玩家控制器中处理输入
```cpp
// AYourPlayerController.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "YourPlayerController.generated.h"

UCLASS()
class YOURGAME_API AYourPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    AYourPlayerController();

protected:
    virtual void SetupInputComponent() override;

public:
    UFUNCTION(BlueprintCallable, Category = "Input")
    void Interact();

};
```

```cpp
// AYourPlayerController.cpp
#include "YourPlayerController.h"

AYourPlayerController::AYourPlayerController()
{
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
}

void AYourPlayerController::SetupInputComponent()
{
    Super::SetupInputComponent();

    // Bind action
    InputComponent->BindAction("Interact", IE_Pressed, this, &AYourPlayerController::Interact);
}

void AYourPlayerController::Interact()
{
    // 当玩家按下 E 键时,执行拾取操作
    if (auto* PlayerCharacter = Cast<AYourCharacter>(GetPawn()))
    {
        PlayerCharacter->PickupItem();
    }
}
```

#### 在玩家角色类中实现拾取逻辑
```cpp
// AYourCharacter.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "YourCharacter.generated.h"

UCLASS()
class YOURGAME_API AYourCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    AYourCharacter();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:    
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

    UFUNCTION(BlueprintCallable, Category = "Interaction")
    void PickupItem();
};
```

```cpp
// AYourCharacter.cpp
#include "YourCharacter.h"

AYourCharacter::AYourCharacter()
{
    // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
}

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

void AYourCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

void AYourCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    // Bind action
    PlayerInputComponent->BindAction("Interact", IE_Pressed, this, &AYourCharacter::PickupItem);
}

void AYourCharacter::PickupItem()
{
    // 实现具体的拾取逻辑
    // 例如:查找最近的可拾取物品,然后将其加入玩家的物品列表
}
```

1. 枪支拾取动画

创建Text Block

编译保存

在h文件写入 ,属性

cpp 复制代码
private:
	    UPROPETY(VisibleAnywhere, Category = "Weapon Properties")
		class UWidgetComponent* PickupWidget;

先写这个:

CreateDefaultSubobject<UWidgetComponent>(TEXT("PickupWidget"));

在 Unreal Engine 中,SetupAttachment() 方法用于将一个组件附加到另一个组件上。这样做的目的是为了建立组件之间的层次关系,从而使得它们能够在场景中正确地相对于彼此移动、旋转和缩放。

关于 RootComponent:

  • RootComponent : 这个术语指的是一个 Actor 的根组件。在 Unreal Engine 中,每个 Actor 都有一个根组件,所有其他的子组件都将直接或间接地附加在这个根组件上。根组件通常是 USceneComponent 的实例,它可以是一个静态网格体、骨骼网格体或其他类型的组件。

对应h文件

cpp 复制代码
protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UFUNCTION()
	virtual void OnSphereOverlap(
		UPrimitiveComponent* OverlappedComponent,
		AActor * OtherComp,
		int32 OtherBodyIndex,
		bool bFromSweep,
		const FHitResult& SweepResult
	);

代码定位上层

拾取代码实现

cpp 复制代码
//简而言之,这段代码的作用是:当武器的碰撞组件检测到与 ABlasterCharacter 类型的演员发生重叠时
// ,就会显示一个拾取提示(如一个 UI 元素)给玩家。这通常用于提示玩家可以拾取或互动的武器。
void AWeapon::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent,AActor*OtherActor,UPrimitiveComponent* OtherComp)
{
	ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(OtherActor);
if (BlasterCharacter && PickupWidget) {  //PickupWidget检查不是空指针
	PickupWidget->SetVisibility(true);
}

}
cpp 复制代码
void AWeapon::BeginPlay()
{
	Super::BeginPlay();
	if (PickupWidget) {
		PickupWidget->SetVisibility(false);  //应该是拾取成功后,让地面不可见
	}

}

在服务器上变的不可见,应该是不捡枪,其他玩家可以看到E键盘拾取,捡起枪后,其他玩家看不到e键拾取了

相关推荐
hkNaruto7 小时前
【AI】基于大模型的AI游戏地图生成、控制方案:AI Native Game Harness 迁移操作手册
前端·人工智能·游戏
揽星河..12 小时前
【C语言】猜数字游戏
c语言·算法·游戏
释厄62313 小时前
AI 军备竞赛悖论——为 AI 卖游戏但 AI 需要游戏母场景
人工智能·游戏·kotlin
努力学习的小廉17 小时前
UE5 入门系列(三):核心框架类全解析
ue5
郝学胜-神的一滴17 小时前
游戏设计:原型与开发 17:数字化系统里的思维体操
人工智能·游戏·游戏程序·游戏策划·游戏设计
驱动小百科1 天前
国产3A游戏《影之刃零》正式发售:售价及电脑配置要求介绍
游戏·影之刃零·影之刃零配置要求·影之刃零下载·影之刃零售价
信奥卷王2 天前
[GESP202312 六级] 闯关游戏
游戏
德迅云安全-上官2 天前
德迅游戏盾:面向 TCP 业务的分布式云安全防护方案
分布式·tcp/ip·游戏
科技那些事儿2 天前
旗舰游戏本 CPU 对决:锐龙 9 9955HX 对比酷睿 Ultra 9 275HX
游戏·智能手机·智能电视
njsgcs2 天前
老滚5 文本替换中文简体 仓库加经验glm5.3f
游戏