슈팅 게임에서 조준점의 간격은 항상 고정되어있지 않고 캐릭터의 움직임이나 점프, 사격, 조준사격 등의 요인에 의해 벌어지거나 좁혀지는게 일반적이다.

 

조준점의 간격에 영향을 주는 요인들을 하나씩 계산해서 하나의 변수로 만들어주면 생각보다 어렵지 않게 구현할 수 있다.

 

/* 조준점의 최종 확산 계수 */
float CrosshairSpreadMultiplier;

/* 속력에 의한 확산 계수 */
float CrosshairVelocityFactor;

/* 점프에 의한 확산 계수 */
float CrosshairInAirFactor;

/* 조준에 의한 확산 계수 */
float CrosshairAimFactor;

/* 사격에 의한 확산 계수 */
float CrosshairShootingFactor;

 

우선은 이동, 점프, 조준, 사격 총 4가지 요인으로 정해서 구현해본다.

 

 

 

이동에 의한 확산값은 현재 이동속도를 최대 이동속도에 대한 비율을 구하면 된다.

 

Vector Velocity = GetVelocity();
Velocity.Z = 0.f // Z값은 필요하지 않다
CrosshairVelocityFactor = Velocity.Size() / GetCharacterMovement()->MaxWalkSpeed;

/* 또는 */
FVector2D WalkSpeedRange = FVector2D(0.f, GetCharacterMovement()->MaxWalkSpeed);
FVector2D VelocityMultiplierRange = FVector2D(0.f, 1.f);
FVector Velocity = GetVelocity();
Velocity.Z = 0.f;

CrosshairVelocityFactor = FMath::GetMappedRangeValueClamped(WalkSpeedRange, VelocityMultiplierRange, Velocity.Size());

 

구한 값을 최종 값에 더해주면 이동에 의한 계산은 끝난다.

 

CrosshairSpreadMultiplier = 0.5f + CrosshairVelocityFactor; // 0.5는 기본 계수

 

 

나머지 값들을 구하기 전에 HUD를 우선 만들어둔다.

 

조준점은 하나로 합쳐진것을 사용하면 확산시킬수 없기 때문에 각 방향으로 나눠진것을 총 4개 사용한다.

 

Crosshair Spread Max의 값을 고정시켜놓고(위의 그래프에서는 16으로 지정) C++에서 계산한 값인 Crosshair Spread Multiplier를 곱해서 사용하게 된다. 조준점을 4개로 분할했으므로 위와 같지만 계산식만 조금 다른 노드들을 4개 사용한다.

 

HUD 블루프린트 작성이 완료되었다면 이제 각 확산 값만 구해주면 잘 적용될 것이다.

 

이동에 의한 확산만 적용한 상태

 

점프에 의한 확산값은 현재 캐릭터가 점프중인지를 판별해서 값을 보간해준다.

 

if (GetCharacterMovement()->IsFalling())
{
	// 점프중에는 천천히 확산되고
    CrosshairInAirFactor = FMath::FInterpTo(CrosshairInAirFactor, 2.25f, DeltaTime, 2.25f);
}
else
{
	// 착지하면 빠르게 회복한다
    CrosshairInAirFactor = FMath::FInterpTo(CrosshairInAirFactor, 0.f, DeltaTime, 30.f);
}

CrosshairSpreadMultiplier = 0.5f + CrosshairVelocityFactor + CrosshairInAirFactor;

 

이동+점프 확산 동시 적용

 

조준도 점프와 마찬가지로 값을 보간해준다. 단, 조준은 확산이 아니라 좁혀지기 때문에 값을 빼주어야 한다.

 

if (bAiming)
{
    CrosshairAimFactor = FMath::FInterpTo(CrosshairAimFactor, 0.3f, DeltaTime, 30.f);
}
else
{
    CrosshairAimFactor = FMath::FInterpTo(CrosshairAimFactor, 0.f, DeltaTime, 30.f);
}

CrosshairSpreadMultiplier = 0.5f + CrosshairVelocityFactor + 
                            CrosshairInAirFactor - CrosshairAimFactor;

 

조준 적용

 

 

사격에 의한 확산값은 단순하게 구현한다면 사격에 의한 확산값을 항상 0으로 보간하고 사격하는 순간만 상수값을 대입하는 방법이 있다.

 

// 사격하는 순간
CrosshairShootingFactor = 1.5f;

/* */

// 항상 0으로 보간
CrosshairShootingFactor = FMath::FInterpTo(CrosshairShootingFactor, 0.f, DeltaTime, 30.f);

 

단순하게 구현

 

사격시 조준점이 즉시 회복되지 않고 일정시간 뒤에 회복되길 원한다면 bool값과 타이머 매니저를 이용해서 구현해주면 된다.

 

 

CrosshairSpreadMultiplier = 
    0.5f + // 기본 계수
    CrosshairVelocityFactor +
    CrosshairInAirFactor -
    CrosshairAimFactor + 
    CrosshairShootingFactor;

 

최종적으로 위의 수식이 만들어진다.

+ Recent posts