Back to Blog

언리얼 엔진 내에서 비디오 통화 앱을 설계하세요

Blueprint a Video Call App Inside Unreal Engine

개발자 여러분, 이 데모에서는 Unreal Engine과 Agora SDK 플러그인을 사용하여 비디오 통화 앱을 만드는 단계별 과정을 안내해 드리겠습니다.

이 예제에서는 Unreal Engine 5.1과 현재 버전의 아고라 SDK를 사용하겠습니다.

시작하기

  1. Unreal Engine을 여기에서 다운로드하세요
  2. Agora 플러그인을 여기에서 다운로드하세요
  3. Agora 계정을 생성하세요

프로젝트 생성

UI Blueprint 위젯이 구현된 기본 C++ Unreal Engine 프로젝트를 생성했습니다. 빠른 시작을 위해 이 GitHub 리포지토리를 클론하세요. Unreal Engine 5 에디터로 프로젝트를 열 수 있습니다. 모든 것을 처음부터 빌드하려면 다음 단계를 따르세요:

  1. Unreal Editor를 열고 '새 프로젝트'를 클릭합니다
  2. 새 프로젝트 패널에서 프로젝트 유형으로 C++를 선택하고 프로젝트 이름을 입력한 후 프로젝트 위치를 선택하고 '프로젝트 생성'을 클릭합니다.
Blueprint a Video Call App Inside Unreal Engine - 1
Figure 1: Create a Project

기본 프로젝트에서 우리는 다음과 같은 디자인을 적용한 Introduction 위젯과 VideoCall 위젯을 사용할 것입니다. 이 위젯에는 Blueprint 그래프가 포함되어 있지 않다는 점을 주의해 주세요.

Blueprint a Video Call App Inside Unreal Engine - 2
Figure 2: Introduction Widget Blueprint
Blueprint a Video Call App Inside Unreal Engine - 3
Figure 3: VideoCall Widget Blueprint

GuestView는 VideoCall 위젯에서 더 큰 이미지 표시 상자로 표시되고 SelfView는 더 작은 상자로 표시되는 것은 디자인 선택 사항입니다.

기본 프로젝트 설정에서 빈 Level GameLevel을 사용합니다. 모든 것을 저장하고 현재는 Unreal Editor를 종료합니다.

설치

  1. 플러그인을 아직 설치하지 않았다면 여기에서 다운로드하세요.
  2. 플러그인을 [your_project]/Plugins 폴더로 복사합니다. 프로젝트 구조는 [project_name]/Plugins/AgoraPlugin과 같아야 합니다.
  3. [your_project]/Source/[project_name]/[project_name].Build.cs 파일의 Dependencies 섹션에 플러그인 의존성을 추가합니다. Dependencies 섹션에는 다음과 같은 설정이 포함되어야 합니다:
  1. 프로젝트를 다시 열고 추가한 모듈을 재컴파일하라는 메시지가 표시되면 재컴파일합니다.
  2. 편집 > 플러그인으로 이동합니다.
  3. 프로젝트 > 기타 카테고리를 찾아 AgoraPlugin이 활성화되어 있는지 확인합니다.
Blueprint a Video Call App Inside Unreal Engine - 4
Figure 4: AgoraPlugin

게임 모드 생성

게임 모드는 위젯 간 전환에 사용됩니다. Content 폴더 아래에 새로운 폴더를 생성하고 Blueprints 디렉토리로 이름을 지정합니다. 오른쪽 클릭하여 GameMode를 부모 클래스로 하는 새로운 클래스를 생성합니다:

Blueprint a Video Call App Inside Unreal Engine - 5
Figure 5: GameMode

이 새로운 클래스를 GameMode_BP로 이름 지정하세요.

Blueprint a Video Call App Inside Unreal Engine - 6
Figure 6: GameMode_BP

게임 모드 구현

GameMode_BP로 돌아가서 기능 섹션 앞의 +를 클릭하여 두 개의 기능을 추가합니다. 이 기능을 SetIntroductionViewSetVideoCallView로 이름 지정합니다. IntroductionWidget_BPVideoCallWidget_BP라는 두 개의 변수를 추가하고, 이 변수의 유형을 각각 Introduction Widget BPVideo Call Widget BP로 변경합니다:

