Unreal - 회피(Dodge)

2026. 1. 3. 06:12·Unreal 프로젝트 다이어리/두번째 프로젝트

미리보기

구현내용

앞으로 플레이어는 AI와 격돌하게될예정인데

치고받고 싸움을 할때 회피 라는 개념을 넣어서 조금더

역동적인 움직임을 구현하고 싶었습니다

 

현재 Shift를 누르면 달리기를 실행하는데

Shift를 일정시간 이상 누르면 달리기 짧게 누르면 닷지 를 실행하는 로직으로 구현하였습니다.

 

구현C++

먼저 Shift를 누르면 누른만큼의 시간을 기록하여 Run인지 Dodge인지 분간할 방법이 필요했습니다

0.18초 동안 감지가 들어오면 달리기 아니면 닷지 로 구분하였습니다

void InputKeyboardShiftPressed();
void InputKeyboardShiftReleased();
bool bShiftPressed = false;
float shiftPressedStartTime = 0.f;

float dodgeThreshold = 0.18f;
float runThreshold = 0.18f;

void AMainCharacterController::InputKeyboardShiftPressed()
{
	bShiftPressed = true;
	shiftPressedStartTime = GetWorld()->GetTimeSeconds();
}

void AMainCharacterController::InputKeyboardShiftReleased()
{
	if (!bShiftPressed || !mainCharacter)
		return;

	float holdTime = GetWorld()->GetTimeSeconds() - shiftPressedStartTime;
	if (holdTime < dodgeThreshold)
		mainCharacter->Dodge();

	mainCharacter-> StopRun();
	bShiftPressed = false;
}

void AMainCharacterController::Tick(float deltaTime)
{
	Super::PlayerTick(deltaTime);
	
	if (bShiftPressed && !mainCharacter->bIsRun)
	{
		float holdTime = GetWorld()->GetTimeSeconds() - shiftPressedStartTime;
		if (holdTime >= runThreshold)
			mainCharacter->StartRun();
	}
	
}

 

Dodge를 구현할때 락온 상태와 락온 상태가 아닐때 두가지로 방향을 구분지었습니다

락온상태일때는 4방향 앞 뒤 오른쪽 왼쪽 비락온상태일때는 닷지가 무조건 앞으로 실행되도록 구현하였습니다

void AMainCharacter::Dodge()
{
    if (bIsDodging)
        return;
    if (guardMode)
        return;
    FVector inputDir = GetLastMovementInputVector();
    FVector dodgeDir;

    EDodgeDir dodgeType = EDodgeDir::Forward;

    bool bLockOn = lockOnSystem->IsLockOn();
    if (bLockOn)
    {
        AActor* target = lockOnSystem->getCurrentLockOnTarget();
        if (!target)
            return;

        FVector toTarget = (target->GetActorLocation() - GetActorLocation()).GetSafeNormal();
        FVector right = FVector::CrossProduct(FVector::UpVector, toTarget);

        FVector input = inputDir.GetSafeNormal();

        float forwardValue = FVector::DotProduct(input, toTarget);
        float rightValue = FVector::DotProduct(input, right);

        const float threshold = 0.3f;

        if (forwardValue > threshold)
            dodgeType = EDodgeDir::Forward;
        else if (forwardValue < -threshold)
            dodgeType = EDodgeDir::Back;
        else if (rightValue > threshold)
            dodgeType = EDodgeDir::Right;
        else
            dodgeType = EDodgeDir::Left;
    }
    else
    {
        if (!inputDir.IsNearlyZero())
            dodgeDir = inputDir.GetSafeNormal();
        else
            dodgeDir = GetActorForwardVector();
    }

    switch (dodgeType)
    {
    case EDodgeDir::Forward: dodgeDir = GetActorForwardVector(); break;
    case EDodgeDir::Back:    dodgeDir = -GetActorForwardVector(); break;
    case EDodgeDir::Left:    dodgeDir = -GetActorRightVector(); break;
    case EDodgeDir::Right:   dodgeDir = GetActorRightVector(); break;
    }

    FCharacterAnimDataTable* row = dodgeRowMap[dodgeType];
    if (!row || !row->usingAnimation)
        return;

    UAnimInstance* animInst = GetMesh()->GetAnimInstance();
    bIsDodging = true;

    float playTime = PlayAnimMontage(row->usingAnimation);
    if (playTime <= 0.f)
    {
        bIsDodging = false;
        return;
    }

    FOnMontageEnded endDel;
    endDel.BindUObject(this, &AMainCharacter::OnDodgeMontageEnded);
    animInst->Montage_SetEndDelegate(endDel, row->usingAnimation);

    FVector launch = dodgeDir * 3000.f;
    launch.Z = 0.f;
    LaunchCharacter(launch, true, true);
}

 

