09.17 - TIL

김혁·2025년 9월 17일

TIL

목록 보기
20/84

오늘의 코드카타

금과 은 운반하기

  • 최적화 문제 = 결정 문제 + 이분 탐색
  • parametric search
  • LV3 - 17% (복습 필요)
    -> 문제 풀이

오늘의 공부

GAS 공부

1. Gameplay Tag & Gameplay Cue 시스템

  1. AGameplayCueNotify_Actor : 복잡한 연출에서 활용
    • Tag를 통해 GameplayCue가 자동으로 실행되게 함
bool AGameplayCue_Status_Poisoned::OnActive_Implementation(AActor* Target, const FGameplayCueParameters& Parameters) {
	int32 StackCount = 1;
    
    // Tag를 활용해 Gameplay Effect에서 스택 수 받아오기
    UAbilitySystemComponent* ASC = Parameters.EffectContext.GetOriginalInstigatorAbilitySystemComponent();
	if (ASC)
	{
		FGameplayEffectQuery Query = FGameplayEffectQuery::MakeQuery_MatchAnyOwningTags(
			FGameplayTagContainer(FGameplayTag::RequestGameplayTag("Status.Poisoned")));
		TArray<FActiveGameplayEffectHandle> ActiveEffects = ASC->GetActiveEffects(Query);

		if (ActiveEffects.Num() > 0)
		{
			const FActiveGameplayEffect* ActiveGE = ASC->GetActiveGameplayEffect(ActiveEffects[0]);
			if (ActiveGE)
			{
				StackCount = ActiveGE->Spec.GetStackCount();
			}
		}
	}
    
    // 스택 수 별로 다른 사운드 이펙트 설정
	USoundBase* PoisonSound = nullptr;
	float SoundVolume = 1.0f;

	switch (StackCount)
	{
	case 1:
		PoisonSound = LightPoisonSound;
		SoundVolume = 0.3f;
		break;
	case 2:
		PoisonSound = ModeratePoisonSound;
		SoundVolume = 0.5f;
		break;
	case 3:
	case 4:
		PoisonSound = HeavyPoisonSound;
		SoundVolume = 0.7f;
		break;
	case 5:
	default:
		PoisonSound = LethalPoisonSound;
		SoundVolume = 1.0f;
		break;
	}
    
    if (PoisonSound)
    {
        PoisonAudioComponent = UGameplayStatics::SpawnSoundAttached(
            PoisonSound,
            Target->GetRootComponent()
        );

        if (PoisonAudioComponent)
        {
            PoisonAudioComponent->SetVolumeMultiplier(SoundVolume);
        }
    }
    
    ...
}

2. Gameplay Effect에 태그 할당 시 주의사항

UHealCooldownEffect::UHealCooldownEffect()
{
	UTargetTagsGameplayEffectComponent* TargetTags = CreateDefaultSubobject<UTargetTagsGameplayEffectComponent>(TEXT("TargetTagsComp"));
	FInheritedTagContainer TagChanges = TargetTags->GetConfiguredTargetTagChanges();
	TagChanges.Added.AddTag(FGameplayTag::RequestGameplayTag("Cooldown.Heal"));
	TargetTags->SetAndApplyTargetTagChanges(TagChanges);
}
  • 동작 과정
    • 태그를 할당하기 위해 SetAndApplyTargetTagChanges() 호출
    • 실행(Development) 모드에서는 동작이 되나, 디버그 모드에서는 크래시 발생
  • 원인
    • UGameplayEffect는 기본적으로 GameplayEffectComponent(추가적인 기능 컴포넌트)들을 GEComponents 배열로 관리
    • UTargetTagsGameplayEffectComponent가 생성이 되지만, GEComponents에 등록되지 않아서 엔진 내부 로직에서 접근할 때 nullptr 예외가 발생
  • 해결법
    • GEComponents에 직접 GameplayEffectComponent 등록
    • GEComponents.Add(TargetTags);

오늘의 CS

컴퓨터의 물리적 메모리 계층

  • 성능순 : 레지스터 > 캐시 > RAM (주기억장치) > SSD/HDD (보조기억장치)
  • 성능과 용량, 비용은 역순

1. 레지스터

  • CPU 내부에 존재, 가장 빠른 메모리
  • CPU가 연산할 때 사용하는 저장 공간
  • 크기가 매우 작음

2. 캐시 메모리

  • CPU와 RAM 사이에 위치 (속도 차이를 해결하기 위한 기억 장치)
  • 자주 쓰는 데이터를 보관해 CPU가 빠르게 접근할 수 있도록 함
  • 3계층
    • L1 캐시 : CPU 코어 내부에 있고, 각 코어가 독점적으로 사용. 가장 빠름.
    • L2 캐시 : 코어별로 할당되는 경우가 많음. L1보다 크고 느림.
    • L3 캐시 : 모든 코어가 공유하는 캐시. 가장 크고 가장 느림.

3. RAM (주기억 장치)

  • 실행 중인 프로그램과 데이터를 저장하는 휘발성 기억 장치
  • 접근 속도가 하드 디스크보다 빠름
  • CPU가 캐시 미스가 발생하면 RAM에서 데이터를 가져옴

4. SSD / HDD (보조기억 장치)

  • 프로그램, 파일 등을 영구 저장
  • RAM보다 훨씬 느리지만, 훨씬 용량이 크고 저렴함
  • SSD (Solid State Drive)
    • 구조 : 플래시 메모리를 사용 -> 반도체 기반
    • 특징
      • 전자적으로만 동작 -> 기계적 부품 없음
      • 접근 속도 빠름
      • 가격은 비쌈
  • HDD (Hard Disk Drive)
    • 구조 : 자기 디스크가 고속 회전하면서, 기계적 헤드가 데이터를 읽고 씀
    • 특징
      • 기계적 동작 -> 물리적 마모, 충격에 취약
      • 용량 대비 가격이 매우 저렴
      • 속도는 느림
profile
게임 개발자를 향해..

0개의 댓글