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

[UnrealEngine5] VR 나사 돌리기 만들기(3)

by yeni_0224 2023. 5. 13.
728x90
반응형

 

https://yeni-0224.tistory.com/entry/UnrealEngine5-%EB%82%98%EC%82%AC-%EB%8F%8C%EB%A6%AC%EA%B8%B01

 

[UnrealEngine5] VR 나사 돌리기 만들기(1)

VR 게임 나사 돌리기 유사 시뮬레이션? VR Screw Simulation https://yeni-0224.tistory.com/entry/UnrealEngine%EB%B2%84%ED%8A%BC%EC%9D%84-%EB%88%84%EB%A5%B4%EB%A9%B4-%EB%AC%B8-%EC%97%B4%EA%B3%A0-%EB%8B%AB%EA%B8%B0-C-1 [UnrealEngine5]버튼을 누

yeni-0224.tistory.com

그렇게 다시 코드를 갈아엎은 것이다. 허허허

사실 Driver에서 모든걸 해결하고자 했다. 왜냐하면 구글링 하면서 찾은 나사 돌리는 방법을 봤더니 거기서는 Driver가 모든것을 하고 있었고, 나사는 그냥 Driver의 움직임을 따라하도록 하기만 하는 것이 목표였기 때문에 그냥 Driver가 Screw의 움직임을 통제하는 것이 맞다고 판단했기 때문이다. 혹시나 이 게시물보다 훨씬 정교한 나사돌리는 작업이 필요하다면 이분의 블루프린트를 참고할 것.

https://www.youtube.com/watch?v=WqdMxyn74sg 

작업물을 공유해주고 계신다. 하지만

Unreal Engine 4버전에서 작업한 것이고, 치명적인 문제는 여기서 사용한 노드 중 Hand 가 있는데, 현재 Hand Node는 지원하지 않는 기능이라고 한다. 유추해보았을 때 Hand는 VR Controller의 Physics 설정 같다.

여기서는 훨씬 정교하게 작업하고있으니 여기를봐도 된다. 회전값을 여기저기서 구하고, 가져와서 사용하는데 이해하는 것이 쉽지 않다. 

 

이걸 보며 작업하려다 결국 다시 머리를 깨끗이 비우고 처음부터 다시 시작했다. ㅎㅎ..

1. Screw.h  

//회전하는가
	bool isRotating;
	void bRotating();

	//나사 시작 위치
	FVector startLoc;
	//나사가 나올만큼 다 나왔는가
	bool isEnoughRotated;
	void bEnoughCameOut();

	//나사가 이동한다
	void MoveScrew();
    //나사가 다 나왔다면 바닥에 떨어진다
	void CameOutScrew();

헤더에는 이렇게 만든다고 생각하고 작업을 시작했다.

나사가 다 빠져나올 만큼 충분히 회전했는지를 어떻게 체크할지가 관건이었다. 처음에는 일정 각도를 기준으로, 얼만큼 회전했을 때 1바퀴 회전했다고 인정할지 고민했다. 그러다가 1바퀴 회전이 아니라 총 얼만큼의 각도만큼 회전했는지를 체크해주는 것이 좋겠다고 판단하여 그렇게 수정했지만, 엔진의 문제점이 하나 있다.

 

영상, 사진 작업을 했던 사람으로써 여러 다른 프로그램들은 회전 값을 어떻게 적용하는지 알 수 있는데, 보통은 360도를넘어가는 회전을 하면, 360도 이상의 값으로 인지하고 여러바퀴 돌릴 수 있도록 해주는데, 엔진은 360도가 끝이다. 그리고 회전을 계속 확인하면서 보았던 건, 270도 이상 넘어가면 갑자기 음수의 각도로 변한다. 그 정확한 이유는 알 수 없지만 아무튼 현재 내 코드에서 회전값을 체크한다는 것은 어렵지 않을까! 했고

지정한 거리만큼 나왔을 때 나사가 다 빠져나온 상태라고 정하기로 했다.

    

void AScrew::BeginPlay()
{
	Super::BeginPlay();

	driver = Cast<AScrewDriver>(UGameplayStatics::GetActorOfClass(GetWorld(), AScrewDriver::StaticClass()));

	startLoc = GetActorLocation();
}

나사의 시작 위치를 지정해주었다. Driver와 닿았는지 계속 확인해줘야하고, 다른 함수에서도 계속 사용할 것이기 때문에driver는 전역변수로 설정해주고, Beginplay에서 캐스팅해주었다.

void AScrew::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	//나사가 드라이버에 붙어있을 때만 회전값이 더해진다
	if(driver->isAttaching == true)
	{
    	if (FMath::Abs(driver->deltaRot) > 1)  
		{
			bRotating();
			if(isRotating == true)
			{	
				MoveScrew();
			}
        }
	}
}

void AScrew::MoveScrew()
{
	//회전
	SetActorRotation(GetActorRotation() + FRotator(0, 0, -1 * driver->deltaRot * 값));
	//이동 : deltaRot 증가한만큼 나사가 forwardvector로 이동한다
	SetActorLocation(GetActorLocation() + GetActorForwardVector() * driver->deltaRot * 값);
}

나사가 어느 쪽으로 회전하는지에 따라 앞 뒤로 이동하도록 할 것이기 때문에

나사가 음의 방향으로 회전하는지, 양의 방향으로 회전하는지 체크해줘야한다.

회전 값은 음의 방향으로 회전하면 음수가 나오고, 양의 방향으로 회전하면 양수가 나오기 때문에 그냥 이 회전 값을 그대로 곱해주기로 했다.

 

돌아는 간다.

이제 어떤 상태일 때 어느 방향으로 회전할지를 설정해주어야한다

728x90
반응형