Blueprint a Video Call App Inside Unreal Engine - 7
Figure 7: GameMode BP Variables

다음과 같이 기능을 구현하십시오:

Blueprint a Video Call App Inside Unreal Engine - 8
Blueprint a Video Call App Inside Unreal Engine - 9

다음으로, 편집 > 프로젝트 설정으로 이동하여 프로젝트 맵과 모드를 새로운 클래스로 업데이트합니다:

Blueprint a Video Call App Inside Unreal Engine - 10
Figure 9: Project Settings

게임 레벨의 생명 주기 구현

GameLevel은 AgoraRtcEngine의 생명 주기와 이벤트 처리 논리를 포함합니다. 최상위 수준에서는 레벨에 대한 Begin PlayEnd Play 이벤트를 구현해야 합니다.

Begin Play

Begin Play 이벤트 동안 발생하는 주요 동작은 네 부분으로 구성됩니다:

  • Pretask (그림 10): 마우스 커서를 설정합니다. Unreal Engine 내장 함수 SetInputModeUIOnly를 사용하여 UI 제어용으로 마우스 커서가 표시되도록 합니다.
  • RTC 엔진 인스턴스 생성(그림 11): GameMode 인스턴스를 GameMode_EP 클래스로 캐스팅하고 변수로 승격합니다. 그런 다음 AgoraRtcEngine 인스턴스를 생성하고 변수 RtcEngine으로 승격하며, GameMode_EP 인스턴스에 복사본을 생성합니다. 다음으로 IRtcEngineEvent 핸들러 인스턴스를 생성하고 변수 EventHandler로 선언합니다. 이 레벨 블루프린트에 BindAgoraEvent 함수를 생성합니다. EventHandler 변수를 생성한 후 이 함수를 호출합니다. BindAgoraEvent 함수는 나중에 구현할 것입니다.
  • 위젯 생성 (그림 12): IntroductionWidget_BP와 VideoCallWidget_BP를 생성하고 GameMode_EP 인스턴스에 저장합니다. BindUIEvent 함수를 생성하고 이 함수를 노드로 연결합니다. BindUIEvent 함수는 나중에 구현할 것입니다.
  • GameMode Set (그림 13): 두 위젯 참조를 GameMode 인스턴스에 저장하고 IntroductionWidget_BP를 뷰포트에 추가합니다. 이로써 게임이 실행될 때 Introduction 위젯의 UI가 표시됩니다. 이벤트의 마지막 단계로 SetAgoraVersionText 함수를 생성합니다. 구현 방법은 그림 14를 참조하세요.
Blueprint a Video Call App Inside Unreal Engine - 11
Figure 10: BeginPlay Pretask
Blueprint a Video Call App Inside Unreal Engine - 12
Figure 11: Create RTC Engine
Blueprint a Video Call App Inside Unreal Engine - 13
Figure 12: Construct Widgets
Blueprint a Video Call App Inside Unreal Engine - 14
Figure 13: GameMode Set

버전 인쇄

RtcEngine 인스턴스의 GetVersion 함수를 호출하여 SetAgoraVersiontext 함수를 구현합니다. 반환된 값을 “Agora SDK Version:” 문자열에 추가하고 Introduction 위젯 BP의 텍스트를 설정합니다.

Blueprint a Video Call App Inside Unreal Engine - 15
Figure 13b: Version Printing

게임 종료

게임 플레이가 종료되면 Agora RTC 엔진이 해제되어야 합니다. 이 작업을 제대로 수행하지 않으면 Unreal Editor에서 게임을 다시 실행할 때 게임이 충돌할 수 있습니다. 이벤트 호출은 단순히 figure 16에 구현된 ReleaseRtcEngine 함수를 호출합니다.

Blueprint a Video Call App Inside Unreal Engine - 16
Figure 14: End Play
Blueprint a Video Call App Inside Unreal Engine - 17
Figure 15: Release Rtc Engine

체크포인트 1

블루프린트가 컴파일되는지 확인합니다. 그런 다음 플레이 버튼을 클릭하여 프로젝트를 실행합니다. 화면 오른쪽 상단에 Agora 엔진의 SDK 버전 번호가 표시된 다음 화면이 표시되어야 합니다:

