5.3 KiB
5.3 KiB
title, date, excerpt, tags, rating
title | date | excerpt | tags | rating |
---|---|---|---|---|
UE5 Lyra学习笔记(5)—QuickBar与Equipment | 2022-09-16 11:03:03 | ⭐ |
前言
ULyraQuickBarComponent
继承自UControllerComponent(ModularGame的给Controller使用的胶水组件)。
成员变量
//QuickBar Slot中的ItemInstance数据
UPROPERTY(ReplicatedUsing=OnRep_Slots)
TArray<TObjectPtr<ULyraInventoryItemInstance>> Slots;
//当前激活的SlotIndex
UPROPERTY(ReplicatedUsing=OnRep_ActiveSlotIndex)
int32 ActiveSlotIndex = -1;
//当前装备的EquipmentInstance
UPROPERTY()
TObjectPtr<ULyraEquipmentInstance> EquippedItem;
2个OnRep()会使用GameplayMessageRouter发送Message,该Message最后会被UI接收并且进行对应处理。
函数
只说几个相对重要的函数:
- CycleActiveSlotForward:激活正向的下一个QuickBarSlot,判断Index是否有效后调用SetActiveSlotIndex()。
- CycleActiveSlotBackward:激活反向的上一个QuickBarSlot,判断Index是否有效后调用SetActiveSlotIndex()。
- EquipItemInSlot:装备指定的物品,通过
Slot[ActiveSlotIndex]
获取到ItemInstance,ItemInstance通过Fragment获取到EquipmentDefinition后用EquipmentManager调用函数EquipItem()来装备(调用FindEquipmentManager获取)。 - UnequipItemInSlot:脱下指定的物品,EquipmentManager调用UnequipItem(EquippedItem)。
- FindEquipmentManager:
Cast<AController>(GetOwner()))->GetPawn()->FindComponentByClass<ULyraEquipmentManagerComponent>()
- SetActiveSlotIndex_Implementation:含有
Server, Reliable
标记,依次调用UnequipItemInSlot(); ActiveSlotIndex = NewIndex; EquipItemInSlot(); OnRep_ActiveSlotIndex();
- AddItemToSlot:增加QuickBarSlot的ItemInstance数据并调用OnRep_Slots()。
- RemoveItemFromSlot:如果处于装备状态会先调用UnequipItemInSlot(),之后移除QuickBarSlot的ItemInstance数据并调用OnRep_Slots()。
QuickBarUI
- W_QuickBar(组合控件):快捷栏主控件,用于嵌套W_QuickBarSlot。
- W_QuickBarSlot: 1. 通过GameplayMessageRouter读取FLyraQuickBarActiveIndexChangedMessage数据(QuickBar组件的消息),获取Payload拥有者是否与UI拥有者相同,来播放对应的UI动画。 2. 通过GameplayMessageRouter读取FLyraQuickBarSlotsChangedMessage数据(QuickBar组件的消息),获取Payload拥有者以及ItemInstance数据,通过ItemInstance找到到指定的Fragment来获取图标资源来更新UI的图标。
- W_WeaponAmmoAndName:取得角色的QuickBar组件,之后获取ActiveSlot的ItemInstance,获取对应的StatTag来设置显示Text(MagazineAmmo、SpareAmmo),再通过Fragment找到对应的图标资产。
- 其他控件:
- W_ActionTouchButton:通过GameplayMessageRouter读取消息,获得Duration值。
ULyraEquipmentManagerComponent
继承自UPawnComponent。(ModularGame的给Pawn使用的胶水组件)。
成员变量
相关逻辑
- UI
- 获取角色对应组件逻辑:
GetOwningPlayer->GetComponentByClass<ULyraQuickBarComponent>();
- 获取角色对应组件逻辑:
- C++
- Controll组件获取到角色组件方法:
Cast<AController>(GetOwner()))->GetPawn()->FindComponentByClass<ULyraEquipmentManagerComponent>()
- Controll组件获取到角色组件方法:
ItemInstance获取Pawn的方法
void ULyraEquipmentInstance::OnUnequipped()
{
K2_OnUnequipped();
}
APawn* ULyraEquipmentInstance::GetPawn() const
{
return Cast<APawn>(GetOuter());
}
APawn* ULyraEquipmentInstance::GetTypedPawn(TSubclassOf<APawn> PawnType) const
{
APawn* Result = nullptr;
if (UClass* ActualPawnType = PawnType)
{
if (GetOuter()->IsA(ActualPawnType))
{
Result = Cast<APawn>(GetOuter());
}
}
return Result;
}
UI从ItemDefinition获取数据的方式
调用ItemInstance->FindFragmentByClass,再从指定的FragmentClass中获取数据。 QuickBar使用了QuickBarIcon
void ULyraQuickBarComponent::EquipItemInSlot()
{
check(Slots.IsValidIndex(ActiveSlotIndex));
check(EquippedItem == nullptr);
if (ULyraInventoryItemInstance* SlotItem = Slots[ActiveSlotIndex])
{
if (const UInventoryFragment_EquippableItem* EquipInfo = SlotItem->FindFragmentByClass<UInventoryFragment_EquippableItem>())
{
TSubclassOf<ULyraEquipmentDefinition> EquipDef = EquipInfo->EquipmentDefinition;
if (EquipDef != nullptr)
{
if (ULyraEquipmentManagerComponent* EquipmentManager = FindEquipmentManager())
{
EquippedItem = EquipmentManager->EquipItem(EquipDef);
if (EquippedItem != nullptr)
{
EquippedItem->SetInstigator(SlotItem);
}
}
}
}
}
}
QuickBar UI更新机制
Lyra选择 tick来 getSlot
TArray<ULyraInventoryItemInstance*> GetSlots() const
{
return Slots;
}
UPROPERTY(ReplicatedUsing=OnRep_Slots)
TArray<TObjectPtr<ULyraInventoryItemInstance>> Slots;
之后根据Slot进行设置图标数据或者将其设置成null。
PS.所以我打算这么做:ItemUISlot设置成null,之后遍历消除nullslot