Section 10: Outline and Glow Effects - Lecture 192

Assigning the Icon Delegate
This commit is contained in:
charnet3d 2024-01-12 06:59:33 +01:00
parent 70d390a0de
commit b65f8e5540
6 changed files with 82 additions and 13 deletions

Binary file not shown.

BIN
Content/_Game/HUD/InventoryBar.uasset (Stored with Git LFS)

Binary file not shown.

BIN
Content/_Game/HUD/WeaponSlot.uasset (Stored with Git LFS)

Binary file not shown.

View File

@ -519,6 +519,8 @@ void AItem::FinishInterping()
// Subtract 1 from the Item Count of the interp location struct
Character->IncrementInterpLocItemCount(InterpLocIndex, -1);
Character->GetPickupItem(this);
Character->UnhighlightInventorySlot();
}
// Set scale back to normal
SetActorScale3D(FVector(1.f));

View File

@ -74,7 +74,9 @@ AShooterCharacter::AShooterCharacter() :
bShouldPlayPickupSound(true),
bShouldPlayEquipSound(true),
PickupSoundResetTime(0.2f),
EquipSoundResetTime(0.2f)
EquipSoundResetTime(0.2f),
// Icon animation property
HighlightedSlot(-1)
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
@ -416,7 +418,7 @@ void AShooterCharacter::ExchangeInventoryItems(int32 CurrentItemIndex, int32 New
{
if (CurrentItemIndex == NewItemIndex
|| NewItemIndex >= Inventory.Num()
|| CombatState != ECombatState::ECS_Unoccupied)
|| (CombatState != ECombatState::ECS_Unoccupied && CombatState != ECombatState::ECS_Equipping))
return;
auto OldEquippedWeapon = EquippedWeapon;
@ -437,6 +439,41 @@ void AShooterCharacter::ExchangeInventoryItems(int32 CurrentItemIndex, int32 New
NewWeapon->PlayEquipSound(true);
}
int32 AShooterCharacter::GetEmptyInventorySlot()
{
for (int32 i = 0; i < Inventory.Num(); ++i)
{
if (Inventory[i] == nullptr)
return i;
}
if (Inventory.Num() < INVENTORY_CAPACITY)
{
return Inventory.Num();
}
return -1; // Inventory full
}
void AShooterCharacter::HighlightInventorySlot()
{
const int32 EmptySlot{ GetEmptyInventorySlot() };
if (EmptySlot != -1)
{
HighlightIconDelegate.Broadcast(EmptySlot, true);
HighlightedSlot = EmptySlot;
}
}
void AShooterCharacter::UnhighlightInventorySlot()
{
if (HighlightedSlot != -1)
{
HighlightIconDelegate.Broadcast(HighlightedSlot, false);
HighlightedSlot = -1;
}
}
int32 AShooterCharacter::GetInterpLocationIndex()
{
int32 LowestIndex = 1;
@ -766,14 +803,19 @@ void AShooterCharacter::TraceForItems()
{
// If an item was being looked at from last frame, we should hide its widget
if (OldTraceHitItem != TraceHitItem)
{
UnhighlightInventorySlot();
SetItemPickupWidgetVisibility(OldTraceHitItem, false);
// Show the new item's widget
OldTraceHitItem = TraceHitItem;
}
if (TraceHitItem && TraceHitItem->GetItemState() == EItemState::EIS_EquipInterping)
TraceHitItem = nullptr;
const auto TraceHitWeapon = Cast<AWeapon>(TraceHitItem);
if (TraceHitWeapon && HighlightedSlot == -1)
HighlightInventorySlot();
// Show the new item's widget
SetItemPickupWidgetVisibility(TraceHitItem, true);
if (Inventory.Num() >= INVENTORY_CAPACITY)
@ -785,15 +827,21 @@ void AShooterCharacter::TraceForItems()
{
TraceHitItem->SetCharacterInventoryFull(false);
}
OldTraceHitItem = TraceHitItem;
}
else if (OldTraceHitItem) // Hide widget for the item from last frame
{
UnhighlightInventorySlot();
SetItemPickupWidgetVisibility(OldTraceHitItem, false);
OldTraceHitItem = nullptr;
}
}
else if (TraceHitItem) // Hide widget for the item from last frame
{
UnhighlightInventorySlot();
SetItemPickupWidgetVisibility(TraceHitItem, false);
TraceHitItem = nullptr;
}
@ -822,7 +870,7 @@ AWeapon* AShooterCharacter::SpawnDefaultWeapon()
return nullptr;
}
void AShooterCharacter::EquipWeapon(AWeapon* WeaponToEquip)
void AShooterCharacter::EquipWeapon(AWeapon* WeaponToEquip, bool bSwapping)
{
// Get the hand socket
const USkeletalMeshSocket* HandSocket = GetMesh()->GetSocketByName(FName("RightHandSocket"));
@ -837,7 +885,7 @@ void AShooterCharacter::EquipWeapon(AWeapon* WeaponToEquip)
// -1 == no EquippedWeapon yet. No need to reverse the icon animation
EquipItemDelegate.Broadcast(-1, WeaponToEquip->GetSlotIndex());
}
else
else if (!bSwapping)
{
EquipItemDelegate.Broadcast(EquippedWeapon->GetSlotIndex(), WeaponToEquip->GetSlotIndex());
}
@ -886,7 +934,7 @@ void AShooterCharacter::SwapWeapon(AWeapon* WeaponToSwap)
}
DropWeapon();
EquipWeapon(WeaponToSwap);
EquipWeapon(WeaponToSwap, true);
}
void AShooterCharacter::InitializeAmmoMap()

View File

@ -45,6 +45,8 @@ struct FInterpLocation
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FEquipItemDelegate, int32, CurrentSlotIndex, int32, NewSlotIndex);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FHighlightIconDelegate, int32, SlotIndex, bool, bStartAnimation);
UCLASS()
class SHOOTER_API AShooterCharacter : public ACharacter
@ -140,7 +142,7 @@ protected:
AWeapon* SpawnDefaultWeapon();
/* Takes a weapon and attaches it to the mesh */
void EquipWeapon(AWeapon* WeaponToEquip);
void EquipWeapon(AWeapon* WeaponToEquip, bool bSwapping = false);
/** Detach weapon and let it fall to the ground */
void DropWeapon();
@ -210,6 +212,10 @@ protected:
void ExchangeInventoryItems(int32 CurrentItemIndex, int32 NewItemIndex);
int32 GetEmptyInventorySlot();
void HighlightInventorySlot();
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = true))
USpringArmComponent* CameraBoom;
@ -477,6 +483,14 @@ private:
UPROPERTY(BlueprintAssignable, Category = Delegates, meta = (AllowPrivateAccess = true))
FEquipItemDelegate EquipItemDelegate;
/** Delegate for sending slot information for playing the icon animation */
UPROPERTY(BlueprintAssignable, Category = Delegates, meta = (AllowPrivateAccess = true))
FHighlightIconDelegate HighlightIconDelegate;
/** The index for the currently highlighted slot */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Inventory, meta = (AllowPrivateAccess = true))
int32 HighlightedSlot;
public:
/* Returns CameraBoom SubObject */
FORCEINLINE USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
@ -515,4 +529,6 @@ public:
void StartPickupSoundTimer();
void StartEquipSoundTimer();
void UnhighlightInventorySlot();
};