본문 바로가기
언리얼엔진 개발/VR

[UnrealEngine5] 나사 돌리기 그 후

by yeni_0224 2023. 6. 9.
728x90
반응형

드디어 게임을 제작 발표하기까지 완료했다. 휴~!

이제 블로그에 글을 작성한 이후에 어느부분이 수정되었는지 이제 풀어볼 차례이다.

기획도 하고 개발도 하고 아트도 한 나! 고생해따~! 갈길은 멀지만 그래도 시작이 좋다!

 

나사 돌리기를 한 이유는

나사를 돌려 환풍구를 해체하고

환풍구 안 통로를 통해 미니카를 방 밖으로 빼내서 힌트를 보여주게 하기 위함이었다.

 

1. 나사를 다 돌려 해체시킬 때까지 환풍구가 손에 잡히거나 움직이면 안된다.

2. 나사를 다 돌려서 바닥에 떨어졌을 때 Physics가 작동하여 손에 잡혀 날아갈 수 있도록 해야한다.

3. 원래는 환풍구 한 곳만 나사를 돌려 해체시키려 했으나 이후 다른 문에도 나사 풀기를 적용해서

두 곳에서 모두 같은 기능을 적용해야했다.


1. 일단 Simulated Physics = false이고

grab은 아무것도 잡을 수 없는 상태로 만들어준 후

일정 조건을 만족했을 때 Simulated Physics = true로 만들어주고 grab 될수 있도록 만들어줄 것이다.


2. 나사가 다 풀려 바닥에 떨어졌는지 어떻게 정의할 것인가.

처음에는 바닥에 떨어진 나사의 갯수를 카운팅하려고 했으나.

나사를 풀었는지 체크하는 쪽은 Tick에서 진행하고 있기 때문에

나사의 갯수를 ++ 해서 바닥에 떨어진 나사 갯수가 4개인지 확인하는 것은 쉽지 않았다.

처음엔 그래서 simulated Physics가 true가 된 나사들을 iterator로 찾아 배열에 넣고, 배열에 다 차면

조건을 만족했으니 vent의 조건을 수정해줄까 했지만, 다른 방법도 있었다.

나사가 다 빠졌으면 > 바닥에 떨어질 것이고 > 여기서 Vent 클래스를 찾아서 바닥에 떨어진 나사의 갯수를 세어줄 것이다.

> 나사가 4개 다 떨어지면 vent를 떨어뜨려라

이런식으로 구성했다.

if (isEnoughRotated == true)
{
    boxComp->SetSimulatePhysics(true); //나사의 Physics 켜주기

    AMovableVent* mv = Cast<AMovableVent>(UGameplayStatics::GetActorOfClass(GetWorld(), AMovableVent::StaticClass()));
    if (!bDoOnce)
    {
        bDoOnce = true;
        mv->cameOutScrewCount++;
        if (mv->cameOutScrewCount == 4)
        {
            mv->FallingCover();
        }
    }
    //후략..

Tick에서 계속 나사의 상태를 체크하고있기 때문에 bool 변수를 이용해서 제어해줄것이다.

//cameoutscrew 체크를 한번만 하도록
	bool bDoOnce;

나사가 한 번 풀릴 때마다 cameout screw의 갯수가 한개씩 추가되었다.

cameout screw는 vent에서 체크해주는, 바닥에 떨어진 나사의 갯수를 체크하는 변수이다.


3. 배터리 커버의 나사인가 환풍구의 나사인가 구분하고 각 나사가 떨어질 때 해당 나사가 붙어있던 커버만 떨어지게 할 것이다. 배터리 커버와 환풍구는 모두 같은 기능을 사용하지만 배터리 커버가 떨어질 경우 다른 클래스에 델리게이트 신호를 보내줘야한다. 배터리 커버만 필요한 기능이 있기 때문에 두 클래스를 나눠줄 것이다.

Movable Cover 라는 부모 클래스를 만들고, Movable Vent, MovableBattCover라는 자식 클래스를 만들어줘서 각각 관리하게 할 것이다.

Screw에서 FallingCover()함수가 호출되면 cameoutScrew의 갯수를 0으로 초기화해줄것이다.

그 다음 physics를 켜주고, 자유롭게 Grab 할 수 있도록 설정을 바꿔줄 것이다.

 

그리고 나사에서 해야할 일은 이게 배터리 커버의 나사인가 환풍구 나사인가 구별해주는 것이다.

//벤트 나사인가 배터리 나사인가
	UPROPERTY(EditAnywhere)
	bool isVentScrew;

어떤 커버인지 구별해주는 함수를 만들어줄것이고, 인스턴스 상에서 벤트 커버에만 isVentScrew는 True라고 엔진에서 체크해줄 것이다.

AMovableVent* mv = Cast<AMovableVent>(UGameplayStatics::GetActorOfClass(GetWorld(), AMovableVent::StaticClass()));
AMovableBattCover* mbc = Cast<AMovableBattCover>(UGameplayStatics::GetActorOfClass(GetWorld(), AMovableBattCover::StaticClass()));
if(isVentScrew)
{
    if (!bDoOnce)
    {
    	bDoOnce = true;
       //중략..
    }
}
else
{
    if (!bDoOnce)
    {
        bDoOnce = true;
       //중략..
    }
}

VentScrew가 참인지 거짓인지에 따른 조건을 달아주고, ventscrew 나사가 다 떨어지면 vent의 fallingCover 함수를 호출하고, battCover의 나사가 다 떨어지면 battCover의 fallingCover 함수를 호출하도록 해주었다.

 

잘 작동된다!

728x90
반응형