๐
2025-12-18
์ฐ๋ฃ๋ฅผ ๋ฃ์ผ๋ฉด ๋ถ์ ์ผค ์ ์๋ ๊ฐ๋ก๋ฑ ์กํฐ๋ฅผ ๋ง๋ค์๋ค. ํต์ฌ์ ์๋ฒ์์ ํ์ด๋จธ๋ก ์ฐ๋ฃ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์๋ชจํ๊ณ , ์ฐ๋ฃ๊ฐ ์์ผ๋ฉด ์๋์ผ๋ก ๋ถ์ ๋๋ ๊ตฌ์กฐ๋ค.
void ATSStreetLamp::SetFuelTimer()
{
if (bIsFueling) return;
GetWorldTimerManager().SetTimer(
FuelTimerHandle,
this,
&ATSStreetLamp::UseFuel,
MaintenanceInterval, // ์ด๋น ์๋ชจ ๊ฐ๊ฒฉ
true, // ๋ฐ๋ณต
0.f // ์ฆ์ ์์
);
bIsFueling = true;
}
void ATSStreetLamp::UseFuel()
{
if (LampInventory->GetItemCount(MaintenanceCostID) > 0)
{
// ์ฐ๋ฃ ์๋ชจ & ๋ถ ์ผ๊ธฐ
LampInventory->ConsumeItem(MaintenanceCostID, 1);
ChangeLightScaleByErosion(ErosionSubSystem->GetCurrentErosion());
StartTime = GetWorld()->GetTimeSeconds(); // ๐ ํ์ฌ ์๊ฐ ์ ์ฅ
}
else
{
// ์ฐ๋ฃ ์์ผ๋ฉด ๋ถ ๋๊ธฐ & ํ์ด๋จธ ์ค์ง
SetLightScale(0);
GetWorldTimerManager().ClearTimer(FuelTimerHandle);
bIsFueling = false;
}
OnFuelModeChanged.Broadcast(bIsFueling);
}
ํต์ฌ ํฌ์ธํธ
MaintenanceInterval๋ง๋ค UseFuel() ํธ์ถ๋ก ์ฐ๋ฃ 1๊ฐ์ฉ ์๋ชจClearTimer()๋ก ์ค์งStartTime์ Replicated๋ก ์ ์ฅํด์ ํด๋ผ์ด์ธํธ๋ ๊ฒฝ๊ณผ ์๊ฐ ๊ณ์ฐ ๊ฐ๋ฅํ๊ฒ ํจbIsFueling ์ํ๋ก ํ์ฌ ๊ฐ๋ ์ค์ธ์ง ์ถ์ UI ์
๋ฐ์ดํธ๋ฅผ ์ํด FOnFuelModeChanged ๋ธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ๋ง๋ค์๋ค. ์ฐ๋ฃ ์ํ๊ฐ ๋ฐ๋ ๋๋ง๋ค ๋ธ๋ก๋์บ์คํธํด์ ์์ ฏ์์ ๊ตฌ๋
ํ๋๋ก ํ๋ค.
// .h
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnFuelModeChanged, bool, bIsFueling);
UPROPERTY(BlueprintAssignable, Category = "Lamp|Events")
FOnFuelModeChanged OnFuelModeChanged;
// .cpp
UPROPERTY(ReplicatedUsing = OnRep_IsFueling)
bool bIsFueling = false;
void ATSStreetLamp::OnRep_IsFueling()
{
OnFuelModeChanged.Broadcast(bIsFueling);
}
์์ ฏ ์ธก ๊ตฌํ
OnFuelModeChanged๋ฅผ ๊ตฌ๋
bIsFueling์ด false๋ฉด ํ๋ก๊ทธ๋ ์ค๋ฐ ์
๋ฐ์ดํธ ํ์ด๋จธ pausetrue๋ฉด ํ์ด๋จธ ์ฌ๊ฐํด์ 0.2์ด๋ง๋ค ๋จ์ ์๊ฐ ๊ณ์ฐ์ด๋ ๊ฒ ํ๋ฉด ์กํฐ ๋ก์ง๊ณผ UI ์ ๋ฐ์ดํธ๊ฐ ์์ ํ ๋ถ๋ฆฌ๋๊ณ , ์์ ฏ์ ์ํ ๋ณํ์๋ง ๋ฐ์ํ๋ฉด ๋๋ค.
๋จํ๋ ์ฐ๋ฃ ์์ดํ
๋ง ๋ฐ์ ์ ์์ด์ผ ํ๋ค. UTSLampInventory๋ฅผ ๋ง๋ค์ด์ CanPlaceItemInSlot()์ ์ค๋ฒ๋ผ์ด๋ํ๋ค.
bool UTSLampInventory::CanPlaceItemInSlot(int32 StaticDataID, EInventoryType InventoryType, int32 SlotIndex)
{
if (Super::CanPlaceItemInSlot(StaticDataID, InventoryType, SlotIndex))
{
if (StaticDataID != MaintenanceCostID) // ์ฐ๋ฃ ์์ดํ
๋ง ํ์ฉ
{
return false;
}
}
OnFuelTransferred.Broadcast(); // ์ฐ๋ฃ ์ถ๊ฐ๋จ ์๋ฆผ
return true;
}
void UTSLampInventory::ClearSlot(FSlotStructMaster& Slot)
{
Super::ClearSlot(Slot);
Slot.ItemData.StaticDataID = MaintenanceCostID; // ๋น ์ฌ๋กฏ๋ ์ฐ๋ฃ ID๋ก
Slot.MaxStackSize = MaintenanceCostQty;
}
์ถ๊ฐ ๊ตฌํ
Internal_TransferItem()์์๋ MaintenanceCostID ์ฒดํฌOnFuelTransferred ๋ธ๋ฆฌ๊ฒ์ดํธ ๋ธ๋ก๋์บ์คํธSetFuelTimer() ํธ์ถ// BeginPlay์์ ๋ธ๋ฆฌ๊ฒ์ดํธ ๋ฐ์ธ๋ฉ
LampInventory->OnFuelTransferred.AddDynamic(this, &ATSStreetLamp::SetFuelTimer);
์ด๋ ๊ฒ ํ๋ฉด ํ๋ ์ด์ด๊ฐ ์ฐ๋ฃ๋ฅผ ๋ฃ๋ ์๊ฐ ์๋์ผ๋ก ํ์ด๋จธ๊ฐ ์์๋๋ค.
์๋ฒ์์๋ง ํ์ด๋จธ๊ฐ ๋์ง๋ง, ํด๋ผ์ด์ธํธ๋ ํ๋ก๊ทธ๋ ์ค๋ฐ๋ฅผ ๋ณด์ฌ์ค์ผ ํ๋ค. ์ด๋ฅผ ์ํด StartTime์ Replicated ๋ณ์๋ก ๋ง๋ค์๋ค.
UPROPERTY(Replicated)
float StartTime = 0.f;
// UseFuel()์์ ์ฐ๋ฃ ์๋ชจํ ๋๋ง๋ค ๊ฐฑ์
StartTime = GetWorld()->GetTimeSeconds();
์์ ฏ์์ ๊ณ์ฐ
// ์์ ฏ์ 0.2์ด ํ์ด๋จธ์์
float OperatingTime = CurrentTime - StartTime;
float Progress = 1.0f - (OperatingTime / MaintenanceInterval);
์ด๋ ๊ฒ ํ๋ฉด:
1. ์๋ฒ๊ฐ ์ฐ๋ฃ ์๋ชจํ ๋๋ง๋ค StartTime ์
๋ฐ์ดํธ
2. ํด๋ผ์ด์ธํธ๋ StartTime๊ณผ ํ์ฌ ์๊ฐ ์ฐจ์ด๋ก ๊ฒฝ๊ณผ ์๊ฐ ๊ณ์ฐ
3. MaintenanceInterval๋ก ๋๋ ์ ์งํ๋ฅ ๊ณ์ฐ
์๋ฒ ํ์ด๋จธ ์์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ํ๋ก๊ทธ๋ ์ค๋ฐ ์ ๋ฐ์ดํธ ๊ฐ๋ฅ!
Tick์ ์ฌ์ฉํ์ง ์๊ณ ๋ถํ๋ฅผ ์ค์ด๋ ค๊ณ ๋ ธ๋ ฅํ๋ค. ์ฐ๋ฃ๋ฅผ ์๋นํ๊ฑฐ๋ ๋ถ์ ๋๋ ์์ ๋ง ๋ธ๋ฆฌ๊ฒ์ดํธ๋ก ํ์คํ๊ฒ ๋๊ธฐํํ๊ณ ๋๋จธ์ง๋ ํด๋ผ์ด์ธํธ์์ ์์ธกํ์ฌ ๋จ์ ์ฐ๋ฃ ๊ฐ๋์๊ฐ์ UI์ ๋ํ๋๋ค. ์ด๋๋ Tick๋ณด๋ค๋ ํ์ด๋จธ๋ฅผ ์ฌ์ฉํด ๋จํ๊ฐ ๊ฐ๋๋๋ ์๊ฐ์๋ง ํ์ด๋จธ๋ฅผ ํ์ฑํํ๋ ๋ฐฉ์์ผ๋ก ๋ถํ๋ฅผ ์ค์๋ค.
๊ธฐ์กด์ ์ธ๋ฒคํ ๋ฆฌ๋ฅผ ์ปค์คํ
ํ์ฌ ํน์ ์์ดํ
๋ง ๋ฃ์ ์ ์๊ณ ์ต๋๋ก ๋ฃ์ ์ ์๋ ์ฐ๋ฃ ์์ดํ
์ ์๋ ์ ํํ๋๋ก CanPlaceItemInSlot()๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ๋ค. ๊ธฐ์กด์๋ ์์ดํ
๋ฐ์ดํฐ์์ MaxStack์ ๊ฐ์ ธ์ ์ฌ๋กฏ์ ์ ์ฉํ๋ ๋ฐฉ์์ด์๋๋ฐ ์ด๋ฒ ๋ก์ง์ ๊ตฌํํ๊ธฐ ์ํด ์คํํ ๋ ์ฌ๋กฏ์ MaxStack์ ๊ฐ์ง๊ณ ์ค๋ ๋ฐฉ์์ผ๋ก ์์ ํ๋ค. ๊ธฐ์กด ์ธ๋ฒคํ ๋ฆฌ ์ปดํฌ๋ํธ๋ฅผ ๊ฝค ํ์ฅ์ฑ ๋๊ฒ ๋ง๋ ๊ฒ ๊ฐ์ ๋ฟ๋ฏํ๋ค.