언리얼 엔진5 GameAbilitySystem-AbilitySystem.h 번역본

조창근·2024년 6월 15일
0

언리얼엔진5 GAS

목록 보기
1/8

5.32버전의 AbilitySystem.h에 대한 번역본입니다

코드를// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Templates/SubclassOf.h"
#include "Engine/NetSerialization.h"
#include "Engine/EngineTypes.h"
#include "Engine/TimerHandle.h"
#include "GameplayTagContainer.h"
#include "AttributeSet.h"
#include "EngineDefines.h"
#include "GameplayPrediction.h"
#include "GameplayCueInterface.h"
#include "GameplayTagAssetInterface.h"
#include "GameplayAbilitySpec.h"
#include "GameplayEffect.h"
#include "GameplayTasksComponent.h"
#include "Abilities/GameplayAbilityRepAnimMontage.h"
#include "Abilities/GameplayAbilityTargetTypes.h"
#include "Abilities/GameplayAbility.h"
#include "AbilitySystemReplicationProxyInterface.h"
#include "Net/Core/PushModel/PushModel.h"

#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_2
#include "Abilities/GameplayAbilityTypes.h"
#include "GameplayEffectTypes.h"
#endif

#include "AbilitySystemComponent.generated.h"

class AGameplayAbilityTargetActor;
class AHUD;
class FDebugDisplayInfo;
class UAnimMontage;
class UCanvas;
class UInputComponent;

/** 
 *	UAbilitySystemComponent	
 *
 *	A component to easily interface with the 3 aspects of the AbilitySystem:
 *	
 *	GameplayAbilities:
 *		-Provides a way to give/assign abilities that can be used (by a player or AI for example)
 *		-Provides management of instanced abilities (something must hold onto them)
 *		-Provides replication functionality
 *			-Ability state must always be replicated on the UGameplayAbility itself, but UAbilitySystemComponent provides RPC replication
 *			for the actual activation of abilities
 *			
 *	GameplayEffects:
 *		-Provides an FActiveGameplayEffectsContainer for holding active GameplayEffects
 *		-Provides methods for applying GameplayEffects to a target or to self
 *		-Provides wrappers for querying information in FActiveGameplayEffectsContainers (duration, magnitude, etc)
 *		-Provides methods for clearing/remove GameplayEffects
 *		
 *	GameplayAttributes
 *		-Provides methods for allocating and initializing attribute sets
 *		-Provides methods for getting AttributeSets
 *  
 */
 /**
  *	UAbilitySystemComponent
  *
  *	AbilitySystem의 세 가지 측면과 쉽게 상호작용할 수 있는 컴포넌트:
  *
  *	GameplayAbilities (게임플레이 능력):
  *		- 능력을 제공/할당할 수 있는 방법을 제공 (예: 플레이어나 AI가 사용 가능)
  *		- 인스턴스화된 능력의 관리를 제공 (어딘가에 보관되어야 함)
  *		- 복제 기능을 제공
  *			- 능력 상태는 항상 UGameplayAbility 자체에서 복제되어야 하지만, UAbilitySystemComponent는 실제 능력 활성화에 대한 RPC 복제를 제공
  *
  *	GameplayEffects (게임플레이 효과):
  *		- 활성화된 GameplayEffects를 보관하는 FActiveGameplayEffectsContainer를 제공
  *		- 목표 또는 자기 자신에게 GameplayEffects를 적용하는 메서드를 제공
  *		- FActiveGameplayEffectsContainers의 정보(지속 시간, 강도 등)를 쿼리하는 래퍼를 제공
  *		- GameplayEffects를 제거/정리하는 메서드를 제공
  *
  *	GameplayAttributes (게임플레이 속성):
  *		- 속성 세트를 할당하고 초기화하는 메서드를 제공
  *		- AttributeSets를 가져오는 메서드를 제공
  */

/** Called when a targeting actor rejects target confirmation */
/** 타겟팅 액터가 타겟 확인을 거부할 때 호출됩니다 */
DECLARE_MULTICAST_DELEGATE_OneParam(FTargetingRejectedConfirmation, int32);

/** Called when ability fails to activate, passes along the failed ability and a tag explaining why */
/** 능력이 활성화되지 못할 때 호출되며, 실패한 능력과 실패 이유를 설명하는 태그를 전달합니다 */
DECLARE_MULTICAST_DELEGATE_TwoParams(FAbilityFailedDelegate, const UGameplayAbility*, const FGameplayTagContainer&);

/** Called when ability ends */
/** 능력이 종료될 때 호출됩니다 */
DECLARE_MULTICAST_DELEGATE_OneParam(FAbilityEnded, UGameplayAbility*);

/** Notify interested parties that ability spec has been modified */
/** 능력 사양이 수정되었음을 관심 있는 파티에 알립니다 */
DECLARE_MULTICAST_DELEGATE_OneParam(FAbilitySpecDirtied, const FGameplayAbilitySpec&);

/** Notifies when GameplayEffectSpec is blocked by an ActiveGameplayEffect due to immunity /*
/**immunity(멀까?)로 인해 활성화된 GameplayEffect가 GameplayEffectSpec을 차단할 때 알립니다 */
DECLARE_MULTICAST_DELEGATE_TwoParams(FImmunityBlockGE, const FGameplayEffectSpec& /*BlockedSpec*/, const FActiveGameplayEffect* /*ImmunityGameplayEffect*/);

/** We allow a list of delegates to decide if the application of a Gameplay Effect can be blocked. If it's blocked, it will call the ImmunityBlockGE above */
/** 여러 대리자가 GameplayEffect의 적용을 차단할 수 있는지 결정하도록 허용합니다. 차단되면 위의 ImmunityBlockGE가 호출됩니다 */
DECLARE_DELEGATE_RetVal_TwoParams(bool, FGameplayEffectApplicationQuery, const FActiveGameplayEffectsContainer& /*ActiveGEContainer*/, const FGameplayEffectSpec& /*GESpecToConsider*/);

/** How gameplay effects will be replicated to clients 게임플레이 효과가 클라이언트에 어떻게 복제될지*/
UENUM()
enum class EGameplayEffectReplicationMode : uint8
{
	/** Only replicate minimal gameplay effect info. Note: this does not work for Owned AbilitySystemComponents (Use Mixed instead).
	/** 최소한의 게임플레이 효과 정보만 복제합니다. 참고: 이것은 소유된 AbilitySystemComponents에서는 작동하지 않습니다 (Mixed를 대신 사용하세요). */*/
	Minimal,
	/** Only replicate minimal gameplay effect info to simulated proxies but full info to owners and autonomous proxies */
	/** 시뮬레이션된 프록시에는 최소한의 게임플레이 효과 정보만 복제하고, 소유자와 자율 프록시에는 전체 정보를 복제합니다. */
	Mixed,
	/** Replicate full gameplay info to all */
	/** 모든 대상에게 전체 게임플레이 정보를 복제합니다. */
	Full,
};

/** The core ActorComponent for interfacing with the GameplayAbilities System */
UCLASS(ClassGroup=AbilitySystem, hidecategories=(Object,LOD,Lighting,Transform,Sockets,TextureStreaming), editinlinenew, meta=(BlueprintSpawnableComponent))
class GAMEPLAYABILITIES_API UAbilitySystemComponent : public UGameplayTasksComponent, public IGameplayTagAssetInterface, public IAbilitySystemReplicationProxyInterface
{
	GENERATED_UCLASS_BODY()

	/** Used to register callbacks to ability-key input */
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityAbilityKey, /*UGameplayAbility*, Ability, */int32, InputID);

	/** Used to register callbacks to confirm/cancel input */
	DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAbilityConfirmOrCancel);

	/** Delegate for when an effect is applied */
	DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnGameplayEffectAppliedDelegate, UAbilitySystemComponent*, const FGameplayEffectSpec&, FActiveGameplayEffectHandle);

	// ----------------------------------------------------------------------------------------------------------------
	//	Attributes
	// ----------------------------------------------------------------------------------------------------------------

	/** Finds existing AttributeSet /** 기존 AttributeSet을 찾음 */
	template <class T >
	const T*	GetSet() const
	{
		return (T*)GetAttributeSubobject(T::StaticClass());
	}

	/** Finds existing AttributeSet. Asserts if it isn't there. */	
	/** 기존 AttributeSet을 찾음. 없을 경우 오류 발생 */
	template <class T >
	const T*	GetSetChecked() const
	{
		return (T*)GetAttributeSubobjectChecked(T::StaticClass());
	}

	/** Adds a new AttributeSet (initialized to default values) */
	/** 새로운 AttributeSet을 추가함 (기본값으로 초기화됨) */
	template <class T >
	const T*  AddSet()
	{
		return (T*)GetOrCreateAttributeSubobject(T::StaticClass());
	}

	/** 
	 * Manually add a new attribute set that is a subobject of this ability system component.
	 * All subobjects of this component are automatically added during initialization.
	 *//** 
	 * 이 능력 시스템 컴포넌트의 하위 객체인 새 속성 집합을 수동으로 추가합니다.
	 * 이 컴포넌트의 모든 하위 객체는 초기화 중에 자동으로 추가됩니다.
	 */
	template <class T>
	const T* AddAttributeSetSubobject(T* Subobject)
	{
		AddSpawnedAttribute(Subobject);
		return Subobject;
	}

	/**
	 * Does this ability system component have this attribute?
	 * 이 능력 시스템 컴포넌트에 해당 속성이 있는지 확인합니다.
	 * @param Attribute	Handle of the gameplay effect to retrieve target tags from
	 * @param Attribute	대상 태그를 검색할 게임플레이 효과의 핸들
	 * @return true if Attribute is valid and this ability system component contains an attribute set that contains Attribute. Returns false otherwise.
	 *@return 속성이 유효하고 이 능력 시스템 컴포넌트에 해당 속성을 포함하는 속성 집합이 있으면 true를 반환합니다. 그렇지 않으면 false를 반환합니다.
	 /
	bool HasAttributeSetForAttribute(FGameplayAttribute Attribute) const;

	/** Initializes starting attributes from a data table. Not well supported, a gameplay effect with curve table references may be a better solution */
	const UAttributeSet* InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable);

	UFUNCTION(BlueprintCallable, Category="Skills", meta=(DisplayName="InitStats", ScriptName="InitStats"))
	void K2_InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable);
		
	/** Returns a list of all attributes for this abilty system component */
	/** 이 능력 시스템 컴포넌트의 모든 속성 목록을 반환합니다. */
	UFUNCTION(BlueprintPure, Category="Gameplay Attributes")
	void GetAllAttributes(TArray<FGameplayAttribute>& OutAttributes);

	/**
	 * Returns a reference to the Attribute Set instance, if one exists in this component
	 *이 컴포넌트에 속성 집합 인스턴스가 존재하면 참조를 반환합니다.
	 * @param AttributeSetClass The type of attribute set to look for
	 * @param AttributeSetClass 검색할 속성 집합의 유형
	 * @param bFound Set to true if an instance of the Attribute Set exists
* 	   @param bFound 속성 집합 인스턴스가 존재하면 true로 설정
	 */
	UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Gameplay Attributes")
	const UAttributeSet* GetAttributeSet(TSubclassOf<UAttributeSet> AttributeSetClass) const;

	/**
	 * Returns the current value of the given gameplay attribute, or zero if the attribute is not found.
	 * NOTE: This doesn't take predicted gameplay effect modifiers into consideration, so the value may not be accurate on clients at all times.
	 * 주어진 게임플레이 속성의 현재 값을 반환하거나 속성을 찾지 못하면 0을 반환합니다.
	 * 참고: 이는 예측된 게임플레이 효과 수정자를 고려하지 않으므로, 클라이언트에서는 값이 항상 정확하지 않을 수 있습니다.
	 * @param Attribute The gameplay attribute to query
	 * @param bFound Set to true if the attribute exists in this component
	 * @param Attribute 조회할 게임플레이 속성
	 * @param bFound 속성이 이 컴포넌트에 존재하면 true로 설정
	 * 
	 */
	UFUNCTION(BlueprintPure, Category = "Gameplay Attributes")
	float GetGameplayAttributeValue(FGameplayAttribute Attribute, bool& bFound) const;

	UPROPERTY(EditAnywhere, Category="AttributeTest")
	TArray<FAttributeDefaults>	DefaultStartingData;

	/** Remove all current AttributeSets and register the ones in the passed array. Note that it's better to call Add/Remove directly when possible. */
	/** 현재 AttributeSet을 모두 제거하고 전달된 배열에 있는 AttributeSet을 등록합니다. 가능할 때는 Add/Remove를 직접 호출하는 것이 좋습니다. */
	void SetSpawnedAttributes(const TArray<UAttributeSet*>& NewAttributeSet);

	UE_DEPRECATED(5.1, "This function will be made private. Use Add/Remove SpawnedAttributes instead")
	/**"이 함수는 private로 변경됩니다. SpawnedAttributes의 Add/Remove를 사용하세요."*/
	TArray<TObjectPtr<UAttributeSet>>& GetSpawnedAttributes_Mutable();

	/** Access the spawned attributes list when you don't intend to modify the list. */
	/** 리스트를 수정할 의도가 없는 경우 생성된 속성 목록에 접근합니다. */
	const TArray<UAttributeSet*>& GetSpawnedAttributes() const;

	/** Add a new attribute set */
	/** 새로운 속성 집합을 추가합니다. */
	void AddSpawnedAttribute(UAttributeSet* Attribute);

	/** Remove an existing attribute set */
	/** 기존 속성 집합을 제거합니다. */
	void RemoveSpawnedAttribute(UAttributeSet* Attribute);

	/** Remove all attribute sets */
	/** 모든 속성 집합을 제거합니다. */
	void RemoveAllSpawnedAttributes();


	/** The linked Anim Instance that this component will play montages in. Use NAME_None for the main anim instance. */
