整体框架:
拾取武器
要在 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
// 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 spawnedvirtual void BeginPlay() override;public: // Called every framevirtual void Tick(float DeltaTime) override;
};
```
// 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 actionInputComponent->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 spawnedvirtual void BeginPlay() override;public: // Called every framevirtual void Tick(float DeltaTime) override;// Called to bind functionality to inputvirtual 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 actionPlayerInputComponent->BindAction("Interact", IE_Pressed, this, &AYourCharacter::PickupItem);
}void AYourCharacter::PickupItem()
{// 实现具体的拾取逻辑// 例如:查找最近的可拾取物品,然后将其加入玩家的物品列表
}
```
1. 枪支拾取动画
创建Text Block
编译保存
在h文件写入 ,属性
private:UPROPETY(VisibleAnywhere, Category = "Weapon Properties")class UWidgetComponent* PickupWidget;
先写这个:
CreateDefaultSubobject<UWidgetComponent>(TEXT("PickupWidget"));
在 Unreal Engine 中,SetupAttachment()
方法用于将一个组件附加到另一个组件上。这样做的目的是为了建立组件之间的层次关系,从而使得它们能够在场景中正确地相对于彼此移动、旋转和缩放。
关于 RootComponent
:
- RootComponent: 这个术语指的是一个 Actor 的根组件。在 Unreal Engine 中,每个 Actor 都有一个根组件,所有其他的子组件都将直接或间接地附加在这个根组件上。根组件通常是
USceneComponent
的实例,它可以是一个静态网格体、骨骼网格体或其他类型的组件。
对应h文件
protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;UFUNCTION()virtual void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent,AActor * OtherComp,int32 OtherBodyIndex,bool bFromSweep,const FHitResult& SweepResult);
代码定位上层
拾取代码实现
//简而言之,这段代码的作用是:当武器的碰撞组件检测到与 ABlasterCharacter 类型的演员发生重叠时
// ,就会显示一个拾取提示(如一个 UI 元素)给玩家。这通常用于提示玩家可以拾取或互动的武器。
void AWeapon::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent,AActor*OtherActor,UPrimitiveComponent* OtherComp)
{ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(OtherActor);
if (BlasterCharacter && PickupWidget) { //PickupWidget检查不是空指针PickupWidget->SetVisibility(true);
}}
void AWeapon::BeginPlay()
{Super::BeginPlay();if (PickupWidget) {PickupWidget->SetVisibility(false); //应该是拾取成功后,让地面不可见}}
在服务器上变的不可见,应该是不捡枪,其他玩家可以看到E键盘拾取,捡起枪后,其他玩家看不到e键拾取了