📌 오늘의 목표
장애물을 인터페이스 기반 구조로 설계하고 확장성 있게 구현
Tick 기반 이동·회전 로직을 완성
Timer + 랜덤 요소를 활용한 고급 장애물 패턴 구현
필수 과제 + 도전 과제 요구사항 충족 여부 점검
🔹 인터페이스 기반 설계
모든 장애물이 공통적으로 가져야 할 동작을 IIObstacleInterface로 정의했다.
class IIObstacleInterface
{
public:
virtual void OnObstcaleOverlap(AActor* OverlapActor) = 0;
virtual void OnObstacalEndOverlap(AActor* OverlapActor) = 0;
virtual FName GetObtacleType() const = 0;
virtual void Move(float MaxRange, float MoveSpeed, FVector StartLocation) = 0;
virtual void Rotate() = 0;
virtual void Spawn() = 0;
};
✔ 장애물 타입이 늘어나도 동일한 규약 유지
✔ Overlap / 이동 / 회전 / 스폰 책임을 명확히 분리
🔹 BaseObstacle – 공통 부모 클래스
모든 장애물의 공통 기반 Actor로 ABaseObstacle를 설계했다.
SceneComponent + StaticMeshComponent 공통 보유
Tick / BeginPlay 기본 제공
이동·회전 로직의 기본 구현 포함
ObjectSettings 구조체를 통해 설정값 관리
UCLASS()
class ABaseObstacle : public AActor, public IIObstacleInterface
{
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FObstacleMoveSettings MoveSettings;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FObstacleRotationSettings RotationSettings;
};
이동/회전 관련 변수를 개별 멤버로 두지 않고 구조체로 묶어 관리했다.
🔹 이동 설정
USTRUCT(BlueprintType)
struct FObstacleMoveSettings
{
float MoveSpeed;
float MaxRange;
FVector MoveAxis;
FVector StartLocation;
float MoveSign;
};
🔹 회전 설정
USTRUCT(BlueprintType)
struct FObstacleRotationSettings
{
bool bEnableRotation;
FRotator RotationSpeedPerSecond;
float MaxRotationAngle;
float AccumulatedRotation;
FRotator StartRotation;
};
✔ 런타임 상태값은 VisibleAnywhere
✔ 튜닝용 값은 EditAnywhere
✔ 에디터에서 실시간 조정 가능
🔹 왕복 이동
StartLocation 기준 거리 계산
MaxRange 초과 시 이동 방향 반전
DeltaTime 기반 프레임 독립 처리
if (Distance >= MaxRange)
{
MoveSign *= -1.f;
}
AddActorWorldOffset(
MoveAxis * MoveSign * MoveSpeed * DeltaTime
);
🔹 회전
AddActorLocalRotation(
RotationSpeedPerSecond * DeltaTime
);
✔ Tick 기반 Transform 변경 충족
✔ 프레임 독립성 보장
① PatrolObstacle
왕복 이동 + 지속 회전
플레이어와 충돌 시 밀려나도록 구현
Overlap 이벤트 → OnObstcaleOverlap()로 위임
👉 기본 이동형 장애물
② FallingObstacle (통나무 낙하)
하늘에서 통나무가 떨어지는 형태
Overlap 또는 Timer 기반 낙하 트리거
낙하 후 충돌 시 제거
👉 수직 압박형 장애물
③ RotatingLaunchObstacle ⭐
바닥에 고정된 회전 발판
일정 시간마다 회전 방향/속도 변경
플레이어가 밟으면 회전 방향의 접선 방향으로 날아감
핵심 아이디어
Timer로 회전 속도·방향 랜덤 변경
플레이어 위치 기준 접선 벡터 계산
LaunchCharacter()로 발사
FVector Tangent = FVector::CrossProduct(Up, Radial) * YawSign;
Character->LaunchCharacter(
Tangent * LaunchStrength + FVector(0,0,LaunchUp),
true, true
);
👉 회전 + 상호작용형 장애물
FTimerHandle + SetTimer() 사용
Tick 의존 없이 주기적 로직 실행
회전 방향 / 속도 변경, 낙하 타이밍 제어 등에 활용
✔ 성능 효율
✔ 시간 기반 패턴 구현
🔹 역할
게임 시작 시 여러 장애물을 동적으로 Spawn
장애물 종류를 랜덤 선택
위치 / 이동 속도 / 범위 / 회전 속도 등을 랜덤 부여
GetWorld()->SpawnActor<AActor>(
ClassToSpawn, RandomLocation, RandomRotation
);
MoveSpeed = RandRange(120.f, 450.f);
MaxRange = RandRange(150.f, 800.f);
RotationSpeed = RandRange(-220.f, 220.f);
✔ 매번 다른 퍼즐 구조 생성
✔ 랜덤 스테이지 개념 체험