/** 이 컴포넌트가 몽타주를 재생할 연결된 애니메이션 인스턴스. 기본 애니메이션 인스턴스를 사용하려면 NAME_None을 사용하십시오. */
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Skills")
	FName AffectedAnimInstanceTag; 


	/** Sets the base value of an attribute. Existing active modifiers are NOT cleared and will act upon the new base value. */
	/** 속성의 기본값을 설정합니다. 기존 활성 수정자는 삭제되지 않으며 새 기본값에 적용됩니다. */
	void SetNumericAttributeBase(const FGameplayAttribute &Attribute, float NewBaseValue);

	/** Gets the base value of an attribute. That is, the value of the attribute with no stateful modifiers */
	/** 속성의 기본값을 가져옵니다. 즉, 상태 수정자가 없는 속성의 값입니다. */
	float GetNumericAttributeBase(const FGameplayAttribute &Attribute) const;

	/**
	 *	Applies an in-place mod to the given attribute. This correctly update the attribute's aggregator, updates the attribute set property,
	 *	and invokes the OnDirty callbacks.
	 *	This does not invoke Pre/PostGameplayEffectExecute calls on the attribute set. This does no tag checking, application requirements, immunity, etc.
	 *	No GameplayEffectSpec is created or is applied!
	 *	This should only be used in cases where applying a real GameplayEffectSpec is too slow or not possible.
	 */
	 /**
  *	주어진 속성에 대해 제자리 수정을 적용합니다. 이는 속성의 집합체를 올바르게 업데이트하고, 속성 집합 속성을 업데이트하며,
  *	OnDirty 콜백을 호출합니다.
  *	이는 속성 집합에서 Pre/PostGameplayEffectExecute 호출을 호출하지 않습니다. 태그 확인, 적용 요구 사항, 면역 등을 수행하지 않습니다.
  *	아무런 GameplayEffectSpec도 생성되거나 적용되지 않습니다!
  *	이 함수는 실제 GameplayEffectSpec을 적용하는 것이 너무 느리거나 불가능한 경우에만 사용해야 합니다.
  */
	void ApplyModToAttribute(const FGameplayAttribute &Attribute, TEnumAsByte<EGameplayModOp::Type> ModifierOp, float ModifierMagnitude);

	/**
	 *  Applies an inplace mod to the given attribute. Unlike ApplyModToAttribute this function will run on the client or server.
	 *  This may result in problems related to prediction and will not roll back properly.
	 */
	 /**
	*  주어진 속성에 대해 제자리 수정을 적용합니다. ApplyModToAttribute와 달리 이 함수는 클라이언트 또는 서버에서 실행됩니다.
	*  이는 예측과 관련된 문제를 일으킬 수 있으며 제대로 롤백되지 않을 수 있습니다.
	*/
	void ApplyModToAttributeUnsafe(const FGameplayAttribute &Attribute, TEnumAsByte<EGameplayModOp::Type> ModifierOp, float ModifierMagnitude);

	/** Returns current (final) value of an attribute */
	/** 속성의 현재 (최종) 값을 반환합니다. */
	float GetNumericAttribute(const FGameplayAttribute &Attribute) const;
	float GetNumericAttributeChecked(const FGameplayAttribute &Attribute) const;

	/** Returns an attribute value, after applying tag filters */
	/** 태그 필터를 적용한 후 속성 값을 반환합니다. */
	float GetFilteredAttributeValue(const FGameplayAttribute& Attribute, const FGameplayTagRequirements& SourceTags, const FGameplayTagContainer& TargetTags, const TArray<FActiveGameplayEffectHandle>& HandlesToIgnore = TArray<FActiveGameplayEffectHandle>());

	// ----------------------------------------------------------------------------------------------------------------
	//	Replication
	// ----------------------------------------------------------------------------------------------------------------

	/** Forces avatar actor to update it's replication. Useful for things like needing to replication for movement / locations reasons. */
	/** 아바타 액터가 복제를 업데이트하도록 강제합니다. 주로 이동/위치와 관련된 이유로 복제가 필요한 경우에 유용합니다. */
	virtual void ForceAvatarReplication();

	/** When true, we will not replicate active gameplay effects for this ability system component, so attributes and tags */
	/** true일 경우, 이 능력 시스템 컴포넌트에 대해 활성화된 게임플레이 효과를 복제하지 않습니다. 따라서 속성과 태그도 복제하지 않습니다. */
	virtual void SetReplicationMode(EGameplayEffectReplicationMode NewReplicationMode);

	/** How gameplay effects are replicated */
	/** 게임플레이 효과가 어떻게 복제되는지 설정합니다. */
	EGameplayEffectReplicationMode ReplicationMode;

	/** Who to route replication through if ReplicationProxyEnabled (if this returns null, when ReplicationProxyEnabled, we wont replicate)  */
	/** 복제 프록시가 활성화된 경우 누구를 통해 복제를 라우팅할지 설정합니다 (null을 반환하면 복제 프록시가 활성화된 경우에도 복제하지 않습니다) */
	virtual IAbilitySystemReplicationProxyInterface* GetReplicationInterface();

	/** Current prediction key, set with FScopedPredictionWindow */
	/** 현재 예측 키, FScopedPredictionWindow로 설정됨 */
	FPredictionKey	ScopedPredictionKey;

	/** Returns the prediction key that should be used for any actions */
	/** 새 작업에 사용할 예측 키를 반환합니다 */
	FPredictionKey GetPredictionKeyForNewAction() const
	{
		return ScopedPredictionKey.IsValidForMorePrediction() ? ScopedPredictionKey : FPredictionKey();
	}

	/** Do we have a valid prediction key to do more predictive actions with */
	/** 더 많은 예측 작업을 수행하기 위한 유효한 예측 키가 있는지 확인합니다 */
	bool CanPredict() const
	{
		return ScopedPredictionKey.IsValidForMorePrediction();
	}

	/** Returns true if this is running on the server or has a valid prediciton key */
	/** 서버에서 실행 중이거나 유효한 예측 키가 있는 경우 true를 반환합니다 */
	bool HasAuthorityOrPredictionKey(const FGameplayAbilityActivationInfo* ActivationInfo) const;

	/** Returns true if this component's actor has authority */
	/** 이 컴포넌트의 액터가 권한을 가지고 있는지 확인합니다 */
	virtual bool IsOwnerActorAuthoritative() const;

	/** Returns true if this component should record montage replication info. */
	/** 이 컴포넌트가 몽타주 복제 정보를 기록해야 하는지 확인합니다 */
	virtual bool ShouldRecordMontageReplication() const;

	/** Replicate that an ability has ended/canceled, to the client or server as appropriate */
	/** 능력이 종료되거나 취소되었음을 클라이언트 또는 서버에 적절하게 복제합니다 */
	virtual void ReplicateEndOrCancelAbility(FGameplayAbilitySpecHandle Handle, FGameplayAbilityActivationInfo ActivationInfo, UGameplayAbility* Ability, bool bWasCanceled);

	/** Force cancels the ability and does not replicate this to the other side. This should be called when the ability is cancelled by the other side */
	/** 능력을 강제로 취소하고 이를 다른 쪽으로 복제하지 않습니다. 이 함수는 능력이 다른 쪽에서 취소되었을 때 호출되어야 합니다 */
	virtual void ForceCancelAbilityDueToReplication(UGameplayAbility* Instance);

	/** A pending activation that cannot be activated yet, will be rechecked at a later point */
	/** 아직 활성화할 수 없는 대기 중인 활성화로, 나중에 다시 확인됩니다 */
	struct FPendingAbilityInfo
	{
		bool operator==(const FPendingAbilityInfo& Other) const
		{
			// Don't compare event data, not valid to have multiple activations in flight with same key and handle but different event data
			// 이벤트 데이터를 비교하지 않습니다. 동일한 키와 핸들로 여러 활성화가 발생했지만 다른 이벤트 데이터가 있는 경우 유효하지 않습니다
			return PredictionKey == Other.PredictionKey	&& Handle == Other.Handle;
		}

		/** Properties of the ability that needs to be activated */
		/** 활성화할 필요가 있는 능력의 속성 */
		FGameplayAbilitySpecHandle Handle;
		FPredictionKey	PredictionKey;
		FGameplayEventData TriggerEventData;

		/** True if this ability was activated remotely and needs to follow up, false if the ability hasn't been activated at all yet */
		/** 원격으로 활성화되었고 후속 작업이 필요한 경우 true, 아직 전혀 활성화되지 않은 경우 false */
		bool bPartiallyActivated;

		FPendingAbilityInfo()
			: bPartiallyActivated(false)
		{}
	};

	/** This is a list of GameplayAbilities that were activated on the server and can't yet execute on the client. It will try to execute these at a later point */
	/** 서버에서 활성화되었지만 클라이언트에서 아직 실행할 수 없는 GameplayAbilities 목록입니다. 나중에 이러한 능력을 실행하려고 시도합니다 */
	TArray<FPendingAbilityInfo> PendingServerActivatedAbilities;

	// ----------------------------------------------------------------------------------------------------------------
	//	GameplayEffects: Primary outward facing API for other systems
	//  게임플레이 효과: 다른 시스템을 위한 주요 외부 API
	// ----------------------------------------------------------------------------------------------------------------

	/** Applies a previously created gameplay effect spec to a target */
	/** 이전에 생성된 게임플레이 효과 사양을 대상에 적용합니다 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects, meta = (DisplayName = "ApplyGameplayEffectSpecToTarget", ScriptName = "ApplyGameplayEffectSpecToTarget"))
	FActiveGameplayEffectHandle BP_ApplyGameplayEffectSpecToTarget(const FGameplayEffectSpecHandle& SpecHandle, UAbilitySystemComponent* Target);

	virtual FActiveGameplayEffectHandle ApplyGameplayEffectSpecToTarget(const FGameplayEffectSpec& GameplayEffect, UAbilitySystemComponent *Target, FPredictionKey PredictionKey=FPredictionKey());

	/** Applies a previously created gameplay effect spec to this component */
	/** 이전에 생성된 게임플레이 효과 사양을 이 컴포넌트에 적용합니다 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects, meta = (DisplayName = "ApplyGameplayEffectSpecToSelf", ScriptName = "ApplyGameplayEffectSpecToSelf"))
	FActiveGameplayEffectHandle BP_ApplyGameplayEffectSpecToSelf(const FGameplayEffectSpecHandle& SpecHandle);

	virtual FActiveGameplayEffectHandle ApplyGameplayEffectSpecToSelf(const FGameplayEffectSpec& GameplayEffect, FPredictionKey PredictionKey = FPredictionKey());

	/** Gets the FActiveGameplayEffect based on the passed in Handle */
	/** 전달된 핸들을 기반으로 FActiveGameplayEffect를 가져옵니다 */
	const UGameplayEffect* GetGameplayEffectDefForHandle(FActiveGameplayEffectHandle Handle);

	/** Removes GameplayEffect by Handle. StacksToRemove=-1 will remove all stacks. */
	/** Handle을 사용하여 GameplayEffect를 제거합니다. StacksToRemove=-1은 모든 스택을 제거합니다. */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = GameplayEffects)
	virtual bool RemoveActiveGameplayEffect(FActiveGameplayEffectHandle Handle, int32 StacksToRemove=-1);

	/** 
	 * Remove active gameplay effects whose backing definition are the specified gameplay effect class
	 * 
	 * @param GameplayEffect					Class of gameplay effect to remove; Does nothing if left null
	 * @param InstigatorAbilitySystemComponent	If specified, will only remove gameplay effects applied from this instigator ability system component
	 * @param StacksToRemove					Number of stacks to remove, -1 means remove all
	 */
	 /**
  * 지정된 게임플레이 효과 클래스의 백업 정의를 가진 활성 게임플레이 효과를 제거합니다.
  *
  * @param GameplayEffect                    제거할 게임플레이 효과 클래스; null로 남겨두면 아무 작업도 하지 않습니다.
  * @param InstigatorAbilitySystemComponent  지정된 경우, 이 시전자 능력 시스템 컴포넌트에서 적용된 게임플레이 효과만 제거합니다.
  * @param StacksToRemove                    제거할 스택 수, -1은 모두 제거합니다.
  */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = GameplayEffects)
	virtual void RemoveActiveGameplayEffectBySourceEffect(TSubclassOf<UGameplayEffect> GameplayEffect, UAbilitySystemComponent* InstigatorAbilitySystemComponent, int32 StacksToRemove = -1);

	/** Get an outgoing GameplayEffectSpec that is ready to be applied to other things. */
	/** 다른 대상에 적용할 준비가 된 게임플레이 효과 사양을 생성합니다. */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	virtual FGameplayEffectSpecHandle MakeOutgoingSpec(TSubclassOf<UGameplayEffect> GameplayEffectClass, float Level, FGameplayEffectContextHandle Context) const;

	/** Create an EffectContext for the owner of this AbilitySystemComponent */
	/** 이 AbilitySystemComponent 소유자를 위한 EffectContext를 생성합니다. */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	virtual FGameplayEffectContextHandle MakeEffectContext() const;

	/**
	 * Get the count of the specified source effect on the ability system component. For non-stacking effects, this is the sum of all active instances.
	 * For stacking effects, this is the sum of all valid stack counts. If an instigator is specified, only effects from that instigator are counted.
	 * 
	 * @param SourceGameplayEffect					Effect to get the count of
	 * @param OptionalInstigatorFilterComponent		If specified, only count effects applied by this ability system component
	 * 
	 * @return Count of the specified source effect
	 */
	 /**
  * 능력 시스템 컴포넌트에서 지정된 소스 효과의 개수를 가져옵니다. 스택되지 않는 효과의 경우, 이는 모든 활성 인스턴스의 합계입니다.
  * 스택되는 효과의 경우, 이는 모든 유효한 스택 수의 합계입니다. 시전자가 지정된 경우, 해당 시전자에서만 적용된 효과를 계산합니다.
  *
  * @param SourceGameplayEffect              개수를 가져올 효과
  * @param OptionalInstigatorFilterComponent 지정된 경우, 이 능력 시스템 컴포넌트에서 적용된 효과만 계산합니다.
  *
  * @return 지정된 소스 효과의 개수
  */
	UFUNCTION(BlueprintCallable, BlueprintPure, Category=GameplayEffects)
	int32 GetGameplayEffectCount(TSubclassOf<UGameplayEffect> SourceGameplayEffect, UAbilitySystemComponent* OptionalInstigatorFilterComponent, bool bEnforceOnGoingCheck = true) const;

	/**
	 * Get the count of the specified source effect on the ability system component. For non-stacking effects, this is the sum of all active instances.
	 * For stacking effects, this is the sum of all valid stack counts. If an instigator is specified, only effects from that instigator are counted.
	 * 
	 * @param SoftSourceGameplayEffect				Effect to get the count of. If this is not currently loaded, the count is 0
	 * @param OptionalInstigatorFilterComponent		If specified, only count effects applied by this ability system component
	 * 
	 * @return Count of the specified source effect
	 */
	 /**
  * 능력 시스템 컴포넌트에서 지정된 소스 효과의 개수를 가져옵니다. 스택되지 않는 효과의 경우, 이는 모든 활성 인스턴스의 합계입니다.
  * 스택되는 효과의 경우, 이는 모든 유효한 스택 수의 합계입니다. 시전자가 지정된 경우, 해당 시전자에서만 적용된 효과를 계산합니다.
  *
  * @param SoftSourceGameplayEffect          개수를 가져올 효과. 현재 로드되지 않은 경우, 개수는 0입니다.
  * @param OptionalInstigatorFilterComponent 지정된 경우, 이 능력 시스템 컴포넌트에서 적용된 효과만 계산합니다.
  *
  * @return 지정된 소스 효과의 개수
  */
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = GameplayEffects)
	int32 GetGameplayEffectCount_IfLoaded(TSoftClassPtr<UGameplayEffect> SoftSourceGameplayEffect, UAbilitySystemComponent* OptionalInstigatorFilterComponent, bool bEnforceOnGoingCheck = true) const;

	/** Returns the sum of StackCount of all gameplay effects that pass query */
	/** 쿼리를 통과하는 모든 게임플레이 효과의 StackCount 합계를 반환합니다. */
	int32 GetAggregatedStackCount(const FGameplayEffectQuery& Query) const;

	/** This only exists so it can be hooked up to a multicast delegate */
	/** 이것은 멀티캐스트 델리게이트에 연결될 수 있도록 존재합니다. */
	void RemoveActiveGameplayEffect_NoReturn(FActiveGameplayEffectHandle Handle, int32 StacksToRemove=-1)
	{
		RemoveActiveGameplayEffect(Handle, StacksToRemove);
	}

	/** Called for predictively added gameplay cue. Needs to remove tag count and possible invoke OnRemove event if misprediction */
	/** 예측적으로 추가된 게임플레이 큐에 대해 호출됩니다. 잘못된 예측이 발생한 경우 태그 수를 제거하고 OnRemove 이벤트를 호출해야 합니다. */
	virtual void OnPredictiveGameplayCueCatchup(FGameplayTag Tag);

	/** Returns the total duration of a gameplay effect */
	/** 게임플레이 효과의 총 지속 시간을 반환합니다. */
	float GetGameplayEffectDuration(FActiveGameplayEffectHandle Handle) const;

	/** Called whenever the server time replicates via the game state to keep our cooldown timers in sync with the server */
	/** 게임 상태를 통해 서버 시간이 복제될 때마다 호출되어 쿨다운 타이머를 서버와 동기화합니다. */
	virtual void RecomputeGameplayEffectStartTimes(const float WorldTime, const float ServerWorldTime);

	/** Return start time and total duration of a gameplay effect */
	/** 게임플레이 효과의 시작 시간과 총 지속 시간을 반환합니다. */
	void GetGameplayEffectStartTimeAndDuration(FActiveGameplayEffectHandle Handle, float& StartEffectTime, float& Duration) const;

	/** Dynamically update the set-by-caller magnitude for an active gameplay effect */
	/** 활성 게임플레이 효과의 set-by-caller 크기를 동적으로 업데이트합니다. */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = GameplayEffects)
	virtual void UpdateActiveGameplayEffectSetByCallerMagnitude(FActiveGameplayEffectHandle ActiveHandle, UPARAM(meta=(Categories = "SetByCaller"))FGameplayTag SetByCallerTag, float NewValue);

	/** Dynamically update multiple set-by-caller magnitudes for an active gameplay effect */
	/** 활성 게임플레이 효과의 여러 set-by-caller 크기를 동적으로 업데이트합니다. */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = GameplayEffects)
	virtual void UpdateActiveGameplayEffectSetByCallerMagnitudes(FActiveGameplayEffectHandle ActiveHandle, const TMap<FGameplayTag, float>& NewSetByCallerValues);

	/** Updates the level of an already applied gameplay effect. The intention is that this is 'seemless' and doesnt behave like removing/reapplying */
	/** 이미 적용된 게임플레이 효과의 레벨을 업데이트합니다. 이는 제거/재적용처럼 작동하지 않도록 하는 것이 목적입니다. */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = GameplayEffects)
	virtual void SetActiveGameplayEffectLevel(FActiveGameplayEffectHandle ActiveHandle, int32 NewLevel);

	/** Updates the level of an already applied gameplay effect. The intention is that this is 'seemless' and doesnt behave like removing/reapplying */
	/** 이미 적용된 게임플레이 효과의 레벨을 업데이트합니다. 이는 제거/재적용처럼 작동하지 않도록 하는 것이 목적입니다. */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = GameplayEffects)
	virtual void SetActiveGameplayEffectLevelUsingQuery(FGameplayEffectQuery Query, int32 NewLevel);

	/** Inhibit an active gameplay effect so that it is disabled, but not removed */
	/** 활성 게임플레이 효과를 억제하여 비활성화하지만 제거하지는 않습니다. */
	virtual void InhibitActiveGameplayEffect(FActiveGameplayEffectHandle ActiveGEHandle, bool bInhibit, bool bInvokeGameplayCueEvents);

	/**
	 * Raw accessor to ask the magnitude of a gameplay effect, not necessarily always correct. How should outside code (UI, etc) ask things like 'how much is this gameplay effect modifying my damage by'
	 * (most likely we want to catch this on the backend - when damage is applied we can get a full dump/history of how the number got to where it is. But still we may need polling methods like below (how much would my damage be)
	 */
	 /**
  * 게임플레이 효과의 크기를 묻는 Raw 접근자, 항상 정확하지는 않을 수 있습니다. 외부 코드(UI 등)가 '이 게임플레이 효과가 내 피해량을 얼마나 수정하고 있는가'와 같은 질문을 할 때 어떻게 물어봐야 하는가
  * (가장 가능성이 높은 방법은 백엔드에서 이 작업을 잡는 것입니다 - 피해가 적용될 때 숫자가 어떻게 계산되었는지에 대한 전체 덤프/히스토리를 얻을 수 있습니다. 하지만 여전히 아래와 같은 폴링 메서드가 필요할 수 있습니다 (내 피해가 얼마나 될지)
  */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	float GetGameplayEffectMagnitude(FActiveGameplayEffectHandle Handle, FGameplayAttribute Attribute) const;

	/** Returns current stack count of an already applied GE */
	/** 이미 적용된 게임플레이 효과의 현재 스택 수를 반환합니다. */
	int32 GetCurrentStackCount(FActiveGameplayEffectHandle Handle) const;

	/** Returns current stack count of an already applied GE, but given the ability spec handle that was granted by the GE */
	/** 게임플레이 효과에 의해 부여된 능력 사양 핸들을 주어 현재 스택 수를 반환합니다. */
	int32 GetCurrentStackCount(FGameplayAbilitySpecHandle Handle) const;

	/** Returns debug string describing active gameplay effect */
	/** 활성 게임플레이 효과를 설명하는 디버그 문자열을 반환합니다. */
	FString GetActiveGEDebugString(FActiveGameplayEffectHandle Handle) const;

	/** Gets the GE Handle of the GE that granted the passed in Ability */
	/** 부여된 능력의 활성 게임플레이 효과 핸들을 찾습니다. */
	FActiveGameplayEffectHandle FindActiveGameplayEffectHandle(FGameplayAbilitySpecHandle Handle) const;

	/** Returns const pointer to the actual active gameplay effect structure */
	/** 실제 활성 게임플레이 효과 구조체에 대한 const 포인터를 반환합니다. */
	const FActiveGameplayEffect* GetActiveGameplayEffect(const FActiveGameplayEffectHandle Handle) const;

	/** Returns all active gameplay effects on this ASC */
	/** 이 능력 시스템 컴포넌트에 있는 모든 활성 게임플레이 효과를 반환합니다. */
	const FActiveGameplayEffectsContainer& GetActiveGameplayEffects() const;

	/** Returns a const pointer to the gameplay effect CDO associated with an active handle. */
	/** 활성 핸들과 연결된 게임플레이 효과 CDO에 대한 const 포인터를 반환합니다. */
	const UGameplayEffect* GetGameplayEffectCDO(const FActiveGameplayEffectHandle Handle) const;

	/**
	 * Get the source tags from the gameplay spec represented by the specified handle, if possible
	 * 
	 * @param Handle	Handle of the gameplay effect to retrieve source tags from
	 * 
	 * @return Source tags from the gameplay spec represented by the handle, if possible
	 */
	 /**
  * 가능하면 지정된 핸들로 표현되는 게임플레이 사양에서 소스 태그를 가져옵니다.
  *
  * @param Handle	소스 태그를 검색할 게임플레이 효과의 핸들
  *
  * @return 가능하면 핸들로 표현되는 게임플레이 사양에서 소스 태그를 반환합니다.
  */
	const FGameplayTagContainer* GetGameplayEffectSourceTagsFromHandle(FActiveGameplayEffectHandle Handle) const;

	/**
	 * Get the target tags from the gameplay spec represented by the specified handle, if possible
	 * 
	 * @param Handle	Handle of the gameplay effect to retrieve target tags from
	 * 
	 * @return Target tags from the gameplay spec represented by the handle, if possible
	 */
	 /**
  * 가능하면 지정된 핸들로 표현되는 게임플레이 사양에서 타겟 태그를 가져옵니다.
  *
  * @param Handle	타겟 태그를 검색할 게임플레이 효과의 핸들
  *
  * @return 가능하면 핸들로 표현되는 게임플레이 사양에서 타겟 태그를 반환합니다.
  */
	const FGameplayTagContainer* GetGameplayEffectTargetTagsFromHandle(FActiveGameplayEffectHandle Handle) const;

	/**
	 * Populate the specified capture spec with the data necessary to capture an attribute from the component
	 * 
	 * @param OutCaptureSpec	[OUT] Capture spec to populate with captured data
	 */
	 /**
  * 지정된 캡처 사양을 컴포넌트에서 속성을 캡처하는 데 필요한 데이터로 채웁니다.
  *
  * @param OutCaptureSpec	[OUT] 캡처된 데이터로 채울 캡처 사양
  */
	void CaptureAttributeForGameplayEffect(OUT FGameplayEffectAttributeCaptureSpec& OutCaptureSpec);
	
	// ----------------------------------------------------------------------------------------------------------------
	//  Callbacks / Notifies
	//  (these need to be at the UObject level so we can safely bind, rather than binding to raw at the ActiveGameplayEffect/Container level which is unsafe if the AbilitySystemComponent were killed).
	// ----------------------------------------------------------------------------------------------------------------
	// ----------------------------------------------------------------------------------------------------------------