Blueprint a Video Call App Inside Unreal Engine - 18
Figure 16: IntroductionWidget test

아고라 콜백 구현

아고라 이벤트에 대한 다양한 콜백 핸들러의 구현을 제공하여 BindAgoraEvents 함수를 처리합니다. 먼저 EventHandler 변수를 Blueprint 편집기 캔버스로 드래그합니다. EventHandler 출력 포트에서 이벤트를 OnJoinChannelSuccess에 바인딩합니다. 입력 포트 Event를 드래그하여 이벤트를 생성합니다. Function > Create Matching Function을 선택합니다. 그림 17을 참조하세요.

Blueprint a Video Call App Inside Unreal Engine - 19
Figure 17: Create OnJoinChannelSuccess

함수의 본체는 나중에 제공하겠습니다. 이제 동일한 단계를 사용하여 이 Blueprint 그래프에 추가 이벤트를 바인딩합니다. 이 데모에서는 다음 네 가지 이벤트만 구현합니다:

  • OnJoinChannelSuccess
  • OnUserJoined
  • OnUserOffline
  • OnLeaveChannel
Blueprint a Video Call App Inside Unreal Engine - 20
Figure 18: Bind Agora Event (1)
Blueprint a Video Call App Inside Unreal Engine - 21
Figure 19: Bind Agora Event (2)

채널 가입 성공

이 이벤트는 로컬 사용자가 채널에 성공적으로 가입할 때 트리거됩니다. 다음 작업을 수행합니다:

  1. (선택 사항) 메시지를 화면에 표시합니다.
  2. UI 위젯을 VideoCall로 전환합니다 (함수 SetVideoCallView; 그림 8 참조).
  3. 웹캠 비디오 스트림을 SelfView 이미지 상자에 렌더링합니다(함수 SetupLocalUserView; 그림 21 참조).
  4. 사용자가 채널에 가입하기 전에 세션에서 웹캠을 꺼둔 경우, SelfView에 기본 이미지를 표시합니다(함수 CleanupLocalUserView; 그림 22 참조).
Blueprint a Video Call App Inside Unreal Engine - 22
Figure 20: OnJoinChannelSuccess

SetupLocalUserView

이 함수는 RtcEngine 인스턴스에서 SetupLocalVideo 유틸리티 함수를 호출합니다. Canvas 입력은 VideoCanvas 인스턴스를 생성하여 제공되며, 이 인스턴스는 VideoCallWidget의 SelfView 객체를 뷰 렌더러로 사용합니다.

Blueprint a Video Call App Inside Unreal Engine - 23
Figure 21: SetupLocalUserView

CleanupLocalUserView

이 기능은 SelfView 이미지 객체의 슬레이트 브러시를 재할당하여 뷰를 지웁니다.

Blueprint a Video Call App Inside Unreal Engine - 24
Figure 22: CleanupLocalUserView

OnLeaveChannel

이 이벤트는 로컬 사용자가 채널을 떠날 때 트리거됩니다. 해당 로직은 뷰를 정리하는 것입니다. 사용자가 채널에 가입할 때마다 SelfView가 정리되기 때문에, 이 호출 시에는 원격 사용자의 뷰만 정리합니다.

Blueprint a Video Call App Inside Unreal Engine - 25
Figure 23: OnLeaveChannel

원격 사용자 보기 정리

이 기능은 CleanupLocalUserView와 매우 유사합니다. 비디오 콜 위젯의 게스트 보기가 여기에서 재설정됩니다.

Blueprint a Video Call App Inside Unreal Engine - 26
Figure 24: CleanupRemoteUserView

OnUserJoined

이 이벤트는 원격 사용자가 채널에 가입할 때마다 트리거됩니다. 이 데모에서는 통화 중에 하나의 원격 사용자만 처리합니다. 통화 중에 있는 원격 사용자를 기억하기 위해 RemoteUID라는 변수를 정의합니다. 통화 중에 아무도 없을 경우 0이 할당됩니다. RemoteUID가 0인 경우에만 들어오는 비디오 스트림을 렌더링합니다(SetupRemoteUserView 함수).

