Unreal 개발 본 캠프 35일차

HappyCircle·2026년 1월 16일

Unreal 개발

목록 보기
52/163

오늘 학습 진행 내용

[6번 과제] 회전 발판과 움직이는 장애물

📘 TIL – 장애물 시스템 확장 (이동 / 회전 / 랜덤 스폰 구조)

📌 오늘의 목표

장애물을 인터페이스 기반 구조로 설계하고 확장성 있게 구현

Tick 기반 이동·회전 로직을 완성

Timer + 랜덤 요소를 활용한 고급 장애물 패턴 구현

필수 과제 + 도전 과제 요구사항 충족 여부 점검

🧱 1. 장애물 시스템 구조 설계

🔹 인터페이스 기반 설계

모든 장애물이 공통적으로 가져야 할 동작을 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;
};

🧩 2. ObjectSettings 구조체로 설정값 정리

이동/회전 관련 변수를 개별 멤버로 두지 않고 구조체로 묶어 관리했다.

🔹 이동 설정

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
✔ 에디터에서 실시간 조정 가능

🔁 3. Tick 기반 이동 / 회전 구현 (필수 과제)

🔹 왕복 이동

StartLocation 기준 거리 계산

MaxRange 초과 시 이동 방향 반전

DeltaTime 기반 프레임 독립 처리

if (Distance >= MaxRange)
{
	MoveSign *= -1.f;
}

AddActorWorldOffset(
	MoveAxis * MoveSign * MoveSpeed * DeltaTime
);

🔹 회전
AddActorLocalRotation(
	RotationSpeedPerSecond * DeltaTime
);

✔ Tick 기반 Transform 변경 충족
✔ 프레임 독립성 보장

🚧 4. 구현한 장애물 종류

① 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
);

👉 회전 + 상호작용형 장애물

⏱ 5. 타이머 시스템 활용 (도전 과제 1)

FTimerHandle + SetTimer() 사용

Tick 의존 없이 주기적 로직 실행

회전 방향 / 속도 변경, 낙하 타이밍 제어 등에 활용

✔ 성능 효율
✔ 시간 기반 패턴 구현

🎲 6. 랜덤 퍼즐 생성 – RandomObstacleSpawner (도전 과제 2)

🔹 역할

게임 시작 시 여러 장애물을 동적으로 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);

✔ 매번 다른 퍼즐 구조 생성
✔ 랜덤 스테이지 개념 체험

profile
개발합시다!

0개의 댓글