1 定义并实现交互接口
接口定义:
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "MyInterActInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UMyInterActInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class ARPG_CPLUS_API IMyInterActInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void OnInterAct(APawn* InstigatorPawn);
};
实现接口:
cpp
class ARPG_CPLUS_API AInterActTrigger : public AActor,public IMyInterActInterface
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AInterActTrigger();
virtual void OnInterAct_Implementation(APawn* InstigatorPawn)override;
.......
}
实现里绑定碰撞函数,重叠时设置指针:
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "InterAct/InterActTrigger.h"
#include "Components/BoxComponent.h"
#include "Player/MyPlayer.h"
// Sets default values
AInterActTrigger::AInterActTrigger()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// 创建 BoxCollision 组件
BoxCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollision"));
BoxCollision->SetupAttachment(RootComponent); // 绑定到根组件
BoxCollision->SetBoxExtent(FVector(50.f, 50.f, 50.f)); // 设置碰撞盒的大小
BoxCollision->SetCollisionProfileName(TEXT("Trigger"));
}
// Called when the game starts or when spawned
void AInterActTrigger::BeginPlay()
{
Super::BeginPlay();
// 绑定重叠事件
BoxCollision->OnComponentBeginOverlap.AddDynamic(this, &AInterActTrigger::OnBeginOverlap);
BoxCollision->OnComponentEndOverlap.AddDynamic(this, &AInterActTrigger::OnEndOverlap);
}
// Called every frame
void AInterActTrigger::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AInterActTrigger::OnInterAct_Implementation(APawn* InstigatorPawn)
{
UE_LOG(LogTemp,Warning,TEXT("OnInterActInC++"));
}
// 开始重叠事件
void AInterActTrigger::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
//UE_LOG(LogTemp, Warning, TEXT("Begin Overlap with: %s"), *OtherActor->GetName());
if (OtherActor && OtherActor != this)
{
//UE_LOG(LogTemp, Warning, TEXT("Begin Overlap with: %s"), *OtherActor->GetName());
if(AMyPlayer* MyPlayer=Cast<AMyPlayer>(OtherActor))
{
MyPlayer->TriggerActorRef=this;
}
else
{
//UE_LOG(LogTemp, Warning, TEXT("AInterActTrigger-->MyPlayer is Not Valid"));
}
}
}
// 结束重叠事件
void AInterActTrigger::OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
if (OtherActor && OtherActor != this)
{
//UE_LOG(LogTemp, Warning, TEXT("End Overlap with: %s"), *OtherActor->GetName());
if(AMyPlayer* MyPlayer=Cast<AMyPlayer>(OtherActor))
{
MyPlayer->TriggerActorRef=nullptr;
}
else
{
//UE_LOG(LogTemp, Warning, TEXT("AInterActTrigger-->MyPlayer is Not Valid"));
}
}
}
这时就能把那一坨东西改为这简洁的一行:

优雅多了() ,然后就是恢复功能了。
2 把实现搬到各接口中
例如这个:

3 提取Bag和Warehouse父类
这里只贴提取完的父类声明,不得不说比之前舒服多了
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Enum/My_Enum.h"
#include "ItemManageBaseComponent.generated.h"
class UGameplayAbility;
USTRUCT(BlueprintType)
struct ARPG_CPLUS_API FMyItemInfo
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadOnly)
int32 ItemId;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
int64 CurrentOwnedCnt;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FString DisplayName;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
EMyItemType ItemType{EMyItemType::Item};
UPROPERTY(EditAnywhere, BlueprintReadOnly)
EMyArmType ArmType{EMyArmType::None};
UPROPERTY(EditAnywhere, BlueprintReadWrite)
EMyItemLocation ItemLocation{EMyItemLocation::None};
FMyItemInfo(int32 ItemId,int64 CurrentOwnedCnt,FString DisplayName) : ItemId(ItemId), CurrentOwnedCnt(CurrentOwnedCnt), DisplayName(DisplayName)
{}
FMyItemInfo()
{
ItemId = 0;
CurrentOwnedCnt=0;
DisplayName=FString("Default");
}
};
USTRUCT(BlueprintType)
struct ARPG_CPLUS_API FMyItemData:public FTableRowBase
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int ItemId;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int MaxOwnedCnt;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString ItemBaseName;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UTexture2D* Texture;
};
USTRUCT(BlueprintType)
struct ARPG_CPLUS_API FAttributeModifier
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString AttributeName;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool bIsPercent;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float PercentValue;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float AddedValue;
};
USTRUCT(BlueprintType)
struct ARPG_CPLUS_API FAttrModItemData:public FMyItemData
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FAttributeModifier> AttributeMods;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<TSubclassOf<UGameplayAbility>> GAsToAdd;
};
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ARPG_CPLUS_API UItemManageBaseComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UItemManageBaseComponent();
UItemManageBaseComponent(int MaxCellCntLimit,EMyItemLocation ItemLocation):
MaxCellCntLimit(MaxCellCntLimit),
ItemLocation(ItemLocation)
{
PrimaryComponentTick.bCanEverTick = true;
static ConstructorHelpers::FObjectFinder<UDataTable> DataTableAsset(TEXT("DataTable'/Game/Data/DataTable/ItemsData.ItemsData'"));
if (DataTableAsset.Succeeded())
{
ItemDataTable = DataTableAsset.Object;
}
}
UFUNCTION(BlueprintCallable)
virtual void SaveData();
UFUNCTION(BlueprintCallable)
virtual void LoadData();
UFUNCTION(BlueprintCallable)
virtual bool AddItemByArrayWithSave(const TArray<FMyItemInfo> ItemsToAdd);
UFUNCTION(BlueprintCallable)
virtual bool AddItemWithSave(FMyItemInfo& ItemToAdd);
UFUNCTION(BlueprintCallable)
virtual bool RemoveItemWithSave(const int ItemId,const int SubCnt);
UFUNCTION(BlueprintCallable)
virtual bool AddItemByArray(TArray<FMyItemInfo> ItemsToAdd);
UFUNCTION(BlueprintCallable)
virtual bool AddItem(FMyItemInfo& ItemToAdd);
UFUNCTION(BlueprintCallable)
virtual int GetAvailableSpace()const;
UFUNCTION(BlueprintCallable)
virtual bool RemoveItem(const int ItemId,const int SubCnt);
UFUNCTION(BlueprintCallable)
virtual void LogMes()const;
UFUNCTION(BlueprintCallable)
virtual FMyItemInfo GetItemInfoByItemId(int& ItemId);
static UDataTable* ItemDataTable;
UFUNCTION(BlueprintCallable)
static FMyItemData GetItemDataByItemId(const int ItemId);
UFUNCTION(BlueprintCallable)
virtual bool CheckIsEnough(const int ItemId,const int Cnt)const;
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemData")
TArray<FMyItemInfo> Items;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemData")
int MaxCellCntLimit{25};
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "ItemData")
EMyItemLocation ItemLocation{EMyItemLocation::None};
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};