Blueprint a Video Call App Inside Unreal Engine - 27
Figure 25: OnUserJoined

원격 사용자 보기 설정

이 함수는 원격 사용자의 UID를 받아 RtcEngine의 유틸리티 함수 SetupRemoteView에 전달하여 GuestView 객체에 들어오는 원격 비디오 스트림을 렌더링합니다.

Blueprint a Video Call App Inside Unreal Engine - 28
Figure 25b: SetupRemoteUserView

사용자가 오프라인 상태가 되면

원격 사용자가 오프라인 상태가 되면 렌더링이 중단되며, CleanupRemoteUserView 메서드를 호출하여 GuestView가 재설정됩니다(그림 24 참조).

Blueprint a Video Call App Inside Unreal Engine - 29
Figure 26: OnUserOffline

아고라 라이프사이클 완료

실제 RTC 세션은 소개 위젯 인터페이스에서 Join 버튼이 클릭될 때 시작됩니다. 구현 세부 사항을 살펴보겠습니다.

OnJoinButtonClicked

이 이벤트는 앞서 언급한 BindUIEvent 호출에 바인딩되어 있습니다. RtcEngines JoinChannel 함수를 최종적으로 호출하기 전에 다음 단계를 고려해야 합니다:

  1. RTC 엔진을 초기화합니다(InitRtcEngine 함수 참조).
  2. 비디오와 오디오를 활성화합니다.
  3. 로컬 사용자의 카메라 및 마이크 설정과 연관된 MediaOption 플래그를 업데이트합니다(UpdateMediaOptionFlags 함수 참조).
  4. UI 텍스트 필드에서 채널 이름을 가져와 JoinChannel 호출에 사용합니다.

Blueprint a Video Call App Inside Unreal Engine - 30
Figure 27: OnJoinButton Clicked (1)
Blueprint a Video Call App Inside Unreal Engine - 31
Figure 28: OnJoinButtonClicked (2)

InitRtcEngine

Blueprint a Video Call App Inside Unreal Engine - 32
Figure 29: InitRtcEngine

UpdateMediaOptionFlag

소개 위젯에서 두 개의 체크박스(CameraCheck 및 MicrophoneCheck)를 정의했습니다. 이 체크박스는 로컬 사용자가 카메라와 마이크 입력을 비활성화할 수 있도록 합니다. 이 옵션의 값은 JoinChannel 호출 시 MediaOptions 플래그로 전달됩니다. 이 함수는 UI의 논리를 번역하는 기능을 제공합니다. 참고로 이 함수는 true/false 값을 직접 받지 않습니다. 입력으로 AgoraOptional이라는 사용자 정의 유형이 필요합니다. 따라서 번역된 값을 저장하기 위해 CameraPublishEnumMicPublishEnum 변수를 사용합니다.

Blueprint a Video Call App Inside Unreal Engine - 40
Figure 30: Update MediaOption (1)
Blueprint a Video Call App Inside Unreal Engine - 34
Figure 31: UpdateMediaOptions (2)

체크포인트 2

플레이 버튼을 클릭하여 프로젝트를 컴파일하고 실행합니다. Join 버튼을 클릭하면 화면에 “유효한 앱 ID를 입력해 주세요”라는 오류 메시지가 표시됩니다. 이는 앱 ID가 누락된 경우의 오류 사례를 확인합니다. Agora 개발자 콘솔에서 생성한 앱 ID를 입력합니다. 이 테스트 환경에서는 테스트 모드 앱 ID를 사용합니다. 이제 로컬 사용자로 채널에 참여하고 SelfView 표시 상자에 표시되어야 합니다. 다른 클라이언트를 사용하여 원격 사용자로 참여하세요. 이 테스트에는 Agora의 웹 데모 클라이언트를 사용하는 것을 권장합니다. 이제 블로그 초반에 보여드린 대로 통화가 정상적으로 작동해야 합니다. 하지만 아직 완료되지 않았습니다. VideoCall 위젯의 구현을 완료해야 합니다.

VideoCall 위젯 구현