//  콜백 / 알림
//  (이들은 UObject 레벨에 있어야 안전하게 바인딩할 수 있습니다. ActiveGameplayEffect/Container 레벨에서 raw로 바인딩하는 것은 AbilitySystemComponent가 죽을 경우 안전하지 않습니다).
// ----------------------------------------------------------------------------------------------------------------
	/** Called when a specific attribute aggregator value changes, gameplay effects refresh their values when this happens */
	/** 특정 속성 집계자 값이 변경될 때 호출됩니다. 게임플레이 효과는 이때 값을 새로 고칩니다. */
	void OnAttributeAggregatorDirty(FAggregator* Aggregator, FGameplayAttribute Attribute, bool FromRecursiveCall=false);

	/** Called when attribute magnitudes change, to forward information to dependent gameplay effects */
	/** 속성 크기가 변경될 때 호출되어 종속 게임플레이 효과에 정보를 전달합니다. */
	void OnMagnitudeDependencyChange(FActiveGameplayEffectHandle Handle, const FAggregator* ChangedAggregator);

	/** This ASC has successfully applied a GE to something (potentially itself) */
	/** 이 ASC가 무언가(자기 자신일 수도 있음)에 GE를 성공적으로 적용했을 때 호출됩니다. */
	void OnGameplayEffectAppliedToTarget(UAbilitySystemComponent* Target, const FGameplayEffectSpec& SpecApplied, FActiveGameplayEffectHandle ActiveHandle);
	void OnGameplayEffectAppliedToSelf(UAbilitySystemComponent* Source, const FGameplayEffectSpec& SpecApplied, FActiveGameplayEffectHandle ActiveHandle);
	void OnPeriodicGameplayEffectExecuteOnTarget(UAbilitySystemComponent* Target, const FGameplayEffectSpec& SpecExecuted, FActiveGameplayEffectHandle ActiveHandle);
	void OnPeriodicGameplayEffectExecuteOnSelf(UAbilitySystemComponent* Source, const FGameplayEffectSpec& SpecExecuted, FActiveGameplayEffectHandle ActiveHandle);

	/** Called when the duration of a gamepaly effect has changed */
	/** 게임플레이 효과의 지속 시간이 변경될 때 호출됩니다. */
	virtual void OnGameplayEffectDurationChange(struct FActiveGameplayEffect& ActiveEffect);

	/** Called on server whenever a GE is applied to self. This includes instant and duration based GEs. */
	/** 서버에서 GE가 자기 자신에게 적용될 때마다 호출됩니다. 여기에는 즉시 및 지속 시간 기반 GE가 포함됩니다. */
	FOnGameplayEffectAppliedDelegate OnGameplayEffectAppliedDelegateToSelf;

	/** Called on server whenever a GE is applied to someone else. This includes instant and duration based GEs. */
	/** 서버에서 GE가 다른 사람에게 적용될 때마다 호출됩니다. 여기에는 즉시 및 지속 시간 기반 GE가 포함됩니다. */
	FOnGameplayEffectAppliedDelegate OnGameplayEffectAppliedDelegateToTarget;

	/** Called on both client and server whenever a duraton based GE is added (E.g., instant GEs do not trigger this). */
	/** 지속 시간 기반 GE가 추가될 때마다 클라이언트와 서버 모두에서 호출됩니다(예: 즉시 GE는 이를 트리거하지 않음). */
	FOnGameplayEffectAppliedDelegate OnActiveGameplayEffectAddedDelegateToSelf;

	/** Called on server whenever a periodic GE executes on self */
	/** 서버에서 주기적인 GE가 자기 자신에게 실행될 때마다 호출됩니다. */
	FOnGameplayEffectAppliedDelegate OnPeriodicGameplayEffectExecuteDelegateOnSelf;

	/** Called on server whenever a periodic GE executes on target */
	/** 서버에서 주기적인 GE가 타겟에 실행될 때마다 호출됩니다. */
	FOnGameplayEffectAppliedDelegate OnPeriodicGameplayEffectExecuteDelegateOnTarget;

	/** Immunity notification support */
	/** Immunity 알림 지원 */
	FImmunityBlockGE OnImmunityBlockGameplayEffectDelegate;

	/** Register for when an attribute value changes, should be replaced by GetGameplayAttributeValueChangeDelegate */
	/** 속성 값이 변경될 때 등록, GetGameplayAttributeValueChangeDelegate로 대체되어야 함 */
	FOnGameplayAttributeChange& RegisterGameplayAttributeEvent(FGameplayAttribute Attribute);

	/** Register for when an attribute value changes */
	/** 속성 값이 변경될 때 등록 */
	FOnGameplayAttributeValueChange& GetGameplayAttributeValueChangeDelegate(FGameplayAttribute Attribute);

	/** A generic callback anytime an ability is activated (started) */
	/** 능력이 활성화(시작)될 때마다 발생하는 일반적인 콜백 */
	FGenericAbilityDelegate AbilityActivatedCallbacks;

	/** Callback anytime an ability is ended */
	/** 능력이 종료될 때마다 발생하는 콜백 */
	FAbilityEnded AbilityEndedCallbacks;

	/** Callback anytime an ability is ended, with extra information */
	/** 추가 정보와 함께 능력이 종료될 때마다 발생하는 콜백 */
	FGameplayAbilityEndedDelegate OnAbilityEnded;

	/** A generic callback anytime an ability is committed (cost/cooldown applied) */
	/** 능력이 커밋될 때마다(비용/쿨다운 적용) 발생하는 일반적인 콜백 */
	FGenericAbilityDelegate AbilityCommittedCallbacks;

	/** Called with a failure reason when an ability fails to activate */
	/** 능력이 활성화에 실패할 때 실패 이유와 함께 호출됨 */
	FAbilityFailedDelegate AbilityFailedCallbacks;

	/** Called when an ability spec's internals have changed */
	/** 능력 사양의 내부가 변경되었을 때 호출됨 */
	FAbilitySpecDirtied AbilitySpecDirtiedCallbacks;

	/** We allow users to setup a series of functions that must be true in order to allow a GameplayEffect to be applied */
	/** 사용자들이 게임플레이 효과를 적용할 수 있도록 해야 하는 일련의 함수들을 설정할 수 있도록 허용 */
	TArray<FGameplayEffectApplicationQuery> GameplayEffectApplicationQueries;

	/** Call notify callbacks above */
	/** 위의 알림 콜백 호출 */
	virtual void NotifyAbilityCommit(UGameplayAbility* Ability);
	virtual void NotifyAbilityActivated(const FGameplayAbilitySpecHandle Handle, UGameplayAbility* Ability);
	virtual void NotifyAbilityFailed(const FGameplayAbilitySpecHandle Handle, UGameplayAbility* Ability, const FGameplayTagContainer& FailureReason);

	/** Called when any gameplay effects are removed */
	/** 게임플레이 효과가 제거될 때마다 호출됨 */
	FOnGivenActiveGameplayEffectRemoved& OnAnyGameplayEffectRemovedDelegate();

	/** Returns delegate structure that allows binding to several gameplay effect changes */
	/** 여러 게임플레이 효과 변경에 바인딩할 수 있는 델리게이트 구조 반환 */
	FActiveGameplayEffectEvents* GetActiveEffectEventSet(FActiveGameplayEffectHandle Handle);
	FOnActiveGameplayEffectRemoved_Info* OnGameplayEffectRemoved_InfoDelegate(FActiveGameplayEffectHandle Handle);
	FOnActiveGameplayEffectStackChange* OnGameplayEffectStackChangeDelegate(FActiveGameplayEffectHandle Handle);
	FOnActiveGameplayEffectTimeChange* OnGameplayEffectTimeChangeDelegate(FActiveGameplayEffectHandle Handle);

	// ----------------------------------------------------------------------------------------------------------------
	//  Gameplay tag operations
	//  Implements IGameplayTagAssetInterface using the TagCountContainer
	// 게임플레이 태그 작업
	//  TagCountContainer를 사용하여 IGameplayTagAssetInterface를 구현
	// ----------------------------------------------------------------------------------------------------------------
	FORCEINLINE bool HasMatchingGameplayTag(FGameplayTag TagToCheck) const override
	{
		return GameplayTagCountContainer.HasMatchingGameplayTag(TagToCheck);
	}

	FORCEINLINE bool HasAllMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override
	{
		return GameplayTagCountContainer.HasAllMatchingGameplayTags(TagContainer);
	}

	FORCEINLINE bool HasAnyMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override
	{
		return GameplayTagCountContainer.HasAnyMatchingGameplayTags(TagContainer);
	}

	FORCEINLINE void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override
	{
		TagContainer.Reset();
		TagContainer.AppendTags(GameplayTagCountContainer.GetExplicitGameplayTags());
	}

	/** Returns the number of instances of a given tag */
	/** 주어진 태그의 인스턴스 수를 반환 */
	FORCEINLINE int32 GetTagCount(FGameplayTag TagToCheck) const
	{
		return GameplayTagCountContainer.GetTagCount(TagToCheck);
	}

	/** Forcibly sets the number of instances of a given tag */
	/** 주어진 태그의 인스턴스 수를 강제로 설정 */
	FORCEINLINE void SetTagMapCount(const FGameplayTag& Tag, int32 NewCount)
	{
		GameplayTagCountContainer.SetTagCount(Tag, NewCount);
	}

	/** Update the number of instances of a given tag and calls callback */
	/** 주어진 태그의 인스턴스 수를 업데이트하고 콜백을 호출 */

	FORCEINLINE void UpdateTagMap(const FGameplayTag& BaseTag, int32 CountDelta)
	{
		if (GameplayTagCountContainer.UpdateTagCount(BaseTag, CountDelta))
		{
			OnTagUpdated(BaseTag, CountDelta > 0);
		}
	}

	/** Update the number of instances of a given tag and calls callback */
	/** 주어진 태그 컨테이너의 인스턴스 수를 업데이트하고 콜백을 호출 */
	FORCEINLINE void UpdateTagMap(const FGameplayTagContainer& Container, int32 CountDelta)
	{
		if (!Container.IsEmpty())
		{
			UpdateTagMap_Internal(Container, CountDelta);
		}
	}

	/** Fills TagContainer with BlockedAbilityTags */
	/** TagContainer를 BlockedAbilityTags로 채움 */
	FORCEINLINE void GetBlockedAbilityTags(FGameplayTagContainer& TagContainer) const
	{
		TagContainer.AppendTags(BlockedAbilityTags.GetExplicitGameplayTags());
	}

	/** 	 
	 *  Allows GameCode to add loose gameplaytags which are not backed by a GameplayEffect. 
	 *	Tags added this way are not replicated! Use the 'Replicated' versions of these functions if replication is needed.
	 *	It is up to the calling GameCode to make sure these tags are added on clients/server where necessary
	 */
	 /**
	  * 게임 코드가 GameplayEffect로 지원되지 않는 느슨한 게임플레이 태그를 추가할 수 있도록 허용.
	  * 이 방식으로 추가된 태그는 복제되지 않습니다! 복제가 필요한 경우 이 함수의 '복제된' 버전을 사용하십시오.
	  * 호출하는 게임 코드가 필요한 클라이언트/서버에 이러한 태그를 추가하는지 확인해야 합니다.
	  */
	FORCEINLINE void AddLooseGameplayTag(const FGameplayTag& GameplayTag, int32 Count=1)
	{
		UpdateTagMap(GameplayTag, Count);
	}

	FORCEINLINE void AddLooseGameplayTags(const FGameplayTagContainer& GameplayTags, int32 Count = 1)
	{
		UpdateTagMap(GameplayTags, Count);
	}

	FORCEINLINE void RemoveLooseGameplayTag(const FGameplayTag& GameplayTag, int32 Count = 1)
	{
		UpdateTagMap(GameplayTag, -Count);
	}

	FORCEINLINE void RemoveLooseGameplayTags(const FGameplayTagContainer& GameplayTags, int32 Count = 1)
	{
		UpdateTagMap(GameplayTags, -Count);
	}

	FORCEINLINE void SetLooseGameplayTagCount(const FGameplayTag& GameplayTag, int32 NewCount)
	{
		SetTagMapCount(GameplayTag, NewCount);
	}

	/**
	 * Returns the current count of the given gameplay tag.
	 * This includes both loose tags, and tags granted by gameplay effects and abilities.
	 * This function can be called on the client, but it may not display the most current count on the server.
	 *
	 * @param GameplayTag The gameplay tag to query
	 */
	 /**
	  * 주어진 게임플레이 태그의 현재 개수를 반환.
	  * 여기에는 느슨한 태그와 게임플레이 효과 및 능력으로 부여된 태그가 모두 포함됩니다.
	  * 이 함수는 클라이언트에서 호출할 수 있지만 서버의 최신 개수를 표시하지 않을 수 있습니다.
	  *
	  * @param GameplayTag 쿼리할 게임플레이 태그
	  */
	UFUNCTION(BlueprintPure, Category = "Gameplay Tags")
	int32 GetGameplayTagCount(FGameplayTag GameplayTag) const;

	/**
	 *  Allows GameCode to add loose gameplaytags which are not backed by a GameplayEffect. Tags added using 
	 *  these functions will be replicated. Note that replicated loose tags will override any locally-set tag counts
	 *  on simulated proxies.
	 */
	/**
	 * 게임 코드가 GameplayEffect로 지원되지 않는 느슨한 게임플레이 태그를 추가할 수 있도록 허용.
	 * 이 함수로 추가된 태그는 복제됩니다. 복제된 느슨한 태그는 시뮬레이션 프록시에서 로컬로 설정된 태그 수를 덮어씁니다.
	 */
	FORCEINLINE void AddReplicatedLooseGameplayTag(const FGameplayTag& GameplayTag)
	{
		GetReplicatedLooseTags_Mutable().AddTag(GameplayTag);
	}

	FORCEINLINE void AddReplicatedLooseGameplayTags(const FGameplayTagContainer& GameplayTags)
	{
		GetReplicatedLooseTags_Mutable().AddTags(GameplayTags);
	}

	FORCEINLINE void RemoveReplicatedLooseGameplayTag(const FGameplayTag& GameplayTag)
	{
		GetReplicatedLooseTags_Mutable().RemoveTag(GameplayTag);
	}

	FORCEINLINE void RemoveReplicatedLooseGameplayTags(const FGameplayTagContainer& GameplayTags)
	{
		GetReplicatedLooseTags_Mutable().RemoveTags(GameplayTags);
	}

	FORCEINLINE void SetReplicatedLooseGameplayTagCount(const FGameplayTag& GameplayTag, int32 NewCount)
	{
		GetReplicatedLooseTags_Mutable().SetTagCount(GameplayTag, NewCount);
	}

	/** 	 
	 * Minimally replicated tags are replicated tags that come from GEs when in bMinimalReplication mode. 
	 * (The GEs do not replicate, but the tags they grant do replicate via these functions)
	 */
	 /**
	  * 게임 코드가 GameplayEffect로 지원되지 않는 느슨한 게임플레이 태그를 제거할 수 있도록 허용.
	  * 이 함수로 제거된 태그는 복제됩니다. 복제된 느슨한 태그는 시뮬레이션 프록시에서 로컬로 설정된 태그 수를 덮어씁니다.
	  */
	FORCEINLINE void AddMinimalReplicationGameplayTag(const FGameplayTag& GameplayTag)
	{
		GetMinimalReplicationTags_Mutable().AddTag(GameplayTag);
	}

	FORCEINLINE void AddMinimalReplicationGameplayTags(const FGameplayTagContainer& GameplayTags)
	{
		GetMinimalReplicationTags_Mutable().AddTags(GameplayTags);
	}

	FORCEINLINE void RemoveMinimalReplicationGameplayTag(const FGameplayTag& GameplayTag)
	{
		GetMinimalReplicationTags_Mutable().RemoveTag(GameplayTag);
	}

	FORCEINLINE void RemoveMinimalReplicationGameplayTags(const FGameplayTagContainer& GameplayTags)
	{
		GetMinimalReplicationTags_Mutable().RemoveTags(GameplayTags);
	}

	/** Allow events to be registered for specific gameplay tags being added or removed */
	/** 특정 게임플레이 태그가 추가되거나 제거될 때 이벤트를 등록할 수 있게 허용 */
	FOnGameplayEffectTagCountChanged& RegisterGameplayTagEvent(FGameplayTag Tag, EGameplayTagEventType::Type EventType=EGameplayTagEventType::NewOrRemoved);

	/** Unregister previously added events */
	/** 이전에 추가된 이벤트를 등록 해제 */
	bool UnregisterGameplayTagEvent(FDelegateHandle DelegateHandle, FGameplayTag Tag, EGameplayTagEventType::Type EventType=EGameplayTagEventType::NewOrRemoved);

	/** Register a tag event and immediately call it */
	/** 태그 이벤트를 등록하고 즉시 호출 */
	FDelegateHandle RegisterAndCallGameplayTagEvent(FGameplayTag Tag, FOnGameplayEffectTagCountChanged::FDelegate Delegate, EGameplayTagEventType::Type EventType=EGameplayTagEventType::NewOrRemoved);

	/** Returns multicast delegate that is invoked whenever a tag is added or removed (but not if just count is increased. Only for 'new' and 'removed' events) */
	/** 태그가 추가되거나 제거될 때마다 호출되는 멀티캐스트 대리자를 반환 (단순히 개수가 증가할 때는 호출되지 않음. 'new' 및 'removed' 이벤트에만 해당) */
	FOnGameplayEffectTagCountChanged& RegisterGenericGameplayTagEvent();

	/** Executes a gameplay event. Returns the number of successful ability activations triggered by the event */
	/** 게임플레이 이벤트를 실행. 이벤트로 인해 성공적으로 활성화된 능력의 수를 반환 */
	virtual int32 HandleGameplayEvent(FGameplayTag EventTag, const FGameplayEventData* Payload);

	/** Adds a new delegate to call when gameplay events happen. It will only be called if it matches any tags in passed filter container */
	/** 게임플레이 이벤트가 발생할 때 호출할 새 대리자를 추가. 전달된 필터 컨테이너의 태그와 일치하는 경우에만 호출됨 */
	FDelegateHandle AddGameplayEventTagContainerDelegate(const FGameplayTagContainer& TagFilter, const FGameplayEventTagMulticastDelegate::FDelegate& Delegate);

	/** Remotes previously registered delegate */
	/** 이전에 등록된 대리자 제거 */
	void RemoveGameplayEventTagContainerDelegate(const FGameplayTagContainer& TagFilter, FDelegateHandle DelegateHandle);

	/** Callbacks bound to Gameplay tags, these only activate if the exact tag is used. To handle tag hierarchies use AddGameplayEventContainerDelegate */
	/** 게임플레이 태그에 바인딩된 콜백, 정확한 태그가 사용될 때만 활성화됨. 태그 계층을 처리하려면 AddGameplayEventContainerDelegate 사용 */
	TMap<FGameplayTag, FGameplayEventMulticastDelegate> GenericGameplayEventCallbacks;

	// ----------------------------------------------------------------------------------------------------------------
	//  System Attributes
	// ----------------------------------------------------------------------------------------------------------------

	/** Internal Attribute that modifies the duration of gameplay effects created by this component */
	/** 이 컴포넌트에서 생성된 게임플레이 이펙트의 지속 시간을 수정하는 내부 속성 */
	UPROPERTY(meta=(SystemGameplayAttribute="true"))
	float OutgoingDuration;

	/** Internal Attribute that modifies the duration of gameplay effects applied to this component */
	/** 이 컴포넌트에 적용된 게임플레이 이펙트의 지속 시간을 수정하는 내부 속성 */
	UPROPERTY(meta = (SystemGameplayAttribute = "true"))
	float IncomingDuration;
	/** OutgoingDuration 속성에 대한 static 함수 */
	static FProperty* GetOutgoingDurationProperty();
	/** IncomingDuration 속성에 대한 static 함수 */
	static FProperty* GetIncomingDurationProperty();
	/** OutgoingDuration의 게임플레이 이펙트 속성 캡처 정의를 가져오는 정적 함수 */
	static const FGameplayEffectAttributeCaptureDefinition& GetOutgoingDurationCapture();
	/** IncomingDuration의 게임플레이 이펙트 속성 캡처 정의를 가져오는 정적 함수 */
	static const FGameplayEffectAttributeCaptureDefinition& GetIncomingDurationCapture();

	// ----------------------------------------------------------------------------------------------------------------
	//  Additional Helper Functions
	// 추가적인 도움 함수
	// ----------------------------------------------------------------------------------------------------------------

	/** Apply a gameplay effect to passed in target */
	/** 대상에게 게임플레이 이펙트를 적용하는 함수 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects, meta=(DisplayName = "ApplyGameplayEffectToTarget", ScriptName = "ApplyGameplayEffectToTarget"))
	FActiveGameplayEffectHandle BP_ApplyGameplayEffectToTarget(TSubclassOf<UGameplayEffect> GameplayEffectClass, UAbilitySystemComponent *Target, float Level, FGameplayEffectContextHandle Context);
	FActiveGameplayEffectHandle ApplyGameplayEffectToTarget(UGameplayEffect *GameplayEffect, UAbilitySystemComponent *Target, float Level = UGameplayEffect::INVALID_LEVEL, FGameplayEffectContextHandle Context = FGameplayEffectContextHandle(), FPredictionKey PredictionKey = FPredictionKey());

	/** Apply a gameplay effect to self */
	/** 자신에게 게임플레이 이펙트를 적용하는 함수 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects, meta=(DisplayName = "ApplyGameplayEffectToSelf", ScriptName = "ApplyGameplayEffectToSelf"))
	FActiveGameplayEffectHandle BP_ApplyGameplayEffectToSelf(TSubclassOf<UGameplayEffect> GameplayEffectClass, float Level, FGameplayEffectContextHandle EffectContext);
	FActiveGameplayEffectHandle ApplyGameplayEffectToSelf(const UGameplayEffect *GameplayEffect, float Level, const FGameplayEffectContextHandle& EffectContext, FPredictionKey PredictionKey = FPredictionKey());

	/** Returns the number of gameplay effects that are currently active on this ability system component */
	/** 현재 이 능력 시스템 컴포넌트에 활성화된 게임플레이 이펙트의 개수를 반환하는 함수 */
	int32 GetNumActiveGameplayEffects() const
	{
		return ActiveGameplayEffects.GetNumGameplayEffects();
	}

	/** Makes a copy of all the active effects on this ability component */
	/** 현재 이 능력 시스템 컴포넌트에서 활성화된 모든 게임플레이 이펙트 스펙을 복사하는 함수 */
	void GetAllActiveGameplayEffectSpecs(TArray<FGameplayEffectSpec>& OutSpecCopies) const
	{
		ActiveGameplayEffects.GetAllActiveGameplayEffectSpecs(OutSpecCopies);
	}

	/** Call from OnRep functions to set the attribute base value on the client */
	/** OnRep 함수에서 클라이언트에게 속성 기본 값을 설정하는 함수 */
	void SetBaseAttributeValueFromReplication(const FGameplayAttribute& Attribute, float NewValue, float OldValue)
	{
		ActiveGameplayEffects.SetBaseAttributeValueFromReplication(Attribute, NewValue, OldValue);
	}

	/** Call from OnRep functions to set the attribute base value on the client */
	/** 이 GameplayEffect에서 모든 수정자가 속성을 0보다 크게 남길 수 있는지 테스트하는 함수 */
	void SetBaseAttributeValueFromReplication(const FGameplayAttribute& Attribute, const FGameplayAttributeData& NewValue, const FGameplayAttributeData& OldValue)
	{
		ActiveGameplayEffects.SetBaseAttributeValueFromReplication(Attribute, NewValue.GetBaseValue(), OldValue.GetBaseValue());
	}

	/** Tests if all modifiers in this GameplayEffect will leave the attribute > 0.f */
	/** 이 GameplayEffect에서 모든 수정자가 속성을 0보다 크게 남길 수 있는지 테스트하는 함수 */
	bool CanApplyAttributeModifiers(const UGameplayEffect *GameplayEffect, float Level, const FGameplayEffectContextHandle& EffectContext)
	{
		return ActiveGameplayEffects.CanApplyAttributeModifiers(GameplayEffect, Level, EffectContext);
	}

	/** Gets time remaining for all effects that match query */
	/** 쿼리에 일치하는 모든 효과의 남은 시간을 가져옵니다 */
	TArray<float> GetActiveEffectsTimeRemaining(const FGameplayEffectQuery& Query) const;

	/** Gets total duration for all effects that match query */
	/** 쿼리에 일치하는 모든 효과의 총 지속 시간을 가져옵니다 */
	TArray<float> GetActiveEffectsDuration(const FGameplayEffectQuery& Query) const;

	/** Gets both time remaining and total duration  for all effects that match query */
	/** 쿼리에 일치하는 모든 효과의 남은 시간과 총 지속 시간을 모두 가져옵니다 */
	TArray<TPair<float,float>> GetActiveEffectsTimeRemainingAndDuration(const FGameplayEffectQuery& Query) const;

	/** Returns list of active effects, for a query */
	/** 쿼리에 대한 활성 효과 목록을 반환합니다 */
	UFUNCTION(BlueprintCallable, BlueprintPure=false, Category = "GameplayEffects", meta=(DisplayName = "Get Active Gameplay Effects for Query"))
	TArray<FActiveGameplayEffectHandle> GetActiveEffects(const FGameplayEffectQuery& Query) const;

	/** Returns list of active effects that have all of the passed in tags */
	/** 전달된 모든 태그를 가진 활성 효과 목록을 반환합니다 */
	UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "GameplayEffects")
	TArray<FActiveGameplayEffectHandle> GetActiveEffectsWithAllTags(FGameplayTagContainer Tags) const;

	/** This will give the world time that all effects matching this query will be finished. If multiple effects match, it returns the one that returns last */
	/** 쿼리에 일치하는 모든 효과가 완료되는 세계 시간을 반환합니다. 여러 효과가 일치하는 경우, 마지막으로 끝나는 효과의 시간을 반환합니다 */
	float GetActiveEffectsEndTime(const FGameplayEffectQuery& Query) const;
	float GetActiveEffectsEndTimeWithInstigators(const FGameplayEffectQuery& Query, TArray<AActor*>& Instigators) const;

	/** Returns end time and total duration */
	/** 종료 시간과 총 지속 시간을 반환합니다 */
	bool GetActiveEffectsEndTimeAndDuration(const FGameplayEffectQuery& Query, float& EndTime, float& Duration) const;

	/** Modify the start time of a gameplay effect, to deal with timers being out of sync originally */
	/** 원래 타이머가 동기화되지 않은 경우를 처리하기 위해 게임플레이 효과의 시작 시간을 수정합니다 */
	virtual void ModifyActiveEffectStartTime(FActiveGameplayEffectHandle Handle, float StartTimeDiff);

	/** Removes all active effects that contain any of the tags in Tags */
	/** 전달된 태그를 포함하는 모든 활성 효과를 제거합니다 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	int32 RemoveActiveEffectsWithTags(FGameplayTagContainer Tags);

	/** Removes all active effects with captured source tags that contain any of the tags in Tags */
	/** 전달된 태그를 포함하는 캡처된 소스 태그를 가진 모든 활성 효과를 제거합니다 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	int32 RemoveActiveEffectsWithSourceTags(FGameplayTagContainer Tags);

	/** Removes all active effects that apply any of the tags in Tags */
	/** 전달된 태그를 적용하는 모든 활성 효과를 제거합니다 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	int32 RemoveActiveEffectsWithAppliedTags(FGameplayTagContainer Tags);

	/** Removes all active effects that grant any of the tags in Tags */
	/** 전달된 태그를 부여하는 모든 활성 효과를 제거합니다 */
	UFUNCTION(BlueprintCallable, Category = GameplayEffects)
	int32 RemoveActiveEffectsWithGrantedTags(FGameplayTagContainer Tags);

	/** Removes all active effects that match given query. StacksToRemove=-1 will remove all stacks. */
	/** 주어진 쿼리에 일치하는 모든 활성 효과를 제거합니다. StacksToRemove=-1이면 모든 스택을 제거합니다 */
	virtual int32 RemoveActiveEffects(const FGameplayEffectQuery& Query, int32 StacksToRemove = -1);

	// ----------------------------------------------------------------------------------------------------------------
	//	GameplayCues
	// ----------------------------------------------------------------------------------------------------------------
	
	// Do not call these functions directly, call the wrappers on GameplayCueManager instead
	// 이 함수들을 직접 호출하지 마십시오. 대신 GameplayCueManager의 래퍼 함수를 호출하십시오
	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueExecuted_FromSpec(const FGameplayEffectSpecForRPC Spec, FPredictionKey PredictionKey) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueExecuted(const FGameplayTag GameplayCueTag, FPredictionKey PredictionKey, FGameplayEffectContextHandle EffectContext) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCuesExecuted(const FGameplayTagContainer GameplayCueTags, FPredictionKey PredictionKey, FGameplayEffectContextHandle EffectContext) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueExecuted_WithParams(const FGameplayTag GameplayCueTag, FPredictionKey PredictionKey, FGameplayCueParameters GameplayCueParameters) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCuesExecuted_WithParams(const FGameplayTagContainer GameplayCueTags, FPredictionKey PredictionKey, FGameplayCueParameters GameplayCueParameters) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueAdded(const FGameplayTag GameplayCueTag, FPredictionKey PredictionKey, FGameplayEffectContextHandle EffectContext) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueAdded_WithParams(const FGameplayTag GameplayCueTag, FPredictionKey PredictionKey, FGameplayCueParameters Parameters) override;
	
	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueAddedAndWhileActive_FromSpec(const FGameplayEffectSpecForRPC& Spec, FPredictionKey PredictionKey) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCueAddedAndWhileActive_WithParams(const FGameplayTag GameplayCueTag, FPredictionKey PredictionKey, FGameplayCueParameters GameplayCueParameters) override;

	UFUNCTION(NetMulticast, unreliable)
	void NetMulticast_InvokeGameplayCuesAddedAndWhileActive_WithParams(const FGameplayTagContainer GameplayCueTags, FPredictionKey PredictionKey, FGameplayCueParameters GameplayCueParameters) override;

	/** GameplayCues can also come on their own. These take an optional effect context to pass through hit result, etc */
	/** GameplayCues는 독립적으로 올 수 있습니다. 이 함수들은 히트 결과 등을 전달하기 위해 선택적 효과 컨텍스트를 받습니다 */
	void ExecuteGameplayCue(const FGameplayTag GameplayCueTag, FGameplayEffectContextHandle EffectContext = FGameplayEffectContextHandle());
	void ExecuteGameplayCue(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters);

	/** Add a persistent gameplay cue */
	/** 지속적인 gameplay cue를 추가합니다 */
	void AddGameplayCue(const FGameplayTag GameplayCueTag, FGameplayEffectContextHandle EffectContext = FGameplayEffectContextHandle());
	void AddGameplayCue(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters);

	/** Add gameplaycue for minimal replication mode. Should only be called in paths that would replicate gameplaycues in other ways (through GE for example) if not in minimal replication mode */
	/** 최소 복제 모드를 위한 gameplaycue를 추가합니다. 최소 복제 모드가 아닐 경우, 다른 방법으로 gameplaycue를 복제할 경로에서만 호출되어야 합니다 (예: GE를 통해) */
	void AddGameplayCue_MinimalReplication(const FGameplayTag GameplayCueTag, FGameplayEffectContextHandle EffectContext = FGameplayEffectContextHandle());

	/** Remove a persistent gameplay cue */
	/** 지속적인 gameplay cue를 제거합니다 */
	void RemoveGameplayCue(const FGameplayTag GameplayCueTag);
	
	/** Remove gameplaycue for minimal replication mode. Should only be called in paths that would replicate gameplaycues in other ways (through GE for example) if not in minimal replication mode */
	/** 최소 복제 모드를 위한 gameplaycue를 제거합니다. 최소 복제 모드가 아닐 경우, 다른 방법으로 gameplaycue를 복제할 경로에서만 호출되어야 합니다 (예: GE를 통해) */
	void RemoveGameplayCue_MinimalReplication(const FGameplayTag GameplayCueTag);
	
	/** Removes any GameplayCue added on its own, i.e. not as part of a GameplayEffect. */
	/** GameplayEffect의 일부로 추가되지 않은 모든 GameplayCue를 제거합니다. */
	void RemoveAllGameplayCues();

	/** Handles gameplay cue events from external sources */
	/** 외부 소스에서 온 gameplay cue 이벤트를 처리합니다 */
	void InvokeGameplayCueEvent(const FGameplayEffectSpecForRPC& Spec, EGameplayCueEvent::Type EventType);
	void InvokeGameplayCueEvent(const FGameplayTag GameplayCueTag, EGameplayCueEvent::Type EventType, FGameplayEffectContextHandle EffectContext = FGameplayEffectContextHandle());
	void InvokeGameplayCueEvent(const FGameplayTag GameplayCueTag, EGameplayCueEvent::Type EventType, const FGameplayCueParameters& GameplayCueParameters);

	/** Allows polling to see if a GameplayCue is active. We expect most GameplayCue handling to be event based, but some cases we may need to check if a GamepalyCue is active (Animation Blueprint for example) */
	/** GameplayCue가 활성화되어 있는지 확인하기 위한 폴링을 허용합니다. 대부분의 GameplayCue 처리는 이벤트 기반이지만, 일부 경우 (예: 애니메이션 블루프린트)에서는 GameplayCue가 활성화되어 있는지 확인해야 할 수 있습니다. */
	UFUNCTION(BlueprintCallable, Category="GameplayCue", meta=(GameplayTagFilter="GameplayCue"))
	bool IsGameplayCueActive(const FGameplayTag GameplayCueTag) const
	{
		return HasMatchingGameplayTag(GameplayCueTag);
	}

	/** Will initialize gameplay cue parameters with this ASC's Owner (Instigator) and AvatarActor (EffectCauser) */
	/** 이 ASC의 소유자(Instigator)와 아바타 액터(EffectCauser)로 게임플레이 큐 매개변수를 초기화합니다 */
	virtual void InitDefaultGameplayCueParameters(FGameplayCueParameters& Parameters);

	/** Are we ready to invoke gameplaycues yet? */
	/** 게임플레이 큐를 호출할 준비가 되었습니까? */
	virtual bool IsReadyForGameplayCues();

	/** Handle GameplayCues that may have been deferred while doing the NetDeltaSerialize and waiting for the avatar actor to get loaded */
	/** 아바타 액터가 로드될 때까지 NetDeltaSerialize를 기다리는 동안 지연된 게임플레이 큐를 처리합니다 */
	virtual void HandleDeferredGameplayCues(const FActiveGameplayEffectsContainer* GameplayEffectsContainer);

	/** Invokes the WhileActive event for all GCs on active, non inhibited, GEs. This would typically be used on "respawn" or something where the mesh/avatar has changed */
	/** 활성 상태이며 억제되지 않은 GE에서 모든 GC의 WhileActive 이벤트를 호출합니다. 이는 일반적으로 "재생성" 시 또는 메쉬/아바타가 변경된 경우에 사용됩니다 */
	virtual void ReinvokeActiveGameplayCues();

	/**
	 *	GameplayAbilities
	 *	
	 *	The role of the AbilitySystemComponent with respect to Abilities is to provide:
	 *		-Management of ability instances (whether per actor or per execution instance).
	 *			-Someone *has* to keep track of these instances.
	 *			-Non instanced abilities *could* be executed without any ability stuff in AbilitySystemComponent.
	 *				They should be able to operate on an GameplayAbilityActorInfo + GameplayAbility.
	 *		
	 *	As convenience it may provide some other features:
	 *		-Some basic input binding (whether instanced or non instanced abilities).
	 *		-Concepts like "this component has these abilities
	 *	
	 */
	 /**
  *	GameplayAbilities
  *
  *	능력 시스템 컴포넌트의 역할은 다음과 같습니다:
  *		-능력 인스턴스의 관리 (액터별 또는 실행 인스턴스별).
  *			-누군가 *반드시* 이 인스턴스들을 추적해야 합니다.
  *			-비인스턴스 능력은 능력 시스템 컴포넌트 없이 실행될 수 있습니다.
  *				이들은 GameplayAbilityActorInfo + GameplayAbility를 기반으로 작동할 수 있어야 합니다.
  *
  *	편의상 다음과 같은 추가 기능을 제공할 수 있습니다:
  *		-기본적인 입력 바인딩 (인스턴스 또는 비인스턴스 능력 여부와 상관없이).
  *		-"이 컴포넌트가 이러한 능력을 가지고 있다"와 같은 개념.
  */

	/*
	 * Grants an Ability.
	 * This will be ignored if the actor is not authoritative.
	 * Returns handle that can be used in TryActivateAbility, etc.
	 * 
	 * @param AbilitySpec FGameplayAbilitySpec containing information about the ability class, level and input ID to bind it to.
	 */
	FGameplayAbilitySpecHandle GiveAbility(const FGameplayAbilitySpec& AbilitySpec);

	/*
	 * Grants an ability and attempts to activate it exactly one time, which will cause it to be removed.
	 * Only valid on the server, and the ability's Net Execution Policy cannot be set to Local or Local Predicted
	 * 
	 * @param AbilitySpec FGameplayAbilitySpec containing information about the ability class, level and input ID to bind it to.
	 * @param GameplayEventData Optional activation event data. If provided, Activate Ability From Event will be called instead of ActivateAbility, passing the Event Data
	 */
	 /*
  * 능력을 부여합니다.
  * 액터가 권한이 없는 경우 무시됩니다.
  * TryActivateAbility 등에서 사용할 수 있는 핸들을 반환합니다.
  *
  * @param AbilitySpec 능력 클래스, 레벨 및 입력 ID에 대한 정보를 포함하는 FGameplayAbilitySpec입니다.
  */
	FGameplayAbilitySpecHandle GiveAbilityAndActivateOnce(FGameplayAbilitySpec& AbilitySpec, const FGameplayEventData* GameplayEventData = nullptr);

	/**
	 * Grants a Gameplay Ability and returns its handle.
	 * This will be ignored if the actor is not authoritative.
	 *
	 * @param AbilityClass Type of ability to grant
	 * @param Level Level to grant the ability at
	 * @param InputID Input ID value to bind ability activation to.
	 */
	/**
 * 게임플레이 능력을 부여하고 그 핸들을 반환합니다.
 * 액터가 권한이 없는 경우 무시됩니다.
 *
 * @param AbilityClass 부여할 능력의 유형
 * @param Level 능력을 부여할 레벨
 * @param InputID 능력 활성화를 바인딩할 입력 ID 값
 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Gameplay Abilities", meta = (DisplayName = "Give Ability", ScriptName = "GiveAbility"))
	FGameplayAbilitySpecHandle K2_GiveAbility(TSubclassOf<UGameplayAbility> AbilityClass, int32 Level = 0, int32 InputID = -1);

	/**
	 * Grants a Gameplay Ability, activates it once, and removes it.
	 * This will be ignored if the actor is not authoritative.
	 *
	 * @param AbilityClass Type of ability to grant
	 * @param Level Level to grant the ability at
	 * @param InputID Input ID value to bind ability activation to.
	 */
	 /**
  * 게임플레이 능력을 부여하고, 한 번 활성화한 후 제거합니다.
  * 액터가 권한이 없는 경우 무시됩니다.
  *
  * @param AbilityClass 부여할 능력의 유형
  * @param Level 능력을 부여할 레벨
  * @param InputID 능력 활성화를 바인딩할 입력 ID 값
  */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Gameplay Abilities", meta = (DisplayName = "Give Ability And Activate Once", ScriptName = "GiveAbilityAndActivateOnce"))
	FGameplayAbilitySpecHandle K2_GiveAbilityAndActivateOnce(TSubclassOf<UGameplayAbility> AbilityClass, int32 Level = 0, int32 InputID = -1);

	/** Wipes all 'given' abilities. This will be ignored if the actor is not authoritative. */
	/** 부여된 모든 능력을 제거합니다. 액터가 권한이 없는 경우 무시됩니다. */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Gameplay Abilities")
	void ClearAllAbilities();

	/**
	 * Clears all abilities bound to a given Input ID
	 * This will be ignored if the actor is not authoritative
	 *
	 * @param InputID The numeric Input ID of the abilities to remove
	 */
	 /**
	* 주어진 입력 ID에 바인딩된 모든 능력을 제거합니다.
	* 액터가 권한이 없는 경우 무시됩니다.
	*
	* @param InputID 제거할 능력의 입력 ID 값
	*/
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Gameplay Abilities")
	void ClearAllAbilitiesWithInputID(int32 InputID = 0);

	/** 
	 * Removes the specified ability.
	 * This will be ignored if the actor is not authoritative.
	 * 
	 * @param Handle Ability Spec Handle of the ability we want to remove
	 */
	 /**
  * 지정된 능력을 제거합니다.
  * 액터가 권한이 없는 경우 무시됩니다.
  *
  * @param Handle 제거하려는 능력의 스펙 핸들
  */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Gameplay Abilities")
	void ClearAbility(const FGameplayAbilitySpecHandle& Handle);
	
	/** Sets an ability spec to remove when its finished. If the spec is not currently active, it terminates it immediately. Also clears InputID of the Spec. */
	/**
 * 능력 스펙이 완료되면 제거하도록 설정합니다.
 * 스펙이 현재 활성 상태가 아닌 경우 즉시 종료됩니다. 또한 스펙의 InputID를 제거합니다.
 */
	void SetRemoveAbilityOnEnd(FGameplayAbilitySpecHandle AbilitySpecHandle);

	/** 
	 * Gets all Activatable Gameplay Abilities that match all tags in GameplayTagContainer AND for which
	 * DoesAbilitySatisfyTagRequirements() is true.  The latter requirement allows this function to find the correct
	 * ability without requiring advanced knowledge.  For example, if there are two "Melee" abilities, one of which
	 * requires a weapon and one of which requires being unarmed, then those abilities can use Blocking and Required
	 * tags to determine when they can fire.  Using the Satisfying Tags requirements simplifies a lot of usage cases.
	 * For example, Behavior Trees can use various decorators to test an ability fetched using this mechanism as well
	 * as the Task to execute the ability without needing to know that there even is more than one such ability.
	 */
	 /**
  * GameplayTagContainer에 있는 모든 태그와 일치하는 모든 활성화 가능한 게임플레이 능력을 가져오며,
  * DoesAbilitySatisfyTagRequirements()가 true인 경우에만 해당합니다. 후자의 요구 사항은 고급 지식 없이도
  * 올바른 능력을 찾을 수 있게 합니다. 예를 들어, "Melee" 능력이 두 개 있고, 하나는 무기가 필요하고
  * 하나는 무기가 필요하지 않다면, 이러한 능력들은 블로킹 및 필요한 태그를 사용하여 언제 발동할 수 있는지
  * 결정할 수 있습니다. 만족하는 태그 요구 사항을 사용하면 많은 사용 사례가 간소화됩니다. 예를 들어,
  * Behavior Trees는 이 메커니즘을 사용하여 가져온 능력을 테스트하고 태스크를 실행할 수 있으며,
  * 여러 개의 능력이 있는지조차 알 필요가 없습니다.
  */
	void GetActivatableGameplayAbilitySpecsByAllMatchingTags(const FGameplayTagContainer& GameplayTagContainer, TArray < struct FGameplayAbilitySpec* >& MatchingGameplayAbilities, bool bOnlyAbilitiesThatSatisfyTagRequirements = true) const;

	/** 
	 * Attempts to activate every gameplay ability that matches the given tag and DoesAbilitySatisfyTagRequirements().
	 * Returns true if anything attempts to activate. Can activate more than one ability and the ability may fail later.
	 * If bAllowRemoteActivation is true, it will remotely activate local/server abilities, if false it will only try to locally activate abilities.
	 */
	 /**
  * 주어진 태그와 일치하는 모든 게임플레이 능력을 활성화하려고 시도하고 DoesAbilitySatisfyTagRequirements()를 만족합니다.
  * 무언가가 활성화를 시도하면 true를 반환합니다. 여러 능력을 활성화할 수 있으며 나중에 실패할 수도 있습니다.
  * bAllowRemoteActivation이 true이면 로컬/서버 능력을 원격으로 활성화하며, false이면 로컬에서만 능력을 활성화하려고 시도합니다.
  */
	UFUNCTION(BlueprintCallable, Category = "Abilities")
	bool TryActivateAbilitiesByTag(const FGameplayTagContainer& GameplayTagContainer, bool bAllowRemoteActivation = true);

	/**
	 * Attempts to activate the ability that is passed in. This will check costs and requirements before doing so.
	 * Returns true if it thinks it activated, but it may return false positives due to failure later in activation.
	 * If bAllowRemoteActivation is true, it will remotely activate local/server abilities, if false it will only try to locally activate the ability
	 */
	 /**
  * 전달된 능력을 활성화하려고 시도합니다. 활성화 전에 비용과 요구 사항을 확인합니다.
  * 활성화되었다고 생각되면 true를 반환하지만, 나중에 활성화 과정에서 실패할 수 있으므로 false 양성 결과를 반환할 수 있습니다.
  * bAllowRemoteActivation이 true이면 로컬/서버 능력을 원격으로 활성화하며, false이면 로컬에서만 능력을 활성화하려고 시도합니다.
  */
	UFUNCTION(BlueprintCallable, Category = "Abilities")
	bool TryActivateAbilityByClass(TSubclassOf<UGameplayAbility> InAbilityToActivate, bool bAllowRemoteActivation = true);

	/** 
	 * Attempts to activate the given ability, will check costs and requirements before doing so.
	 * Returns true if it thinks it activated, but it may return false positives due to failure later in activation.
	 * If bAllowRemoteActivation is true, it will remotely activate local/server abilities, if false it will only try to locally activate the ability
	 */
	 /**
	* 주어진 능력을 활성화하려고 시도하며, 활성화 전에 비용과 요구 사항을 확인합니다.
	* 활성화되었다고 생각되면 true를 반환하지만, 나중에 활성화 과정에서 실패할 수 있으므로 false 양성 결과를 반환할 수 있습니다.
	* bAllowRemoteActivation이 true이면 로컬/서버 능력을 원격으로 활성화하며, false이면 로컬에서만 능력을 활성화하려고 시도합니다.
	*/
	UFUNCTION(BlueprintCallable, Category = "Abilities")
	bool TryActivateAbility(FGameplayAbilitySpecHandle AbilityToActivate, bool bAllowRemoteActivation = true);

	bool HasActivatableTriggeredAbility(FGameplayTag Tag);

	/** Triggers an ability from a gameplay event, will only trigger on local/server depending on execution flags */
	/** 게임플레이 이벤트로부터 능력을 트리거하며, 실행 플래그에 따라 로컬/서버에서만 트리거합니다 */
	bool TriggerAbilityFromGameplayEvent(FGameplayAbilitySpecHandle AbilityToTrigger, FGameplayAbilityActorInfo* ActorInfo, FGameplayTag Tag, const FGameplayEventData* Payload, UAbilitySystemComponent& Component);

	// ----------------------------------------------------------------------------------------------------------------
	// Ability Cancelling/Interrupts
	// ----------------------------------------------------------------------------------------------------------------

	/** Cancels the specified ability CDO. */
	/** 지정된 능력 CDO를 취소합니다. */
	void CancelAbility(UGameplayAbility* Ability);	

	/** Cancels the ability indicated by passed in spec handle. If handle is not found among reactivated abilities nothing happens. */
	/** 전달된 스펙 핸들에 의해 표시된 능력을 취소합니다. 핸들이 재활성화된 능력 중에 발견되지 않으면 아무 일도 일어나지 않습니다. */
	void CancelAbilityHandle(const FGameplayAbilitySpecHandle& AbilityHandle);

	/** Cancel all abilities with the specified tags. Will not cancel the Ignore instance */
	/** 지정된 태그를 가진 모든 능력을 취소합니다. Ignore 인스턴스는 취소하지 않습니다. */
	void CancelAbilities(const FGameplayTagContainer* WithTags=nullptr, const FGameplayTagContainer* WithoutTags=nullptr, UGameplayAbility* Ignore=nullptr);

	/** Cancels all abilities regardless of tags. Will not cancel the ignore instance */
	/** 태그에 관계없이 모든 능력을 취소합니다. Ignore 인스턴스는 취소하지 않습니다. */
	void CancelAllAbilities(UGameplayAbility* Ignore=nullptr);

	/** Cancels all abilities and kills any remaining instanced abilities */
	/** 모든 능력을 취소하고 남아 있는 인스턴스화된 능력을 제거합니다. */
	virtual void DestroyActiveState();

	/** 
	 * Called from ability activation or native code, will apply the correct ability blocking tags and cancel existing abilities. Subclasses can override the behavior 
	 * 
	 * @param AbilityTags The tags of the ability that has block and cancel flags
	 * @param RequestingAbility The gameplay ability requesting the change, can be NULL for native events
	 * @param bEnableBlockTags If true will enable the block tags, if false will disable the block tags
	 * @param BlockTags What tags to block
	 * @param bExecuteCancelTags If true will cancel abilities matching tags
	 * @param CancelTags what tags to cancel
	 */
	 /**
  * 능력 활성화 또는 네이티브 코드에서 호출되며, 올바른 능력 차단 태그를 적용하고 기존 능력을 취소합니다. 하위 클래스에서 동작을 재정의할 수 있습니다.
  *
  * @param AbilityTags 차단 및 취소 플래그가 있는 능력의 태그
  * @param RequestingAbility 변경을 요청하는 게임플레이 능력, 네이티브 이벤트의 경우 NULL일 수 있음
  * @param bEnableBlockTags true이면 차단 태그를 활성화하고, false이면 차단 태그를 비활성화합니다.
  * @param BlockTags 차단할 태그
  * @param bExecuteCancelTags true이면 태그와 일치하는 능력을 취소합니다.
  * @param CancelTags 취소할 태그
  */
	virtual void ApplyAbilityBlockAndCancelTags(const FGameplayTagContainer& AbilityTags, UGameplayAbility* RequestingAbility, bool bEnableBlockTags, const FGameplayTagContainer& BlockTags, bool bExecuteCancelTags, const FGameplayTagContainer& CancelTags);

	/** Called when an ability is cancellable or not. Doesn't do anything by default, can be overridden to tie into gameplay events */
	/** 능력이 취소 가능하거나 그렇지 않은 경우 호출됩니다. 기본적으로 아무 것도 하지 않으며, 게임플레이 이벤트에 연결되도록 재정의할 수 있습니다. */
	virtual void HandleChangeAbilityCanBeCanceled(const FGameplayTagContainer& AbilityTags, UGameplayAbility* RequestingAbility, bool bCanBeCanceled) {}

	/** Returns true if any passed in tags are blocked */
	/** 전달된 태그가 차단된 경우 true를 반환합니다. */
	virtual bool AreAbilityTagsBlocked(const FGameplayTagContainer& Tags) const;

	/** Block or cancel blocking for specific ability tags */
	/** 특정 능력 태그에 대한 차단 또는 차단 해제를 수행합니다. */
	void BlockAbilitiesWithTags(const FGameplayTagContainer& Tags);
	void UnBlockAbilitiesWithTags(const FGameplayTagContainer& Tags);

	/** Checks if the ability system is currently blocking InputID. Returns true if InputID is blocked, false otherwise.  */
	/** 능력 시스템이 현재 InputID를 차단 중인지 확인합니다. InputID가 차단되었으면 true를 반환하고, 그렇지 않으면 false를 반환합니다. */
	bool IsAbilityInputBlocked(int32 InputID) const;

	/** Block or cancel blocking for specific input IDs */
	/** 특정 입력 ID에 대한 차단 또는 차단 해제를 수행합니다. */
	void BlockAbilityByInputID(int32 InputID);
	void UnBlockAbilityByInputID(int32 InputID);

	// ----------------------------------------------------------------------------------------------------------------
	// Functions meant to be called from GameplayAbility and subclasses, but not meant for general use
	// GameplayAbility 및 하위 클래스에서 호출되지만 일반 사용을 위해서는 의도되지 않은 함수들
	// ----------------------------------------------------------------------------------------------------------------

	/** Returns the list of all activatable abilities. Read-only. */
	/** 활성화 가능한 모든 능력의 목록을 반환합니다. 읽기 전용. */
	const TArray<FGameplayAbilitySpec>& GetActivatableAbilities() const
	{
		return ActivatableAbilities.Items;
	}

	/** Returns the list of all activatable abilities. */
	/** 활성화 가능한 모든 능력의 목록을 반환합니다. */
	TArray<FGameplayAbilitySpec>& GetActivatableAbilities()
	{
		return ActivatableAbilities.Items;
	}

	/** Returns local world time that an ability was activated. Valid on authority (server) and autonomous proxy (controlling client).  */
	/** 능력이 활성화된 로컬 월드 시간을 반환합니다. 서버 및 자율 프록시(제어 클라이언트)에서 유효합니다. */
	float GetAbilityLastActivatedTime() const { return AbilityLastActivatedTime; }

	/** Returns an ability spec from a handle. If modifying call MarkAbilitySpecDirty */
	/** 핸들에서 ability spec을 반환합니다. 수정하는 경우 MarkAbilitySpecDirty를 호출하십시오. */
	FGameplayAbilitySpec* FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle) const;
	
	/** Returns an ability spec from a GE handle. If modifying call MarkAbilitySpecDirty */
	/** GE 핸들에서 능력 스펙을 반환합니다. 수정하는 경우 MarkAbilitySpecDirty를 호출하십시오. */
	UE_DEPRECATED(5.3, "FindAbilitySpecFromGEHandle was never accurate because a GameplayEffect can grant multiple GameplayAbilities. It now returns nullptr.")
	FGameplayAbilitySpec* FindAbilitySpecFromGEHandle(FActiveGameplayEffectHandle Handle) const;

	/** Returns an ability spec corresponding to given ability class. If modifying call MarkAbilitySpecDirty */
	/** 주어진 능력 클래스에 해당하는 능력 스펙을 반환합니다. 수정하는 경우 MarkAbilitySpecDirty를 호출하십시오. */
	FGameplayAbilitySpec* FindAbilitySpecFromClass(TSubclassOf<UGameplayAbility> InAbilityClass) const;

	/** Returns an ability spec from a handle. If modifying call MarkAbilitySpecDirty */
	/** 핸들에서 능력 스펙을 반환합니다. 수정하는 경우 MarkAbilitySpecDirty를 호출하십시오. */
	FGameplayAbilitySpec* FindAbilitySpecFromInputID(int32 InputID) const;

	/**
	 * Returns all abilities with the given InputID
	 *
	 * @param InputID The Input ID to match
	 * @param OutAbilitySpecs Array of pointers to matching specs
	 */
	 /**
  * 주어진 InputID와 일치하는 모든 능력을 반환합니다.
  *
  * @param InputID 일치할 Input ID
  * @param OutAbilitySpecs 일치하는 스펙의 포인터 배열
  */
	virtual void FindAllAbilitySpecsFromInputID(int32 InputID, TArray<const FGameplayAbilitySpec*>& OutAbilitySpecs) const;

	/**
	 * Build a simple FGameplayAbilitySpec from class, level and optional Input ID
	 */
	 /**
	* 클래스, 레벨 및 선택적 Input ID에서 간단한 FGameplayAbilitySpec을 작성합니다.
	 */
	virtual FGameplayAbilitySpec BuildAbilitySpecFromClass(TSubclassOf<UGameplayAbility> AbilityClass, int32 Level = 0, int32 InputID = -1);

	/**
	 * Returns an array with all granted ability handles
	 * NOTE: currently this doesn't include abilities that are mid-activation
	 * 
	 * @param OutAbilityHandles This array will be filled with the granted Ability Spec Handles
	 */
	 /**
  * 부여된 모든 능력 핸들을 포함하는 배열을 반환합니다.
  * 참고: 현재 이 배열에는 활성화 중인 능력이 포함되지 않습니다.
  *
  * @param OutAbilityHandles 이 배열은 부여된 능력 스펙 핸들로 채워집니다.
  */
	UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Gameplay Abilities")
	void GetAllAbilities(TArray<FGameplayAbilitySpecHandle>& OutAbilityHandles) const;

	/**
	 * Returns an array with all abilities that match the provided tags
	 *
	 * @param OutAbilityHandles This array will be filled with matching Ability Spec Handles
	 * @param Tags Gameplay Tags to match
	 * @param bMatchAll If true, tags must be matched exactly. Otherwise, abilities matching any of the tags will be returned
	 */
	UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Gameplay Abilities")
	void FindAllAbilitiesWithTags(TArray<FGameplayAbilitySpecHandle>& OutAbilityHandles, FGameplayTagContainer Tags, bool bExactMatch = true) const;

	/**
	 * Returns an array with all abilities that match the provided Gameplay Tag Query
	 *
	 * @param OutAbilityHandles This array will be filled with matching Ability Spec Handles
	 * @param Query Gameplay Tag Query to match
	 */
	 /**
  * 제공된 태그와 일치하는 모든 능력을 포함하는 배열을 반환합니다.
  *
  * @param OutAbilityHandles 이 배열은 일치하는 능력 스펙 핸들로 채워집니다.
  * @param Tags 일치할 게임플레이 태그
  * @param bExactMatch true이면 태그가 정확히 일치해야 합니다. 그렇지 않으면 태그 중 하나와 일치하는 능력을 반환합니다.
  */
	UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Gameplay Abilities")
	void FindAllAbilitiesMatchingQuery(TArray<FGameplayAbilitySpecHandle>& OutAbilityHandles, FGameplayTagQuery Query) const;

	/**
	 * Returns an array with all abilities bound to an Input ID value
	 *
	 * @param OutAbilityHandles This array will be filled with matching Ability Spec Handles
	 * @param InputID The Input ID to match
	 */
	 /**
  * 입력 ID 값에 바인딩된 모든 능력을 반환합니다.
  *
  * @param OutAbilityHandles 일치하는 능력 사양 핸들로 채워질 배열
  * @param InputID 일치시킬 입력 ID
  */
	UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Gameplay Abilities")
	void FindAllAbilitiesWithInputID(TArray<FGameplayAbilitySpecHandle>& OutAbilityHandles, int32 InputID = 0) const;

	/** Retrieves the EffectContext of the GameplayEffect of the active GameplayEffect. */
	/** 활성화된 게임플레이 효과의 효과 컨텍스트를 검색합니다. */
	FGameplayEffectContextHandle GetEffectContextFromActiveGEHandle(FActiveGameplayEffectHandle Handle);

	/** Call to mark that an ability spec has been modified */
	/** 능력 사양이 수정되었음을 표시하기 위해 호출 */
	void MarkAbilitySpecDirty(FGameplayAbilitySpec& Spec, bool WasAddOrRemove=false);

	/** Attempts to activate the given ability, will only work if called from the correct client/server context */
	/** 지정된 능력을 활성화하려고 시도합니다. 이는 올바른 클라이언트/서버 컨텍스트에서 호출된 경우에만 작동합니다. */
	bool InternalTryActivateAbility(FGameplayAbilitySpecHandle AbilityToActivate, FPredictionKey InPredictionKey = FPredictionKey(), UGameplayAbility ** OutInstancedAbility = nullptr, FOnGameplayAbilityEnded::FDelegate* OnGameplayAbilityEndedDelegate = nullptr, const FGameplayEventData* TriggerEventData = nullptr);

	/** Failure tags used by InternalTryActivateAbility (E.g., this stores the  FailureTags of the last call to InternalTryActivateAbility */
	/** InternalTryActivateAbility에서 사용된 실패 태그(예: InternalTryActivateAbility 호출의 실패 태그를 저장) */
	FGameplayTagContainer InternalTryActivateAbilityFailureTags;

	/** Called from the ability to let the component know it is ended */
	/** 능력이 종료되었음을 컴포넌트에 알리기 위해 능력에서 호출됨 */
	virtual void NotifyAbilityEnded(FGameplayAbilitySpecHandle Handle, UGameplayAbility* Ability, bool bWasCancelled);

	void ClearAbilityReplicatedDataCache(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActivationInfo& ActivationInfo);

	/** Called from FScopedAbilityListLock */
	/** FScopedAbilityListLock에서 호출됨 */
	void IncrementAbilityListLock();
	void DecrementAbilityListLock();

	// ----------------------------------------------------------------------------------------------------------------
	// Debugging
	// ----------------------------------------------------------------------------------------------------------------

	struct FAbilitySystemComponentDebugInfo
	{
		FAbilitySystemComponentDebugInfo()
		{
			FMemory::Memzero(*this);
		}

		class UCanvas* Canvas;

		bool bPrintToLog;

		bool bShowAttributes;
		bool bShowGameplayEffects;;
		bool bShowAbilities;

		float XPos;
		float YPos;
		float OriginalX;
		float OriginalY;
		float MaxY;
		float NewColumnYPadding;
		float YL;

		bool Accumulate;
		TArray<FString>	Strings;

		int32 GameFlags; // arbitrary flags for games to set/read in Debug_Internal
	};

	static void OnShowDebugInfo(AHUD* HUD, UCanvas* Canvas, const FDebugDisplayInfo& DisplayInfo, float& YL, float& YPos);

	virtual void DisplayDebug(class UCanvas* Canvas, const class FDebugDisplayInfo& DebugDisplay, float& YL, float& YPos);
	virtual void PrintDebug();

	void AccumulateScreenPos(FAbilitySystemComponentDebugInfo& Info);
	virtual void Debug_Internal(struct FAbilitySystemComponentDebugInfo& Info);
	void DebugLine(struct FAbilitySystemComponentDebugInfo& Info, FString Str, float XOffset, float YOffset, int32 MinTextRowsToAdvance = 0);
	FString CleanupName(FString Str);

	/** Print a debug list of all gameplay effects */
	/** 모든 게임플레이 효과의 디버그 목록을 출력합니다. */
	void PrintAllGameplayEffects() const;

	/** Ask the server to send ability system debug information back to the client, via ClientPrintDebug_Response  */
	/** 서버에 클라이언트로 디버그 정보를 보내달라고 요청합니다. 결과는 ClientPrintDebug_Response를 통해 전달됩니다. */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerPrintDebug_Request();

	/** Same as ServerPrintDebug_Request but this includes the client debug strings so that the server can embed them in replays */
	/** ServerPrintDebug_Request와 동일하지만 클라이언트 디버그 문자열도 포함하여 서버가 재생에 포함할 수 있도록 합니다. */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerPrintDebug_RequestWithStrings(const TArray<FString>& Strings);

	/** Virtual function games can override to do their own stuff when either ServerPrintDebug function runs on the server */
	/** 게임에서 ServerPrintDebug 함수가 서버에서 실행될 때 자체 작업을 수행하도록 오버라이드할 수 있는 가상 함수 */
	virtual void OnServerPrintDebug_Request();

	/** Determines whether to call ServerPrintDebug_Request or ServerPrintDebug_RequestWithStrings.   */
	/** ServerPrintDebug_Request 또는 ServerPrintDebug_RequestWithStrings를 호출할지 여부를 결정합니다. */
	virtual bool ShouldSendClientDebugStringsToServer() const;

	UFUNCTION(Client, reliable)
	void ClientPrintDebug_Response(const TArray<FString>& Strings, int32 GameFlags);
	virtual void OnClientPrintDebug_Response(const TArray<FString>& Strings, int32 GameFlags);

