Move 함수
캐릭터를 움직이는 Move 기능을 GA가 아닌 캐릭터에 함수로 구현 하였음
그래서 Move가 실행 중일때 Tag를 붙이고 싶으면 따로 코드로 구현해야 함
Move 함수를 GA로 구현하지 않은 이유는 GA 실행시 변수를 전달할 방법을 찾지 못함
MoveInputReleased
Move 입력이 끝나면 호출되는 함수
Move함수에서 부착한 Tag와 발동중인 Sprint GA가 있으면 취소시키는 함수
코드로 Tag 부착
void APPGASCharacterPlayer::Move(const FInputActionValue& Value)
{
//ASC에 태그 달기
//#include "GameplayTagContainer.h" 추가
FGameplayTagContainer WalkingTagContainer;
WalkingTagContainer.AddTag(PPTAG_CHARACTER_ISWALKING);
if (GetCharacterMovement()->GetMovementName() == TEXT("Walking"))
{
if (!ASC->HasAnyMatchingGameplayTags(WalkingTagContainer))
{
ASC->AddLooseGameplayTags(WalkingTagContainer);
//#include "AbilitySystemGlobals.h" 추가
if (UAbilitySystemGlobals::Get().ShouldReplicateActivationOwnedTags())
{
ASC->AddReplicatedLooseGameplayTags(WalkingTagContainer);
}
}
}
if (GetCharacterMovement()->GetMovementName() != TEXT("Walking"))
{
RemoveWalkingTag(WalkingTagContainer);
}
}
- FGameplayTagContainer WalkingTagContainer;
WalkingTagContainer.AddTag(PPTAG_CHARACTER_ISWALKING);- 태그를 달기 위해서는 GameplayTagContainer에 캐릭터에 추가할 태그를 GameplayTagContainer에 넣어 줘야함
- #include "GameplayTagContainer.h" 추가
- PPTAG_CHARACTER_ISWALKING 매크로는 별도로 추가한 매크로
- 매크로 내용 : FGameplayTag::RequestGameplayTag(FName("Character.State.IsWalking"))
- 태그를 찾아오는 매크로
- if (GetCharacterMovement()->GetMovementName() == TEXT("Walking"))
- 캐릭터 무브먼트 모드가 Walking 이면
- if (!ASC->HasAnyMatchingGameplayTags(WalkingTagContainer))
- ASC에 WalkingTagContainer에 들어있는 태그가 없으면
- ASC->AddLooseGameplayTags(WalkingTagContainer);
- 태그 추가
- //#include "AbilitySystemGlobals.h" 추가
if (UAbilitySystemGlobals::Get().ShouldReplicateActivationOwnedTags())
{
ASC->AddReplicatedLooseGameplayTags(WalkingTagContainer);
}- 태그가 추가된걸 리플리케이트 해주는 코드
- if (GetCharacterMovement()->GetMovementName() != TEXT("Walking"))
- 캐릭터 무브먼트가 Walking이 아니면
- RemoveWalkingTag(WalkingTagContainer);
- RemoveTag 함수 실행
코드로 Tag 제거
void APPGASCharacterPlayer::RemoveWalkingTag(const FGameplayTagContainer& RemoveTagContainer)
{
// ASC에 태그 제거
if (ASC->HasAnyMatchingGameplayTags(RemoveTagContainer))
{
ASC->RemoveLooseGameplayTags(RemoveTagContainer);
if (UAbilitySystemGlobals::Get().ShouldReplicateActivationOwnedTags())
{
ASC->RemoveReplicatedLooseGameplayTags(RemoveTagContainer);
}
}
}
- if (ASC->HasAnyMatchingGameplayTags(RemoveTagContainer))
- ASC에 제거할 태그가 있으면
- ASC->RemoveLooseGameplayTags(RemoveTagContainer);
- 태그 제거
- if (UAbilitySystemGlobals::Get().ShouldReplicateActivationOwnedTags())
{
ASC->RemoveReplicatedLooseGameplayTags(RemoveTagContainer);
}- 리플리케이트가 필요한 경우 추가
특정 태그가 달린 GA 취소
const FGameplayTagContainer* CancelAbilityTags = new FGameplayTagContainer(PPTAG_ABILITY_ATTACK);
ASC->CancelAbilities(CancelAbilityTags);
- 공격이 진행 중일때 이동을 하면 공격을 취소 시킴
- const FGameplayTagContainer* CancelAbilityTags = new FGameplayTagContainer(PPTAG_ABILITY_ATTACK);
- 공격 GA의 태그를 컨테이너에 추가하여 컨테이너를 생성
- ASC->CancelAbilities(CancelAbilityTags);
- 컨테이너를 이용하여 어빌리티 취소
어빌리티 스펙을 이용하여 GA 취소
FGameplayAbilitySpec* Spec = ASC->FindAbilitySpecFromInputID((int32)EInputAbility::Sprint);
if (Spec->IsActive())
{
ASC->CancelAbilityHandle(Spec->Handle);
}
- FGameplayAbilitySpec* Spec = ASC->FindAbilitySpecFromInputID((int32)EInputAbility::Sprint);
- FindAbilitySpec 함수를 통해 어빌리티 스펙을 찾음
- if (Spec->IsActive())
- 찾은 스펙이 실행 중이면
- ASC->CancelAbilityHandle(Spec->Handle);
- CancelAbilityHandle 함수를 통해 GA 취소
전체 코드
void APPGASCharacterPlayer::Move(const FInputActionValue& Value)
{
//ASC에 태그 달기
//#include "GameplayTagContainer.h" 추가
FGameplayTagContainer WalkingTagContainer;
WalkingTagContainer.AddTag(PPTAG_CHARACTER_ISWALKING);
if (GetCharacterMovement()->GetMovementName() == TEXT("Walking"))
{
if (!ASC->HasAnyMatchingGameplayTags(WalkingTagContainer))
{
ASC->AddLooseGameplayTags(WalkingTagContainer);
//#include "AbilitySystemGlobals.h" 추가
if (UAbilitySystemGlobals::Get().ShouldReplicateActivationOwnedTags())
{
ASC->AddReplicatedLooseGameplayTags(WalkingTagContainer);
}
}
//이동시 공격 어빌리티 캔슬
const FGameplayTagContainer* CancelAbilityTags = new FGameplayTagContainer(PPTAG_ABILITY_ATTACK);
ASC->CancelAbilities(CancelAbilityTags);
//X는 좌우 Y는 상하 입력
FVector2D MovementVector = Value.Get<FVector2D>();
//CameraArm->bUsePawnControlRotation = true; 설정을 통해
//카메라 암과 컨트롤러의 로테이션은 동기화 됨
//const FRotator Rotation = Controller->GetControlRotation();
const FRotator Rotation = CameraArm->GetDesiredRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
if (GetCharacterMovement()->GetMovementName() != TEXT("Walking"))
{
RemoveWalkingTag(WalkingTagContainer);
}
}
void APPGASCharacterPlayer::MoveInputReleased()
{
FGameplayTagContainer WalkingTagContainer;
WalkingTagContainer.AddTag(PPTAG_CHARACTER_ISWALKING);
InputReleasedDelegate.Execute();
RemoveWalkingTag(WalkingTagContainer);
FGameplayAbilitySpec* Spec = ASC->FindAbilitySpecFromInputID((int32)EInputAbility::Sprint);
if (Spec->IsActive())
{
ASC->CancelAbilityHandle(Spec->Handle);
}
}
void APPGASCharacterPlayer::RemoveWalkingTag(const FGameplayTagContainer& RemoveTagContainer)
{
// ASC에 태그 제거
if (ASC->HasAnyMatchingGameplayTags(RemoveTagContainer))
{
ASC->RemoveLooseGameplayTags(RemoveTagContainer);
if (UAbilitySystemGlobals::Get().ShouldReplicateActivationOwnedTags())
{
ASC->RemoveReplicatedLooseGameplayTags(RemoveTagContainer);
}
}
}
'포트폴리오 제작 > Project_P' 카테고리의 다른 글
Project_P AttributeSet을 캐릭터에 생성하기 (0) | 2024.10.16 |
---|---|
Project_P AttributeSet을 사용하여 스탯 만들기 (0) | 2024.10.16 |
Project_P 공격 판정 구현(4) TA 타겟액터 구현 (0) | 2024.09.11 |
Project_P 공격 판정 구현(3) Trace 어빌리티 태스크 생성 (0) | 2024.09.06 |
Project_P 공격 판정 구현(2) AttackCheck GA 생성 (0) | 2024.09.06 |