UE4 C++学习笔记之替换物品

任务:给武器修改功能,通过按键拾取并替换原有武器

第一步、项目设置添加操作映射

第二步、修改相关代码

代码修改导图如下:

 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();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_44928892/article/details/108232629