#if ENABLE_VISUAL_LOG
	void ClearDebugInstantEffects();
#endif // ENABLE_VISUAL_LOG

	UE_DEPRECATED(4.26, "This will be made private in future engine versions. Use SetClientDebugStrings, GetClientDebugStrings, or GetClientDebugStrings_Mutable instead.")
	UPROPERTY(ReplicatedUsing=OnRep_ClientDebugString)
	TArray<FString>	ClientDebugStrings;

	void SetClientDebugStrings(TArray<FString>&& NewClientDebugStrings);
	TArray<FString>& GetClientDebugStrings_Mutable();
	const TArray<FString>& GetClientDebugStrings() const;

	UE_DEPRECATED(4.26, "This will be made private in future engine versions. Use SetServerDebugStrings, GetServerDebugStrings, or GetServerDebugStrings_Mutable instead.")
	UPROPERTY(ReplicatedUsing=OnRep_ServerDebugString)
	TArray<FString>	ServerDebugStrings;

	void SetServerDebugStrings(TArray<FString>&& NewServerDebugStrings);
	TArray<FString>& GetServerDebugStrings_Mutable();
	const TArray<FString>& GetServerDebugStrings() const;

	UFUNCTION()
	virtual void OnRep_ClientDebugString();

	UFUNCTION()
	virtual void OnRep_ServerDebugString();

	// ----------------------------------------------------------------------------------------------------------------
	// Batching client->server RPCs
	// This is a WIP feature to batch up client->server communication. It is opt in and not complete. It only batches the below functions. Other Server RPCs are not safe to call during a batch window. Only opt in if you know what you are doing!
	// 클라이언트에서 서버로의 RPC 일괄 처리
	// 이 기능은 클라이언트에서 서버로의 통신을 일괄 처리하기 위한 기능입니다. 
	// 현재 작업 중이며 선택 사항이며 완전히 구현되지 않았습니다. 아래 함수들만 일괄 처리합니다. 다른 서버 RPC는 일괄 처리 창 동안 안전하게 호출할 수 없습니다. 
	// 이 기능은 사용하기 전에 반드시 사용 방법을 숙지해야 합니다!
	// 
	//  ----------------------------------------------------------------------------------------------------------------	

	void CallServerTryActivateAbility(FGameplayAbilitySpecHandle AbilityToActivate, bool InputPressed, FPredictionKey PredictionKey);
	void CallServerSetReplicatedTargetData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, const FGameplayAbilityTargetDataHandle& ReplicatedTargetDataHandle, FGameplayTag ApplicationTag, FPredictionKey CurrentPredictionKey);
	void CallServerEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo ActivationInfo, FPredictionKey PredictionKey);

	virtual bool ShouldDoServerAbilityRPCBatch() const { return false; }
	virtual void BeginServerAbilityRPCBatch(FGameplayAbilitySpecHandle AbilityHandle);
	virtual void EndServerAbilityRPCBatch(FGameplayAbilitySpecHandle AbilityHandle);

	/** Accumulated client side data that is batched out to server on EndServerAbilityRPCBatch */
	TArray<FServerAbilityRPCBatch, TInlineAllocator<1> > LocalServerAbilityRPCBatchData;

	UFUNCTION(Server, reliable, WithValidation)
	void	ServerAbilityRPCBatch(FServerAbilityRPCBatch BatchInfo);

	// Overridable function for sub classes
	virtual void ServerAbilityRPCBatch_Internal(FServerAbilityRPCBatch& BatchInfo);

	// ----------------------------------------------------------------------------------------------------------------
	//	Input handling/targeting
	// ----------------------------------------------------------------------------------------------------------------	

	/**
	 * This is meant to be used to inhibit activating an ability from an input perspective. (E.g., the menu is pulled up, another game mechanism is consuming all input, etc)
	 * This should only be called on locally owned players.
	 * This should not be used to game mechanics like silences or disables. Those should be done through gameplay effects.
	 * 이 함수는 입력 관점에서 능력 활성화를 금지하기 위해 사용됩니다. (예: 메뉴가 열린 상태, 다른 게임 메커니즘이 모든 입력을 소비 중인 경우 등)
 * 이 함수는 로컬 플레이어에 대해서만 호출해야 합니다.
 * 이 함수는 침묵(silence)이나 비활성(disable)과 같은 게임 메커니즘에 사용해서는 안 됩니다. 해당 기능은 게임플레이 이펙트를 통해 구현되어야 합니다.
	 */

	UFUNCTION(BlueprintCallable, Category="Abilities")
	bool GetUserAbilityActivationInhibited() const;
	
	/** Disable or Enable a local user from being able to activate abilities. This should only be used for input/UI etc related inhibition. Do not use for game mechanics. */
	/**
	* 사용자의 능력 활성화를 비활성화하거나 활성화합니다. 이 함수는 입력/UI 관련 제한에만 사용해야 합니다. 게임 메커니즘에는 사용해서는 안 됩니다.
	*/
	UFUNCTION(BlueprintCallable, Category="Abilities")
	virtual void SetUserAbilityActivationInhibited(bool NewInhibit);

	/** Rather activation is currently inhibited */
	/** 현재 활성화가 금지된 상태인지 여부 */
	UPROPERTY()
	bool UserAbilityActivationInhibited;

	/** When enabled GameplayCue RPCs will be routed through the AvatarActor's IAbilitySystemReplicationProxyInterface rather than this component */
	/** 이 옵션이 활성화되면 GameplayCue RPC는 이 컴포넌트 대신 AvatarActor의 IAbilitySystemReplicationProxyInterface를 통해 라우팅됩니다. */
	UPROPERTY()
	bool ReplicationProxyEnabled;

	/** Suppress all ability granting through GEs on this component */
	/** 이 컴포넌트에서 게임플레이 이펙트를 통한 모든 능력 부여를 억제합니다. */
	UPROPERTY()
	bool bSuppressGrantAbility;

	/** Suppress all GameplayCues on this component */
	/** 이 컴포넌트에서 모든 GameplayCue를 억제합니다. */
	UPROPERTY()
	bool bSuppressGameplayCues;

	/** List of currently active targeting actors */
	/** 현재 활성화된 타겟 액터의 목록 */
	UPROPERTY()
	TArray<TObjectPtr<AGameplayAbilityTargetActor>> SpawnedTargetActors;

	/** Bind to an input component with some default action names */
	/** 기본 작업 이름을 사용하여 입력 컴포넌트에 바인딩합니다. */
	virtual void BindToInputComponent(UInputComponent* InputComponent);

	/** Bind to an input component with customized bindings */
	/** 사용자 정의된 바인딩으로 입력 컴포넌트에 능력 활성화를 바인딩합니다. */
	virtual void BindAbilityActivationToInputComponent(UInputComponent* InputComponent, FGameplayAbilityInputBinds BindInfo);

	/** Initializes BlockedAbilityBindings variable */
	/** BlockedAbilityBindings 변수를 초기화하는 데 사용됩니다. */
	virtual void SetBlockAbilityBindingsArray(FGameplayAbilityInputBinds BindInfo);

	/** Called to handle ability bind input */
	/** 능력 바인드 입력을 처리하기 위해 호출됩니다. */
	virtual void AbilityLocalInputPressed(int32 InputID);
	virtual void AbilityLocalInputReleased(int32 InputID);

	/*
	 * Sends a local player Input Pressed event with the provided Input ID, notifying any bound abilities
	 *
	 * @param InputID The Input ID to match
	 */
	 /*
  * 특정 입력 ID와 함께 로컬 플레이어 입력 Pressed 이벤트를 보내어 바인드된 능력들에게 알립니다.
  *
  * @param InputID 매치할 입력 ID
  */
	UFUNCTION(BlueprintCallable, Category = "Gameplay Abilities")
	void PressInputID(int32 InputID);

	/**
	 * Sends a local player Input Released event with the provided Input ID, notifying any bound abilities
	 * @param InputID The Input ID to match
	 */
	 /**
  * 특정 입력 ID와 함께 로컬 플레이어 입력 Released 이벤트를 보내어 바인드된 능력들에게 알립니다.
  * @param InputID 매치할 입력 ID
  */
	UFUNCTION(BlueprintCallable, Category = "Gameplay Abilities")
	void ReleaseInputID(int32 InputID);

	/** Handle confirm/cancel for target actors */
	/** 타겟 액터의 Confirm/Cancel 처리 */
	virtual void LocalInputConfirm();
	virtual void LocalInputCancel();

	/**
	 * Sends a local player Input Confirm event, notifying abilities
	 */
	 /**
	* 로컬 플레이어 입력 Confirm 이벤트를 보내어 능력에게 알립니다.
	*/
	UFUNCTION(BlueprintCallable, Category = "Gameplay Abilities")
	void InputConfirm();

	/**
	 * Sends a local player Input Cancel event, notifying abilities
	 */
	 /**
  * 로컬 플레이어 입력 Cancel 이벤트를 보내어 능력에게 알립니다.
  */
	UFUNCTION(BlueprintCallable, Category = "Gameplay Abilities")
	void InputCancel();
	
	/** InputID for binding GenericConfirm/Cancel events */
	/** GenericConfirm/Cancel 이벤트를 바인딩할 입력 ID */
	int32 GenericConfirmInputID;
	int32 GenericCancelInputID;

	bool IsGenericConfirmInputBound(int32 InputID) const	{ return ((InputID == GenericConfirmInputID) && GenericLocalConfirmCallbacks.IsBound()); }
	bool IsGenericCancelInputBound(int32 InputID) const		{ return ((InputID == GenericCancelInputID) && GenericLocalCancelCallbacks.IsBound()); }

	/** Generic local callback for generic ConfirmEvent that any ability can listen to */
	/** 어떤 능력이든 들을 수 있는 일반적인 Confirm 이벤트에 대한 로컬 콜백 */
	FAbilityConfirmOrCancel	GenericLocalConfirmCallbacks;

	/** Generic local callback for generic CancelEvent that any ability can listen to */
	/** 어떤 능력이든 들을 수 있는 일반적인 Cancel 이벤트에 대한 로컬 콜백 */
	FAbilityConfirmOrCancel	GenericLocalCancelCallbacks;

	/** Any active targeting actors will be told to stop and return current targeting data */
	/** 모든 활성 타겟 액터들에게 현재 타겟팅 데이터를 반환하도록 지시합니다. */
	UFUNCTION(BlueprintCallable, Category = "Abilities")
	virtual void TargetConfirm();

	/** Any active targeting actors will be stopped and canceled, not returning any targeting data */
	UFUNCTION(BlueprintCallable, Category = "Abilities")
	/** 모든 활성 타겟 액터들을 중지하고 취소하며, 타겟팅 데이터를 반환하지 않습니다. */
	virtual void TargetCancel();

	// ----------------------------------------------------------------------------------------------------------------
	//	AnimMontage Support
	// ----------------------------------------------------------------------------------------------------------------	

	/** Plays a montage and handles replication and prediction based on passed in ability/activation info */
	/** 전달된 능력/활성화 정보에 따라 몽타주를 재생하고 복제 및 예측을 처리합니다. */
	virtual float PlayMontage(UGameplayAbility* AnimatingAbility, FGameplayAbilityActivationInfo ActivationInfo, UAnimMontage* Montage, float InPlayRate, FName StartSectionName = NAME_None, float StartTimeSeconds = 0.0f);

	/** Plays a montage without updating replication/prediction structures. Used by simulated proxies when replication tells them to play a montage. */
	/** 복제/예측 구조를 업데이트하지 않고 몽타주를 재생합니다. 복제가 몽타주를 재생하라고 지시할 때 시뮬레이션된 프록시에서 사용됩니다. */
	virtual float PlayMontageSimulated(UAnimMontage* Montage, float InPlayRate, FName StartSectionName = NAME_None);

	/** Stops whatever montage is currently playing. Expectation is caller should only be stopping it if they are the current animating ability (or have good reason not to check) */
	/** 현재 재생 중인 몽타주를 중지합니다. 호출자는 현재 애니메이션 능력인 경우에만 중지해야 합니다 (또는 확인하지 않아도 되는 충분한 이유가 있는 경우). */
	virtual void CurrentMontageStop(float OverrideBlendOutTime = -1.0f);

	/** Stops current montage if it's the one given as the Montage param */
	/** 주어진 몽타주 매개변수와 동일한 경우 현재 몽타주를 중지합니다. */
	virtual void StopMontageIfCurrent(const UAnimMontage& Montage, float OverrideBlendOutTime = -1.0f);

	/** Clear the animating ability that is passed in, if it's still currently animating */
	/** 여전히 현재 애니메이션 중인 경우 전달된 애니메이션 능력을 지웁니다. */
	virtual void ClearAnimatingAbility(UGameplayAbility* Ability);

	/** Jumps current montage to given section. Expectation is caller should only be stopping it if they are the current animating ability (or have good reason not to check) */
	/** 현재 몽타주를 주어진 섹션으로 점프합니다. 호출자는 현재 애니메이션 능력인 경우에만 점프해야 합니다 (또는 확인하지 않아도 되는 충분한 이유가 있는 경우). */
	virtual void CurrentMontageJumpToSection(FName SectionName);

	/** Sets current montages next section name. Expectation is caller should only be stopping it if they are the current animating ability (or have good reason not to check) */
	/** 현재 몽타주의 다음 섹션 이름을 설정합니다. 호출자는 현재 애니메이션 능력인 경우에만 설정해야 합니다 (또는 확인하지 않아도 되는 충분한 이유가 있는 경우). */
	virtual void CurrentMontageSetNextSectionName(FName FromSectionName, FName ToSectionName);

	/** Sets current montage's play rate */
	/** 현재 몽타주의 재생 속도를 설정합니다. */
	virtual void CurrentMontageSetPlayRate(float InPlayRate);

	/** Returns true if the passed in ability is the current animating ability */
	/** 전달된 능력이 현재 애니메이션 능력인지 여부를 반환합니다. */
	bool IsAnimatingAbility(UGameplayAbility* Ability) const;

	/** Returns the current animating ability */
	/** 현재 애니메이션 중인 능력을 반환합니다. */
	UGameplayAbility* GetAnimatingAbility();

	/** Returns montage that is currently playing */
	/** 현재 재생 중인 몽타주를 반환합니다. */
	UAnimMontage* GetCurrentMontage() const;

	/** Get SectionID of currently playing AnimMontage */
	/** 현재 재생 중인 애니메이션 몽타주의 섹션 ID를 가져옵니다. */
	int32 GetCurrentMontageSectionID() const;

	/** Get SectionName of currently playing AnimMontage */
	/** 현재 재생 중인 애니메이션 몽타주의 섹션 이름을 가져옵니다. */
	FName GetCurrentMontageSectionName() const;

	/** Get length in time of current section */
	/** 현재 섹션의 시간을 가져옵니다. */
	float GetCurrentMontageSectionLength() const;

	/** Returns amount of time left in current section */
	/** 현재 섹션에서 남은 시간을 반환합니다. */
	float GetCurrentMontageSectionTimeLeft() const;

	/** Method to set the replication method for the position in the montage */
	/** 몽타주에서 애니메이션 위치의 복제 방법을 설정하는 메서드입니다. */
	void SetMontageRepAnimPositionMethod(ERepAnimPositionMethod InMethod);

	// ----------------------------------------------------------------------------------------------------------------
	//	Actor interaction
	// ----------------------------------------------------------------------------------------------------------------	

