UE4 C++基础回顾1

1、C++创建enum,E开头

//表示Item的类型
UENUM(BlueprintType)
enum class EItemCategory :uint8 {
    Consumable,
    Equipment,
    QuestItem,
    Others,
    Materials
};

2、C++创建Struct ,F开头

USTRUCT(BlueprintType)
struct FInventorySlot {
    GENERATED_BODY()
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AbilityInfo")
    TSubclassOf<class AItemBase>ItemClass; //对应的ItemClass类
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FItemInfo")
    int32 Amount;

    //构造函数,按需拓展
    FInventorySlot();

};

 3、创建UFUNCTION()

参见:https://www.tomlooman.com/ue4-ufunction-keywords-explained/

BlueprintCallable和const连用,成为pure function

BlueprintPure适用于数学函数

BlueprintImplementableEvent和BlueprintCallable连用

BlueprintNativeEvent

    UFUNCTION(BlueprintImplementableEvent)
    bool OnUse(); //据具体实现在蓝图中进行 返回Sucess

 4、一个简单Inventory的数据结构:

    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
    int32 AmountOfSlots;
    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
    int32 MaxStackSize;
    UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
    TArray<FInventorySlot>Slots; //具体用于存储物品类型的数据结构

5、IsSlotEmpty

 bool AInventoryBase::IsSlotEmpty(int32 index)
{    
    //为空返回true
    return !Slots[index].ItemClass;
}

 6、实现类似蓝图GetClassdefaults的功能,存在问题,待解决

FItemInfo AInventoryBase::GetItemInfoAtIndex(int32 index)
{
    AItemBase* Item = Cast<AItemBase>(Slots[index].ItemClass->GetDefaultObject());
    if (Item) { return Item->ItemInfo; }
    else { return FItemInfo(); }
}

经过调试找到原因:ItemClass要加入非空判断

 7、SearchEmptySlot

int32 AInventoryBase::SearchEmptySlot()
{
    for (int index = 0; index < Slots.Num(); index++)
    {
        if (IsSlotEmpty(index))return index;
    }
    return -1;
}

8、SearchFreeStack

int32 AInventoryBase::SearchFreeStack(TSubclassOf<class AItemBase>ItemClass)
{
    for (int index = 0; index < Slots.Num(); index++)
    {
        if (!IsSlotEmpty(index))
        {  //找到且未满
            if ((Slots[index].ItemClass == ItemClass)
                &&Slots[index].Amount<MaxStackSize)
            {
                return index;
            }
        }
    }
    return -1;
}

9、AddItem 

bool AInventoryBase::AddItem(TSubclassOf<class AItemBase> ItemClass, int32 Amount)
{
	AItemBase* ItemToAdd = Cast<AItemBase>(ItemClass->GetDefaultObject());
	if (ItemToAdd==nullptr) { return false; }
	if (ItemToAdd->ItemInfo.CanbeStacked)
	{
		int32 FoundIndex = SearchFreeStack(ItemClass);
		if (FoundIndex != -1)
		{
			//找到且能装,则更新数值即可
			if (Slots[FoundIndex].Amount + Amount <= MaxStackSize) {
				Slots[FoundIndex].Amount = Slots[FoundIndex].Amount + Amount;
				OnSlotChanged(FoundIndex);//蓝图Event
				return true;
			}
			else {
				//找到一个格装不下
				//为了避免递归>2,规定Amount<=MaxStackSize.
				Amount = Slots[FoundIndex].Amount + MaxStackSize - Amount;
				Slots[FoundIndex].Amount = MaxStackSize;
				OnSlotChanged(FoundIndex);//蓝图Event
				return AddItem(ItemClass, Amount);//这里执行物品栏中没有freestack那部分
			}
		}
		else {
			//物品栏中没有freestack
			FoundIndex = SearchEmptySlot();
			if (FoundIndex != -1)
			{
				//由于Amount <= MaxStackSize.更新数值和ItemClass
				Slots[FoundIndex].Amount=Amount;
				Slots[FoundIndex].ItemClass = ItemClass;
				OnSlotChanged(FoundIndex);//蓝图Event
				return true;
			}
			else {
				//已满,需要清理
				return false;
			}

		}
	}
	else {
		//如果物品都是可以堆积的话,类似于魔女之泉,就用不到这里了
		//如果不能堆积,则规定Amount为1
		int32 FoundIndex = SearchEmptySlot();
		if (FoundIndex != -1)
		{
			//由于Amount ==1.更新数值和ItemClass
			Slots[FoundIndex].Amount = Amount;
			Slots[FoundIndex].ItemClass = ItemClass;
			OnSlotChanged(FoundIndex);//蓝图Event
			return true;
		}
		else {
			//已满,需要清理
			return false;
		}
	}
	return false;
}

10、RemoveItemAtIndex

//一般只有UI会调用
bool AInventoryBase::RemoveItemAtIndex(int32 index, int32 Amount)
{
	if (IsSlotEmpty(index)) { return false; }
	if (Amount <= 0) { return false; }
	if (Slots[index].Amount > Amount)
	{
		Slots[index].Amount -= Amount;
		OnSlotChanged(index);//只要改变就调用
		return true;
	}
	else {
		//移除数量大于等于已有数量,则清空
		Slots[index].Amount = 0;
		Slots[index].ItemClass = nullptr;
		OnSlotChanged(index);//只要改变就调用
		return true;
	}
	return false;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值