任务:给武器修改功能,通过按键拾取并替换原有武器
第一步、项目设置添加操作映射
第二步、修改相关代码
代码修改导图如下:
Man.h关键部分代码如下:
public:
//声明物品类,储存当前重叠的Item类
UPROPERTY()
class AItem* ActiveOverlapItem;
//声明函数:设置当前武器
UFUNCTION()
void SetWeapon(class AWeapon* Weapon);
//声明函数:装备武器
UFUNCTION()
void EquipWeapon();
protected:
//声明武器类:储存当前装备的武器
UPROPERTY(VisibleAnywhere)
class AWeapon* EquippedWeapon;
Man.cpp关键代码如下:
//初始化相关指针
AMan::AMan()
{
……
ActiveOverlapItem = nullptr;
EquippedWeapon = nullptr;
……
}
void AMan::SetWeapon(AWeapon* Weapon)
{
//如果已装备武器,则销毁当前装备武器
if (EquippedWeapon)
{
EquippedWeapon->Destroy();
}
if (EquippedWeapon == nullptr)
{
EquippedWeapon = Weapon;
}
}
void AMan::EquipWeapon()
{
AWeapon* Weapon = Cast<AWeapon>(ActiveOverlapItem);
if (Weapon)
{
//调用武器类的Equip函数,将其附着在自身
Weapon->Equip(this);
//重叠物品指针设为空
ActiveOverlapItem = nullptr;
}
}
//绑定相关按键和函数
void AMan::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
……
PlayerInputComponent->BindAction("PickUp", IE_Pressed, this, &AMan::EquipWeapon);
……
}
Weapon.h代码如下:
#pragma once
#include "CoreMinimal.h"
#include "Item.h"
#include "Weapon.generated.h"
/**
*
*/
UCLASS()
class LEARNTEST_API AWeapon : public AItem
{
GENERATED_BODY()
public:
AWeapon();
UPROPERTY(EditAnywhere, BlueprintReadOnly)
class USkeletalMeshComponent* WeaponMesh;
//重写父类重叠函数
virtual void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;
virtual void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) override;
//声明函数:装备武器
void Equip(class AMan* Picker);
};
Weapon.cpp代码如下:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon.h"
#include "Man.h"
#include "Components\StaticMeshComponent.h"
#include "Particles\ParticleSystemComponent.h"
#include "Sound\SoundCue.h"
#include "Components\SkeletalMeshComponent.h"
#include "Components\SphereComponent.h"
#include "Containers\UnrealString.h"
#include "Engine\Engine.h"
AWeapon::AWeapon()
{
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh"));
WeaponMesh->SetupAttachment(StaticMesh);
}
//当物品开始重叠
void AWeapon::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
Super::OnOverlapBegin(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
if (OtherActor)
{
AMan* Picker = Cast<AMan>(OtherActor);
if (Picker)
{
//当重叠的角色当前没有已重叠物品时可触发事件,设置重叠物品,打印提示信息
if (Picker->ActiveOverlapItem == nullptr)
{
Picker->ActiveOverlapItem = this;
TArray<FStringFormatArg> StringArray;
StringArray.Add(GetName());
GEngine->AddOnScreenDebugMessage(-1, 100, FColor::Blue, FString::Format(TEXT("按F装备武器:{0}"), StringArray), false, FVector2D(2, 2));
}
}
}
}
//当重叠事件结束
void AWeapon::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
Super::OnOverlapEnd(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex);
if (OtherActor)
{
AMan* Picker = Cast<AMan>(OtherActor);
if (Picker)
{
//如果角色当前重叠对象为自身,则将其重置为空指针,并清除提示信息
if (Picker->ActiveOverlapItem == this)
{
Picker->ActiveOverlapItem = nullptr;
GEngine->ClearOnScreenDebugMessages();
}
}
}
}
void AWeapon::Equip(AMan* Picker)
{
if (Picker)
{
WeaponMesh->SetCollisionResponseToAllChannels(ECR_Ignore);
WeaponMesh->SetSimulatePhysics(false);
ParticleComp->SetActive(false);
//解除重叠事件绑定
Sphere->OnComponentBeginOverlap.RemoveDynamic(this, &AItem::OnOverlapBegin);
Sphere->OnComponentEndOverlap.RemoveDynamic(this, &AItem::OnOverlapEnd);
AttachToComponent(Picker->GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, "weapon_r");
//清除提示信息
GEngine->ClearOnScreenDebugMessages();
}
}