private:

	/** The actor that owns this component logically */
	/** 논리적으로 이 컴포넌트를 소유하는 액터 */
	UPROPERTY(ReplicatedUsing = OnRep_OwningActor)
	TObjectPtr<AActor> OwnerActor;

	/** The actor that is the physical representation used for abilities. Can be NULL */
		/** 능력에 사용되는 물리적 표현의 액터. NULL일 수 있음 */
	UPROPERTY(ReplicatedUsing = OnRep_OwningActor)
	TObjectPtr<AActor> AvatarActor;

public:

	void SetOwnerActor(AActor* NewOwnerActor);
	AActor* GetOwnerActor() const { return OwnerActor; }

	void SetAvatarActor_Direct(AActor* NewAvatarActor);
	AActor* GetAvatarActor_Direct() const { return AvatarActor; }
	
	UFUNCTION()
	void OnRep_OwningActor();

	UFUNCTION()
	void OnAvatarActorDestroyed(AActor* InActor);

	UFUNCTION()
	void OnOwnerActorDestroyed(AActor* InActor);

	UFUNCTION()
	void OnSpawnedAttributesEndPlayed(AActor* InActor, EEndPlayReason::Type EndPlayReason);

	/** Cached off data about the owning actor that abilities will need to frequently access (movement component, mesh component, anim instance, etc) */
	/** 능력이 자주 접근해야 하는 소유 액터에 대한 캐시된 데이터 (이동 컴포넌트, 메쉬 컴포넌트, 애니메이션 인스턴스 등) */
	TSharedPtr<FGameplayAbilityActorInfo>	AbilityActorInfo;

	/**
	 *	Initialized the Abilities' ActorInfo - the structure that holds information about who we are acting on and who controls us.
	 *      OwnerActor is the actor that logically owns this component.
	 *		AvatarActor is what physical actor in the world we are acting on. Usually a Pawn but it could be a Tower, Building, Turret, etc, may be the same as Owner
	 */
	 /**
  *	능력의 ActorInfo를 초기화합니다 - 우리가 누구에게 작용하고 누가 우리를 제어하는지에 대한 정보를 담고 있는 구조체.
  *		OwnerActor는 논리적으로 이 컴포넌트를 소유하는 액터입니다.
  *		AvatarActor는 우리가 물리적으로 작용하는 월드의 액터입니다. 보통은 Pawn이지만 타워, 건물, 터렛 등일 수 있으며, Owner와 동일할 수 있습니다.
  */
	virtual void InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor);

	/** Returns avatar actor to be used for a specific task, normally GetAvatarActor */
		/** 특정 작업에 사용되는 아바타 액터를 반환합니다. 보통은 GetAvatarActor를 호출합니다. */
	virtual AActor* GetGameplayTaskAvatar(const UGameplayTask* Task) const override;

	/** Returns the avatar actor for this component */
	/** 아바타 액터를 변경하며, 소유 액터는 동일하게 유지합니다. */
	AActor* GetAvatarActor() const;

	/** Changes the avatar actor, leaves the owner actor the same */
	void SetAvatarActor(AActor* InAvatarActor);

	/** called when the ASC's AbilityActorInfo has a PlayerController set. */
	/** ASC의 AbilityActorInfo에 PlayerController가 설정되었을 때 호출됩니다. */
	virtual void OnPlayerControllerSet() { }

	/**
	* This is called when the actor that is initialized to this system dies, this will clear that actor from this system and FGameplayAbilityActorInfo
	*/
	/**
	* 초기화된 시스템에 연결된 액터가 죽었을 때 호출되며, 이 시스템 및 FGameplayAbilityActorInfo에서 해당 액터를 제거합니다.
	*/
	virtual void ClearActorInfo();

	/**
	 *	This will refresh the Ability's ActorInfo structure based on the current ActorInfo. That is, AvatarActor will be the same but we will look for new
	 *	AnimInstance, MovementComponent, PlayerController, etc.
	 */	
	 /**
	  *	현재 ActorInfo를 기반으로 Ability의 ActorInfo 구조체를 새로 고칩니다. 즉, AvatarActor는 동일하지만 새로운 AnimInstance, MovementComponent, PlayerController 등을 찾습니다.
	  */
	void RefreshAbilityActorInfo();

	// ----------------------------------------------------------------------------------------------------------------
	//	Synchronization RPCs
	//  While these appear to be state, these are actually synchronization events w/ some payload data
	// 	동기화 RPC
	//  이것들은 상태처럼 보이지만, 실제로는 일부 페이로드 데이터를 포함한 동기화 이벤트입니다.
	// ----------------------------------------------------------------------------------------------------------------	

	
	/** Replicates the Generic Replicated Event to the server. */
		/** Generic Replicated Event를 서버에 복제합니다. */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerSetReplicatedEvent(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, FPredictionKey CurrentPredictionKey);

	/** Replicates the Generic Replicated Event to the server with payload. */
	/** 페이로드와 함께 Generic Replicated Event를 서버에 복제합니다. */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerSetReplicatedEventWithPayload(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, FPredictionKey CurrentPredictionKey, FVector_NetQuantize100 VectorPayload);

	/** Replicates the Generic Replicated Event to the client. */
	/** Generic Replicated Event를 클라이언트에 복제합니다. */
	UFUNCTION(Client, reliable)
	void ClientSetReplicatedEvent(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Calls local callbacks that are registered with the given Generic Replicated Event */
	/** 주어진 Generic Replicated Event와 등록된 로컬 콜백을 호출합니다. */
	bool InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, FPredictionKey CurrentPredictionKey = FPredictionKey());

	/** Calls local callbacks that are registered with the given Generic Replicated Event */
	/** 주어진 Generic Replicated Event와 등록된 로컬 콜백을 페이로드와 함께 호출합니다. */
	bool InvokeReplicatedEventWithPayload(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, FPredictionKey CurrentPredictionKey, FVector_NetQuantize100 VectorPayload);
	
	/** Replicates targeting data to the server */
	/** 타겟 데이터를 서버에 복제합니다. */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerSetReplicatedTargetData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, const FGameplayAbilityTargetDataHandle& ReplicatedTargetDataHandle, FGameplayTag ApplicationTag, FPredictionKey CurrentPredictionKey);

	/** Replicates to the server that targeting has been cancelled */
	/** 타겟팅이 취소되었음을 서버에 복제합니다. */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerSetReplicatedTargetDataCancelled(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, FPredictionKey CurrentPredictionKey);

	/** Sets the current target data and calls applicable callbacks */
	/** 현재 타겟 데이터를 설정하고 적용 가능한 콜백을 호출합니다. */
	virtual void ConfirmAbilityTargetData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, const FGameplayAbilityTargetDataHandle& TargetData, const FGameplayTag& ApplicationTag);

	/** Cancels the ability target data and calls callbacks */
	/** 능력 타겟 데이터를 취소하고 콜백을 호출합니다. */
	virtual void CancelAbilityTargetData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Deletes all cached ability client data (Was: ConsumeAbilityTargetData)*/
	/** 모든 캐시된 능력 클라이언트 데이터를 삭제합니다 (이전: ConsumeAbilityTargetData) */
	void ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);
	/** Consumes cached TargetData from client (only TargetData) */
	/** 클라이언트에서 복제된 타겟 데이터만 소비합니다. */

	void ConsumeClientReplicatedTargetData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Consumes the given Generic Replicated Event (unsets it). */
	/** 주어진 Generic Replicated Event를 소비합니다 (해제). */
	void ConsumeGenericReplicatedEvent(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Gets replicated data of the given Generic Replicated Event. */
	/** 주어진 Generic Replicated Event의 복제된 데이터를 가져옵니다. */

	FAbilityReplicatedData GetReplicatedDataOfGenericReplicatedEvent(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);
	
	/** Calls any Replicated delegates that have been sent (TargetData or Generic Replicated Events). Note this can be dangerous if multiple places in an ability register events and then call this function. */
	/** 보낸 모든 복제된 대리자를 호출합니다 (타겟 데이터 또는 Generic Replicated Events). 주의: 능력의 여러 위치에서 이벤트를 등록하고 이 함수를 호출하면 위험할 수 있습니다. */
	void CallAllReplicatedDelegatesIfSet(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Calls the TargetData Confirm/Cancel events if they have been sent. */
	/** 타겟 데이터 확인/취소 이벤트가 보내진 경우 호출합니다. */
	bool CallReplicatedTargetDataDelegatesIfSet(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Calls a given Generic Replicated Event delegate if the event has already been sent */
	/** 이벤트가 이미 보내진 경우 주어진 Generic Replicated Event 대리자를 호출합니다. */
	bool CallReplicatedEventDelegateIfSet(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Calls passed in delegate if the Client Event has already been sent. If not, it adds the delegate to our multicast callback that will fire when it does. */
	/** 클라이언트 이벤트가 이미 보내진 경우 전달된 대리자를 호출합니다. 그렇지 않은 경우, 이벤트가 보내졌을 때 실행될 멀티캐스트 콜백에 대리자를 추가합니다. */
	bool CallOrAddReplicatedDelegate(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey, FSimpleMulticastDelegate::FDelegate Delegate);

	/** Returns TargetDataSet delegate for a given Ability/PredictionKey pair */
	/** 주어진 능력/예측 키 쌍에 대한 TargetDataSet 대리자를 반환합니다. */
	FAbilityTargetDataSetDelegate& AbilityTargetDataSetDelegate(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Returns TargetData Cancelled delegate for a given Ability/PredictionKey pair */
	/** 주어진 능력/예측 키 쌍에 대한 TargetData Cancelled 대리자를 반환합니다. */
	FSimpleMulticastDelegate& AbilityTargetDataCancelledDelegate(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Returns Generic Replicated Event for a given Ability/PredictionKey pair */
	/** 주어진 능력/예측 키 쌍에 대한 Generic Replicated Event를 반환합니다. */
	FSimpleMulticastDelegate& AbilityReplicatedEventDelegate(EAbilityGenericReplicatedEvent::Type EventType, FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey AbilityOriginalPredictionKey);

	/** Direct Input state replication. These will be called if bReplicateInputDirectly is true on the ability and is generally not a good thing to use. (Instead, prefer to use Generic Replicated Events). */
	/** 직접 입력 상태 복제. 이들은 bReplicateInputDirectly가 능력에서 true인 경우 호출됩니다. 일반적으로 사용하지 않는 것이 좋습니다. (대신 Generic Replicated Events를 사용하는 것이 좋습니다). */
	UFUNCTION(Server, reliable, WithValidation)
	void ServerSetInputPressed(FGameplayAbilitySpecHandle AbilityHandle);

	UFUNCTION(Server, reliable, WithValidation)
	void ServerSetInputReleased(FGameplayAbilitySpecHandle AbilityHandle);

	/** Called on local player always. Called on server only if bReplicateInputDirectly is set on the GameplayAbility. */
	/** 항상 로컬 플레이어에서 호출됩니다. bReplicateInputDirectly가 GameplayAbility에서 설정된 경우에만 서버에서 호출됩니다. */
	virtual void AbilitySpecInputPressed(FGameplayAbilitySpec& Spec);

	/** Called on local player always. Called on server only if bReplicateInputDirectly is set on the GameplayAbility. */
	/** 항상 로컬 플레이어에서 호출됩니다. bReplicateInputDirectly가 GameplayAbility에서 설정된 경우에만 서버에서 호출됩니다. */
	virtual void AbilitySpecInputReleased(FGameplayAbilitySpec& Spec);

	// ----------------------------------------------------------------------------------------------------------------
	//  Component overrides
	// ----------------------------------------------------------------------------------------------------------------
	/** 컴포넌트를 초기화합니다. */
	virtual void InitializeComponent() override;
	/** 컴포넌트의 초기화를 해제합니다. */
	virtual void UninitializeComponent() override;
	/** 컴포넌트가 파괴될 때 호출됩니다. */
	virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
	/** 틱을 실행할지 여부를 반환합니다. */
	virtual bool GetShouldTick() const override;
	/** 컴포넌트의 틱을 처리합니다. */
	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
	/** 네트워킹을 위한 안정적인 이름을 가진 서브 객체들을 가져옵니다. */
	virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& Objs) override;
	/** 서브 객체들을 복제합니다. */
	virtual bool ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
	/** Force owning actor to update it's replication, to make sure that gameplay cues get sent down quickly. Override to change how aggressive this is */
	/** 소유하는 액터가 복제를 업데이트하도록 강제합니다. 게임플레이 큐가 빠르게 전송되도록 합니다. 공격성을 변경하려면 오버라이드하십시오. */
	virtual void ForceReplication() override;
	/** 네트워크 수신 전 호출됩니다. */
	virtual void PreNetReceive() override;
	/** 네트워크 수신 후 호출됩니다. */
	virtual void PostNetReceive() override;
	/** 컴포넌트가 등록될 때 호출됩니다. */
	virtual void OnRegister() override;
	/** 컴포넌트가 등록 해제될 때 호출됩니다. */
	virtual void OnUnregister() override;
	/** 복제를 위한 준비를 완료합니다. */
	virtual void ReadyForReplication() override;
	/** 게임이 시작될 때 호출됩니다. */
	virtual void BeginPlay() override;

protected:
	/** 복제된 속성을 설정합니다. */
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
	
	/** 사용자 정의 조건 상태의 복제된 속성을 가져옵니다. */
	virtual void GetReplicatedCustomConditionState(FCustomPropertyConditionState& OutActiveState) const override;
	/** 활성 게임플레이 효과 복제 조건을 업데이트합니다. */
	void UpdateActiveGameplayEffectsReplicationCondition();
	/** 최소 복제 게임플레이 큐 조건을 업데이트합니다. */
	void UpdateMinimalReplicationGameplayCuesCondition();

	/**
	 *	The abilities we can activate. 
	 *		-This will include CDOs for non instanced abilities and per-execution instanced abilities. 
	 *		-Actor-instanced abilities will be the actual instance (not CDO)
	 *		
	 *	This array is not vital for things to work. It is a convenience thing for 'giving abilities to the actor'. But abilities could also work on things
	 *	without an AbilitySystemComponent. For example an ability could be written to execute on a StaticMeshActor. As long as the ability doesn't require 
	 *	instancing or anything else that the AbilitySystemComponent would provide, then it doesn't need the component to function.
	 */
	 /**
  * 활성화할 수 있는 능력들입니다.
  * - 인스턴스화되지 않은 능력과 실행당 인스턴스화되는 능력의 CDO가 포함됩니다.
  * - 액터 인스턴스화된 능력은 실제 인스턴스가 됩니다 (CDO가 아님).
  *
  * 이 배열은 동작에 필수적이지 않습니다. 액터에 능력을 부여하는 편의 기능입니다. 그러나 AbilitySystemComponent 없이도 작동할 수 있습니다.
  * 예를 들어, 능력이 StaticMeshActor에서 실행되도록 작성될 수 있습니다. 능력이 인스턴싱이나 다른 AbilitySystemComponent가 제공하는 것을 필요로 하지 않는 한 컴포넌트가 없어도 기능할 수 있습니다.
  */
	UPROPERTY(ReplicatedUsing = OnRep_ActivateAbilities, BlueprintReadOnly, Transient, Category = "Abilities")
	FGameplayAbilitySpecContainer ActivatableAbilities;

	/** Maps from an ability spec to the target data. Used to track replicated data and callbacks */
	/** 능력 스펙에서 타겟 데이터를 매핑합니다. 복제된 데이터와 콜백을 추적하는 데 사용됩니다. */
	FGameplayAbilityReplicatedDataContainer AbilityTargetDataMap;

	/** List of gameplay tag container filters, and the delegates they call */
	/** 게임플레이 태그 컨테이너 필터 목록과 해당 대리자들 */
	TArray<TPair<FGameplayTagContainer, FGameplayEventTagMulticastDelegate>> GameplayEventTagContainerDelegates;

	/** Full list of all instance-per-execution gameplay abilities associated with this component */
	/** 이 컴포넌트와 관련된 모든 실행당 인스턴스화된 게임플레이 능력의 전체 목록 */
	UE_DEPRECATED(5.1, "This array will be made private. Use GetReplicatedInstancedAbilities, AddReplicatedInstancedAbility or RemoveReplicatedInstancedAbility instead.")
	UPROPERTY()
	TArray<TObjectPtr<UGameplayAbility>>	AllReplicatedInstancedAbilities;

	/** Full list of all instance-per-execution gameplay abilities associated with this component */
	/** 이 컴포넌트와 관련된 모든 실행당 인스턴스화된 게임플레이 능력의 전체 목록 */
	PRAGMA_DISABLE_DEPRECATION_WARNINGS
	const TArray<UGameplayAbility*>& GetReplicatedInstancedAbilities() const { return AllReplicatedInstancedAbilities; }
	PRAGMA_ENABLE_DEPRECATION_WARNINGS

	/** Add a gameplay ability associated to this component */
		/** 이 컴포넌트에 관련된 게임플레이 능력을 추가합니다. */
	void AddReplicatedInstancedAbility(UGameplayAbility* GameplayAbility);

	/** Remove a gameplay ability associated to this component */
	/** 이 컴포넌트에 관련된 게임플레이 능력을 제거합니다. */
	void RemoveReplicatedInstancedAbility(UGameplayAbility* GameplayAbility);

	/** Unregister all the gameplay abilities of this component */
	/** 이 컴포넌트의 모든 게임플레이 능력을 등록 해제합니다. */
	void RemoveAllReplicatedInstancedAbilities();

	/** Will be called from GiveAbility or from OnRep. Initializes events (triggers and inputs) with the given ability */
	/** GiveAbility 또는 OnRep에서 호출됩니다. 주어진 능력과 이벤트 (트리거 및 입력)를 초기화합니다. */
	virtual void OnGiveAbility(FGameplayAbilitySpec& AbilitySpec);

	/** Will be called from RemoveAbility or from OnRep. Unbinds inputs with the given ability */
	/** RemoveAbility 또는 OnRep에서 호출됩니다. 주어진 능력과 입력을 바인딩 해제합니다. */
	virtual void OnRemoveAbility(FGameplayAbilitySpec& AbilitySpec);

	/** Called from ClearAbility, ClearAllAbilities or OnRep. Clears any triggers that should no longer exist. */
	/** ClearAbility, ClearAllAbilities 또는 OnRep에서 호출됩니다. 더 이상 존재하지 않는 트리거를 제거합니다. */
	void CheckForClearedAbilities();

	/** Cancel a specific ability spec */
	/** 특정 능력 스펙을 취소합니다. */
	virtual void CancelAbilitySpec(FGameplayAbilitySpec& Spec, UGameplayAbility* Ignore);

	/** Creates a new instance of an ability, storing it in the spec */
	/** 능력의 새 인스턴스를 생성하여 스펙에 저장합니다. */
	virtual UGameplayAbility* CreateNewInstanceOfAbility(FGameplayAbilitySpec& Spec, const UGameplayAbility* Ability);

	int32 AbilityScopeLockCount;
	TArray<FGameplayAbilitySpecHandle, TInlineAllocator<2> > AbilityPendingRemoves;
	TArray<FGameplayAbilitySpec, TInlineAllocator<2> > AbilityPendingAdds;

	/** Local World time of the last ability activation. This is used for AFK/idle detection */
	/** 마지막 능력 활성화의 로컬 월드 시간입니다. 이것은 AFK/유휴 감지에 사용됩니다. */
	float AbilityLastActivatedTime;

	UFUNCTION()
	virtual void OnRep_ActivateAbilities();

	UFUNCTION(Server, reliable, WithValidation)
	void	ServerTryActivateAbility(FGameplayAbilitySpecHandle AbilityToActivate, bool InputPressed, FPredictionKey PredictionKey);

	UFUNCTION(Server, reliable, WithValidation)
	void	ServerTryActivateAbilityWithEventData(FGameplayAbilitySpecHandle AbilityToActivate, bool InputPressed, FPredictionKey PredictionKey, FGameplayEventData TriggerEventData);

	UFUNCTION(Client, reliable)
	void	ClientTryActivateAbility(FGameplayAbilitySpecHandle AbilityToActivate);

	/** Called by ServerEndAbility and ClientEndAbility; avoids code duplication. */
	void	RemoteEndOrCancelAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo ActivationInfo, bool bWasCanceled);

	UFUNCTION(Server, reliable, WithValidation)
	void	ServerEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo ActivationInfo, FPredictionKey PredictionKey);

	UFUNCTION(Client, reliable)
	void	ClientEndAbility(FGameplayAbilitySpecHandle AbilityToEnd, FGameplayAbilityActivationInfo ActivationInfo);

	UFUNCTION(Server, reliable, WithValidation)
	void    ServerCancelAbility(FGameplayAbilitySpecHandle AbilityToCancel, FGameplayAbilityActivationInfo ActivationInfo);

	UFUNCTION(Client, reliable)
	void    ClientCancelAbility(FGameplayAbilitySpecHandle AbilityToCancel, FGameplayAbilityActivationInfo ActivationInfo);

	UFUNCTION(Client, Reliable)
	void	ClientActivateAbilityFailed(FGameplayAbilitySpecHandle AbilityToActivate, int16 PredictionKey);
	int32	ClientActivateAbilityFailedCountRecent;
	float	ClientActivateAbilityFailedStartTime;

	
	void	OnClientActivateAbilityCaughtUp(FGameplayAbilitySpecHandle AbilityToActivate, FPredictionKey::KeyType PredictionKey);

	UFUNCTION(Client, Reliable)
	void	ClientActivateAbilitySucceed(FGameplayAbilitySpecHandle AbilityToActivate, FPredictionKey PredictionKey);

	UFUNCTION(Client, Reliable)
	void	ClientActivateAbilitySucceedWithEventData(FGameplayAbilitySpecHandle AbilityToActivate, FPredictionKey PredictionKey, FGameplayEventData TriggerEventData);

	/** Implementation of ServerTryActivateAbility */
	/** ServerTryActivateAbility의 구현 */
	virtual void InternalServerTryActivateAbility(FGameplayAbilitySpecHandle AbilityToActivate, bool InputPressed, const FPredictionKey& PredictionKey, const FGameplayEventData* TriggerEventData);

	/** Called when a prediction key that played a montage is rejected */
	/** 예측 몽타주가 거부될 때 호출됩니다 */
	void OnPredictiveMontageRejected(UAnimMontage* PredictiveMontage);

	/** Copy LocalAnimMontageInfo into RepAnimMontageInfo */
	/** LocalAnimMontageInfo를 RepAnimMontageInfo로 복사합니다 */
	void AnimMontage_UpdateReplicatedData();
	void AnimMontage_UpdateReplicatedData(FGameplayAbilityRepAnimMontage& OutRepAnimMontageInfo);

	/** Copy over playing flags for duplicate animation data */
	/** 중복 애니메이션 데이터에 대한 재생 플래그를 강제로 업데이트합니다 */
	void AnimMontage_UpdateForcedPlayFlags(FGameplayAbilityRepAnimMontage& OutRepAnimMontageInfo);

	UE_DEPRECATED(4.26, "This will be made private in future engine versions. Use SetRepAnimMontageInfo, GetRepAnimMontageInfo, or GetRepAnimMontageInfo_Mutable instead.")
	/** Data structure for replicating montage info to simulated clients */
	/** 클라이언트에 몽타주 정보를 복제하기 위한 데이터 구조 */
	UPROPERTY(ReplicatedUsing=OnRep_ReplicatedAnimMontage)
	FGameplayAbilityRepAnimMontage RepAnimMontageInfo;

	void SetRepAnimMontageInfo(const FGameplayAbilityRepAnimMontage& NewRepAnimMontageInfo);
	FGameplayAbilityRepAnimMontage& GetRepAnimMontageInfo_Mutable();
	const FGameplayAbilityRepAnimMontage& GetRepAnimMontageInfo() const;

	/** Cached value of rather this is a simulated actor */
	/** 시뮬레이션된 액터인지 여부를 캐시된 값 */
	UPROPERTY()
	bool bCachedIsNetSimulated;

	/** Set if montage rep happens while we don't have the animinstance associated with us yet */
	/** 애니메이션 인스턴스가 아직 연결되지 않았을 때 몽타주 복제가 발생했는지 설정 */
	UPROPERTY()
	bool bPendingMontageRep;

	/** Data structure for montages that were instigated locally (everything if server, predictive if client. replicated if simulated proxy) */
	/** 로컬에서 시작된 몽타주에 대한 데이터 구조 (서버에서는 모든 것, 클라이언트에서는 예측, 시뮬레이션된 프록시에서는 복제됨) */
	UPROPERTY()
	FGameplayAbilityLocalAnimMontage LocalAnimMontageInfo;

	UFUNCTION()
	virtual void OnRep_ReplicatedAnimMontage();

	/** Returns true if we are ready to handle replicated montage information */
	/** 복제된 몽타주 정보를 처리할 준비가 되었는지 반환합니다 */
	virtual bool IsReadyForReplicatedMontage();

	/** RPC function called from CurrentMontageSetNextSectopnName, replicates to other clients */
	/** CurrentMontageSetNextSectionName에서 호출되는 RPC 함수로, 다른 클라이언트에 복제됩니다 */
	UFUNCTION(reliable, server, WithValidation)
	void ServerCurrentMontageSetNextSectionName(UAnimMontage* ClientAnimMontage, float ClientPosition, FName SectionName, FName NextSectionName);

	/** RPC function called from CurrentMontageJumpToSection, replicates to other clients */
/** CurrentMontageJumpToSection에서 호출되는 RPC 함수로, 다른 클라이언트에 복제됩니다 */
	UFUNCTION(reliable, server, WithValidation)
	void ServerCurrentMontageJumpToSectionName(UAnimMontage* ClientAnimMontage, FName SectionName);

	/** RPC function called from CurrentMontageSetPlayRate, replicates to other clients */
	/** CurrentMontageSetPlayRate에서 호출되는 RPC 함수로, 다른 클라이언트에 복제됩니다 */
	UFUNCTION(reliable, server, WithValidation)
	void ServerCurrentMontageSetPlayRate(UAnimMontage* ClientAnimMontage, float InPlayRate);

	/** Abilities that are triggered from a gameplay event */
	/** 게임플레이 이벤트에서 트리거되는 능력들 */
	TMap<FGameplayTag, TArray<FGameplayAbilitySpecHandle > > GameplayEventTriggeredAbilities;

	/** Abilities that are triggered from a tag being added to the owner */
	/** 소유자에게 태그가 추가될 때 트리거되는 능력들 */
	TMap<FGameplayTag, TArray<FGameplayAbilitySpecHandle > > OwnedTagTriggeredAbilities;

	/** Callback that is called when an owned tag bound to an ability changes */
	/** 능력에 바인딩된 소유 태그가 변경될 때 호출되는 콜백 */
	virtual void MonitoredTagChanged(const FGameplayTag Tag, int32 NewCount);

	/** Returns true if the specified ability should be activated from an event in this network mode */
	/** 지정된 능력이 이 네트워크 모드에서 이벤트로부터 활성화되어야 하는지 여부를 반환합니다 */
	bool HasNetworkAuthorityToActivateTriggeredAbility(const FGameplayAbilitySpec &Spec) const;

	UE_DEPRECATED(5.3, "Use OnImmunityBlockGameplayEffectDelegate directly.  It is trigger from a UImmunityGameplayEffectComponent.  You can create your own GameplayEffectComponent if you need different functionality.")
	virtual void OnImmunityBlockGameplayEffect(const FGameplayEffectSpec& Spec, const FActiveGameplayEffect* ImmunityGE);

	// Internal gameplay cue functions
	// 내부 게임플레이 큐 함수들
	virtual void AddGameplayCue_Internal(const FGameplayTag GameplayCueTag, FGameplayEffectContextHandle& EffectContext, FActiveGameplayCueContainer& GameplayCueContainer);
	virtual void AddGameplayCue_Internal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters, FActiveGameplayCueContainer& GameplayCueContainer);
	virtual void RemoveGameplayCue_Internal(const FGameplayTag GameplayCueTag, FActiveGameplayCueContainer& GameplayCueContainer);

	/** Actually pushes the final attribute value to the attribute set's property. Should not be called by outside code since this does not go through the attribute aggregator system. */
	/** 최종 속성 값을 속성 세트의 속성으로 실제로 푸시합니다. 이 함수는 속성 애그리게이터 시스템을 통해 호출되지 않으므로 외부 코드에서 호출해서는 안 됩니다. */
	void SetNumericAttribute_Internal(const FGameplayAttribute &Attribute, float& NewFloatValue);

	bool HasNetworkAuthorityToApplyGameplayEffect(FPredictionKey PredictionKey) const;

	void ExecutePeriodicEffect(FActiveGameplayEffectHandle	Handle);

	void ExecuteGameplayEffect(FGameplayEffectSpec &Spec, FPredictionKey PredictionKey);

	void CheckDurationExpired(FActiveGameplayEffectHandle Handle);
		
	TArray<TObjectPtr<UGameplayTask>>&	GetAbilityActiveTasks(UGameplayAbility* Ability);
	
	/** Contains all of the gameplay effects that are currently active on this component */
	/** 이 구성 요소에 현재 활성화된 모든 게임플레이 효과를 포함합니다 */
	UPROPERTY(Replicated)
	FActiveGameplayEffectsContainer ActiveGameplayEffects;

	/** List of all active gameplay cues, including ones applied manually */
	/** 수동으로 적용된 것들을 포함한 모든 활성 게임플레이 큐의 목록 */
	UPROPERTY(Replicated)
	FActiveGameplayCueContainer ActiveGameplayCues;

	/** Replicated gameplaycues when in minimal replication mode. These are cues that would come normally come from ActiveGameplayEffects */
	/** 최소 복제 모드에서 복제된 게임플레이 큐. 이는 일반적으로 ActiveGameplayEffects에서 오는 큐들입니다 */

	UPROPERTY(Replicated)
	FActiveGameplayCueContainer MinimalReplicationGameplayCues;

	/** Abilities with these tags are not able to be activated */
	/** 입력 바인딩을 기준으로 차단된 능력을 추적합니다. BlockedAbilityBindings[InputID] > 0인 경우 능력이 차단됩니다 */
	UPROPERTY(Transient, Replicated)
	FGameplayTagCountContainer BlockedAbilityTags;

	UE_DEPRECATED(4.26, "This will be made private in future engine versions. Use SetBlockedAbilityBindings, GetBlockedAbilityBindings, or GetBlockedAbilityBindings_Mutable instead.")
	/** Tracks abilities that are blocked based on input binding. An ability is blocked if BlockedAbilityBindings[InputID] > 0 */
	UPROPERTY(Transient, Replicated)
	TArray<uint8> BlockedAbilityBindings;

	void SetBlockedAbilityBindings(const TArray<uint8>& NewBlockedAbilityBindings);
	TArray<uint8>& GetBlockedAbilityBindings_Mutable();
	const TArray<uint8>& GetBlockedAbilityBindings() const;

	void DebugCyclicAggregatorBroadcasts(struct FAggregator* Aggregator);
	
	/** Acceleration map for all gameplay tags (OwnedGameplayTags from GEs and explicit GameplayCueTags) */
	/** 모든 게임플레이 태그에 대한 가속 맵 (GEs에서의 OwnedGameplayTags 및 명시적 GameplayCueTags) */
	FGameplayTagCountContainer GameplayTagCountContainer;

	UE_DEPRECATED(4.26, "This will be made private in future engine versions. Use SetMinimalReplicationTags, GetMinimalReplicationTags, or GetMinimalReplicationTags_Mutable instead.")
	UPROPERTY(Replicated)
	FMinimalReplicationTagCountMap MinimalReplicationTags;

	void SetMinimalReplicationTags(const FMinimalReplicationTagCountMap& NewMinimalReplicationTags);
	FMinimalReplicationTagCountMap& GetMinimalReplicationTags_Mutable();
	const FMinimalReplicationTagCountMap& GetMinimalReplicationTags() const;

	FMinimalReplicationTagCountMap& GetReplicatedLooseTags_Mutable();
	const FMinimalReplicationTagCountMap& GetReplicatedLooseTags() const;

	void ResetTagMap();

	void NotifyTagMap_StackCountChange(const FGameplayTagContainer& Container);

	virtual void OnTagUpdated(const FGameplayTag& Tag, bool TagExists) {};
	
	const UAttributeSet*	GetAttributeSubobject(const TSubclassOf<UAttributeSet> AttributeClass) const;
	const UAttributeSet*	GetAttributeSubobjectChecked(const TSubclassOf<UAttributeSet> AttributeClass) const;
	const UAttributeSet*	GetOrCreateAttributeSubobject(TSubclassOf<UAttributeSet> AttributeClass);

	void UpdateTagMap_Internal(const FGameplayTagContainer& Container, int32 CountDelta);

	friend struct FActiveGameplayEffect;
	friend struct FActiveGameplayEffectAction;
	friend struct FActiveGameplayEffectsContainer;
	friend struct FActiveGameplayCue;
	friend struct FActiveGameplayCueContainer;
	friend struct FGameplayAbilitySpec;
	friend struct FGameplayAbilitySpecContainer;
	friend struct FAggregator;
	friend struct FActiveGameplayEffectAction_Add;
	friend struct FGameplayEffectSpec;
	friend class AAbilitySystemDebugHUD;
	friend class UAbilitySystemGlobals;

private:

	// Needs to be called when modifying the SpawnedAttributes array for changes to be replicated
	// SpawnedAttributes 배열을 수정할 때 변경 사항이 복제되도록 해야 합니다
	void SetSpawnedAttributesListDirty();

    // Private accessor to the AllReplicatedInstancedAbilities array until the deprecation tag on it is removed and we can reference the array directly again.
	// AllReplicatedInstancedAbilities 배열을 비공개 접근자로 변경하여 참조할 수 없게 된 경우를 대비해 비공개 접근자를 사용합니다.
	PRAGMA_DISABLE_DEPRECATION_WARNINGS
	PRAGMA_DISABLE_DEPRECATION_WARNINGS
	TArray<TObjectPtr<UGameplayAbility>>& GetReplicatedInstancedAbilities_Mutable() { return AllReplicatedInstancedAbilities; }
	PRAGMA_ENABLE_DEPRECATION_WARNINGS

private:

	/** List of attribute sets */
	/** 속성 세트 목록 */
	UPROPERTY(Replicated, ReplicatedUsing = OnRep_SpawnedAttributes, Transient)
	TArray<TObjectPtr<UAttributeSet>>	SpawnedAttributes;

	UFUNCTION()
	void OnRep_SpawnedAttributes(const TArray<UAttributeSet*>& PreviousSpawnedAttributes);

	FDelegateHandle MonitoredTagChangedDelegateHandle;
	FTimerHandle    OnRep_ActivateAbilitiesTimerHandle;

	/** Container used for replicating loose gameplay tags */
	/** 헐거운 게임플레이 태그를 복제하는 데 사용되는 컨테이너 */
	UPROPERTY(Replicated)
	FMinimalReplicationTagCountMap ReplicatedLooseTags;

	uint8 bDestroyActiveStateInitiated : 1;
public:

	/** Caches the flags that indicate whether this component has network authority. */
	/** 이 구성 요소가 네트워크 권한을 가지고 있는지 여부를 나타내는 플래그를 캐시합니다. */
	void CacheIsNetSimulated();

	/** PredictionKeys, see more info in GameplayPrediction.h. This has to come *last* in all replicated properties on the AbilitySystemComponent to ensure OnRep/callback order. */
	/** PredictionKeys, 자세한 내용은 GameplayPrediction.h를 참조하세요. 이 속성은 AbilitySystemComponent의 모든 복제된 속성 중 *마지막*에 와야 OnRep/콜백 순서가 보장됩니다. */
	UPROPERTY(Replicated, Transient)
	FReplicatedPredictionKeyMap ReplicatedPredictionKeyMap;

protected:

	struct FAbilityListLockActiveChange
	{
		FAbilityListLockActiveChange(UAbilitySystemComponent& InAbilitySystemComp,
									 TArray<FGameplayAbilitySpec, TInlineAllocator<2> >& PendingAdds,
									 TArray<FGameplayAbilitySpecHandle, TInlineAllocator<2> >& PendingRemoves) :
			AbilitySystemComp(InAbilitySystemComp),
			Adds(MoveTemp(PendingAdds)),
			Removes(MoveTemp(PendingRemoves))
		{
			AbilitySystemComp.AbilityListLockActiveChanges.Add(this);
		}

		~FAbilityListLockActiveChange()
		{
			AbilitySystemComp.AbilityListLockActiveChanges.Remove(this);
		}

		UAbilitySystemComponent& AbilitySystemComp;
		TArray<FGameplayAbilitySpec, TInlineAllocator<2> > Adds;
		TArray<FGameplayAbilitySpecHandle, TInlineAllocator<2> > Removes;
	};

	TArray<FAbilityListLockActiveChange*> AbilityListLockActiveChanges;
	
}; 

번역을 진행하면서 재미있는 코드를 많이 볼 수 있었다.
예제 프로젝트를 진행하면서 중요한 것들 위주로 적용해보고 싶다.

0개의 댓글