또한 데이터테이블에서 RowName이 Dodge인 Dodge Row중에서 이름으로 매핑도 해주었습니다

해당 함수는 전부 BeginPlay에서 캐싱해주었습니다

FName AMainCharacter::GetDodgeRowName(EDodgeDir dir) const
{
    switch (dir)
    {
    case EDodgeDir::Forward: return FName("DodgeForward");
    case EDodgeDir::Back:    return FName("DodgeBack");
    case EDodgeDir::Left:    return FName("DodgeLeft");
    case EDodgeDir::Right:   return FName("DodgeRight");
    default:                 return NAME_None;
    }
}

void AMainCharacter::InitDodgeRows()
{
    if (!animDataTable)
        return;

    const EDodgeDir dirs[] =
    {
        EDodgeDir::Forward,
        EDodgeDir::Back,
        EDodgeDir::Left,
        EDodgeDir::Right
    };

    for (EDodgeDir dir : dirs)
    {
        FName rowName = GetDodgeRowName(dir);

        FCharacterAnimDataTable* row =animDataTable->FindRow<FCharacterAnimDataTable>(rowName, TEXT("Dodge"));

        if (row)
            dodgeRows.Add(rowName, row);
    }
}

 

캐릭터의 애니메이션을 담당하는 데이터테이블에 Dodge 타입으로 애니메이션을 추가해주었습니다

 

결과

비락온 상태일때는 앞방향으로 닷지 할 수 있습니다.

 

락온 상태일때는 적을 기준으로 4방향 앞 뒤 오른쪽 왼쪽 으로 닷지가 가능합니다

 

영상

 

 

저작자표시 비영리 변경금지 (새창열림)

'Unreal 프로젝트 다이어리 > 두번째 프로젝트' 카테고리의 다른 글

Unreal - 그래플링 훅  (0) 2026.01.08
Unreal - 처형( Execution )  (0) 2026.01.05
Unreal - 스킬창 & 연동  (0) 2026.01.01
Unreal - 버프창  (0) 2025.12.27
Unreal - 퀵슬롯  (0) 2025.12.27
'Unreal 프로젝트 다이어리/두번째 프로젝트' 카테고리의 다른 글
  • Unreal - 그래플링 훅
  • Unreal - 처형( Execution )
  • Unreal - 스킬창 & 연동
  • Unreal - 버프창
lucodev
lucodev
언리얼 포폴개발 일기
  • lucodev
    루코 개발테이블
    lucodev
  • 전체
    오늘
    어제
    • 분류 전체보기 (236)
      • Unreal 프로젝트 다이어리 (132)
        • 첫번째 프로젝트 (73)
        • 두번째 프로젝트 (59)
      • Unreal 팁 (8)
      • Unreal 디버깅 (8)
      • C++ 프로그래머스 (52)
        • Stack,Queue (7)
        • Hash (4)
        • Heap (2)
        • Sort (5)
        • Exhaustive search (5)
        • Greedy (2)
        • BFS , DFS (7)
        • Graph (2)
        • Dynamic Programming (1)
        • C++ Math (2)
        • 기타 문제 (14)
      • C++ 백준 (5)
      • C++ 팁 (1)
      • 개인 코테 & 스타디 <비공개> (29)
        • 코드 개인보관함 (9)
        • 코딩테스트+@ (11)
        • 알고리즘 스타디 (6)
        • 알고리즘 스타디 과제 (3)
        • 비공개 (0)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 링크

  • 공지사항

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 태그

    언리얼 ui
    unreal
    언리얼 세키로
    언리얼 파쿠르
    unreal 상호작용
    unreal 인벤토리
    unreal 세키로
    언리얼 비헤이비어트리
    언리얼 인터렉션
    unreal npc
    언리얼 behaviortree
    언리얼 parkour
    언리얼 behavior tree
    unreal 파쿠르
    언리얼 인벤토리
    언리얼 시퀀스
    언리얼 컷씬
    unreal inventory
    언리얼 상호작용
    언리얼
  • hELLO· Designed By정상우.v4.10.3
lucodev
Unreal - 회피(Dodge)
상단으로

티스토리툴바