통화 중의 논리를 이 위젯 블루프린트에 포함시킬 것입니다. 사용자가 통화 중 음소거/음소거 해제 또는 앱을 닫지 않고 통화를 종료할 수 있도록 하는 것이 중요합니다. VideoCall 위젯의 세 개의 버튼이 이 기능을 수행합니다.

먼저 GameMode_BP 인스턴스의 참조를 저장한 후 버튼을 초기화합니다.

Blueprint a Video Call App Inside Unreal Engine - 35
Figure 32: Construct VideoCall BP

UpdateButtonState

이전 JoinChannel 호출에서 저장된 Boolean 변수 CameraEnabled와 MicrophoneEnabled를 사용하여 버튼의 텍스트를 업데이트합니다.

Blueprint a Video Call App Inside Unreal Engine - 36
Figure 33: UpdateButtonState

OnClicked (CameraButton)

비디오 기능의 다양한 전환을 처리하기 위해 세 개의 Agora API가 호출됩니다:

  • MuteLocalVideoStream: 아웃바운드 비디오 스트림이 중단되지만, 카메라를 켜는 것은 여전히 가능합니다.
  • EnableLocalVideo: 로컬 카메라를 켜고 끄는 스위치입니다.
  • PublishVideoTrack (ChannelMediaOptions 내): 이 설정은 통화 중 카메라를 사용할 수 있는지 여부를 결정합니다. 채널에 참여할 때 이 설정이 false로 설정되어 있다면, EnableLocalVideo 또는 MuteLocalVideoStream을 호출해도 카메라가 켜지지 않으며 비디오 스트림이 전송되지 않습니다. 로컬 비디오를 캡처하고 전송하려면 UpdateMediaOption을 호출하여 음소거를 해제해야 합니다.
Blueprint a Video Call App Inside Unreal Engine - 37
Figure 34: Camera Button Clicked

OnClick (마이크 버튼)

카메라 버튼과 유사하게, 마이크 버튼은 세 개의 마이크 입력 단자를 사용하며 유사한 블루프린트 그래프를 적용합니다:

  • MuteLocalAudioStream: 출력 비디오 스트림이 중단되지만, 카메라 자체는 여전히 켜질 수 있습니다.
  • EnableLocalAudio: 로컬 마이크를 켜고 끄는 스위치입니다.
  • PublishMicrophoneTrack (ChannelMediaOptions 내): PublishCameraTrack의 설명과 유사합니다.
Blueprint a Video Call App Inside Unreal Engine - 38
Figure 35: Microphone Button Clicked

OnClicked (뒤로 버튼)

뒤로 버튼은 사용자 인터페이스를 첫 번째 화면(소개 위젯 뷰)으로 돌아가게 합니다. 이 버튼을 클릭하면 Agora 채널을 떠나며 콜 세션을 종료합니다.

Blueprint a Video Call App Inside Unreal Engine - 39
Figure 36: Back Button Clicked

체크포인트 3

데모가 완료되었습니다. 음소거 버튼이 정상적으로 작동하는지 확인하고 소개 화면으로 돌아가 채널에 다시 연결할 수 있는지 확인하세요. 잘하셨습니다!

결론

이 간단한 데모는 Agora가 제공하는 API와의 통합을 포함한 UI 구현의 몇 가지 단계로 구성되어 있습니다. 언리얼 엔진 애플리케이션을 통해 비디오 통화로 사람들과 연결하는 것은 재미있는 경험입니다. 배포를 위한 빌드 패키징 방법은 이 GitHub Readme 파일을 참고하여 Agora Unreal SDK로 게임을 패키징하는 최신 정보를 확인하세요. 이 완료된 데모는 리포지토리의 AgoraBlog 브랜치에서 액세스할 수 있습니다. 의견이나 질문은 GitHub 페이지에서도 제기할 수 있습니다. 읽어주셔서 감사합니다!

RTE Telehealth 2023
Join us for RTE Telehealth - a virtual webinar where we’ll explore how AI and AR/VR technologies are shaping the future of healthcare delivery.

Learn more about Agora's video and voice solutions

Ready to chat through your real-time video and voice needs? We're here to help! Current Twilio customers get up to 2 months FREE.

Complete the form, and one of our experts will be in touch.

Try Agora for Free

Sign up and start building! You don’t pay until you scale.
Try for Free