인프런 커뮤니티 질문&답변

jh park님의 프로필 이미지

작성한 질문수

Unreal GameThread 문의

23.11.25 14:44 작성

·

613

0

안녕하세요.

Unreal 공부 중 해결 되지 않는 문제가 있어 문의 드립니다.

  1. FRunnableThread를 생성

  2. Run()함수에서 FSocket 의 Recv함수를 호출

  3. 수신 된 데이터를 활용 해 Level 내 Actor의 상태를 변경

위 행위를 하였을 경우 GameThread가 아니여서 문제라는 오류가 발생 합니다.

언리얼에서 제공하는 GameThread에 함수를 등록하여 호출 할 수 있는 방법 또는

FRunnableThread에서 Actor의 상태를 변경 할 수 있는 방법이 있는지 질문 드립니다.

 

 

IsRunThread = FRunnableThread::Create(this, TEXT("Create Network Thread"));

uint32 FSocket::Run()

{

while (IsRunThread)

{ Recv(PacketData, BufferSize, BytesRead, ESocketReceiveFlags::None); }

..

SpawnActor(...);

}

 

 

답변 1

0

인프런 AI 인턴님의 프로필 이미지

2023. 11. 25. 14:51

안녕하세요, 인프런 AI 인턴입니다.

Unreal Engine에서 별도의 스레드에서 생성된 FRunnableThread 또는 그밖의 워커 스레드에서 메인 게임 스레드(GameThread)가 아닌 다른 스레드에서 Actor의 상태를 변경하려고 시도하면 동기화 문제로 인해 오류가 발생할 수 있습니다. 이를 해결하기 위해서는 GameThread에서만 Actor 상태를 변경하도록 해야 합니다.

다음 두 가지 방법을 활용하여 메인 게임 스레드에서 작업을 수행할 수 있습니다.

  1. AsyncTask를 사용하여 GameThread에서 작업 실행하기
    AsyncTask를 사용하면 별도의 스레드에서 GameThread에 작업을 예약할 수 있습니다. 이는 일반적으로 Lambda 함수를 통해 이루어지며, 이를 이용하여 워커 스레드에서 GameThread로 작업을 전환할 수 있습니다.
// 워커 스레드에서 GameThread로 작업을 이동하기 위한 코드 예시
AsyncTask(ENamedThreads::GameThread, [this]()
{
    // 이 안에서는 GameThread에서 실행되는 코드입니다.
    // Actor를 스폰하거나 상태를 변경하는 등의 작업을 안전하게 수행할 수 있습니다.
    SpawnActor(...);
});
  1. FGraphEventRef를 사용하여 GameThread에서 태스크 실행하기
    FGraphEventRef를 사용하면 복잡한 태스크 의존성을 처리하는 고급 방식으로, 스레드 간 태스크를 스케줄링하거나 결과를 동기화할 때 유용합니다. TGraphTask를 생성하여 TFunction을 넘겨주고 GameThread에서 실행하도록 할 수 있습니다.
// 워커 스레드에서 GameThread 태스크를 생성하는 코드 예시
FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady([]()
{
    // 이 안에서는 GameThread에서 실행되는 코드입니다.
    // Actor를 스폰하거나 상태를 변경하는 등의 작업을 수행합니다.
}, TStatId(), nullptr, ENamedThreads::GameThread);

두 방법 모두 GameThread에서 실행되도록 구현하여 Actor의 상태를 변경하거나 고유한 인터랙션을 게임에 통합할 수 있습니다.

이러한 방식으로 Actor의 상태를 안전하게 변경할 수 있으며, 메인 게임 스레드와 워커 스레드 간의 동기화 문제를 피할 수 있습니다.

jh park님의 프로필 이미지
jh park
질문자

2023. 12. 20. 17:32

답변 감사합니다.

 

알려주신 방법으로 정상적으로 GameThread에 Actor의 상태를 변경 할 수 있었습니다.

하지만 TCP 통신을 통해 수신 받은 Actor에 상태에 대해 처리하지 못하는 문제가 발생 하였습니다.

AsyncTask(ENamedThreads::GameThread, [this, PacketData, BytesRead]()

{

});

cline가 동시에 송신하는 3개의 이벤트 메시지에 대해 하나만 처리하는 문제가 발생 하였습니다.

ENamedThreads::GameThread를 ENamedThreads::AnyThread로 변경 시에는 3개의 이벤트 메시지가 정상적으로 수신 되는 것을 확인 할 수 있었지만 Actor의 상태를 변경하게 되면 오류가 발생합니다. 동시에 송신하는 메시지를 정상적으로 처리하는 방법에 대해 질문 드립니다.

감사합니다.

jh park님의 프로필 이미지

작성한 질문수

질문하기