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