Visual Studio 2019에서 EOS를 위한 C# 솔루션 설정하기

에픽게임즈 테크니컬 어카운트 매니저 Rajen Kishna |
2021년 9월 28일
이 시리즈의 이전 연재글에서는 에픽 온라인 서비스(EOS)를 시작하기 위해 에픽게임즈 개발자 포털에 등록하는 방법을 설명했습니다. 계정 설정을 마쳤으니 이제 Visual Studio 2019를 설정하고 C#으로 WPF 솔루션을 생성하는 방법을 알려드리겠습니다. 이를 통해 모든 EOS 서비스를 탐색할 수 있습니다. 단계를 진행하면서 이전 연재글에서 다룬 중요 사항도 염두에 두시기 바랍니다. 이 연재글에서는 다루는 내용은 다음과 같습니다.

Visual Studio 2019 설치하기

설치하지 않았다면 https://visualstudio.microsoft.com/으로 이동하여 Visual Studio 2019를 다운로드하세요. Microsoft에서는 개인 및 특정 조직에 무료 커뮤니티 에디션을 제공하므로 화면 하단으로 스크롤하여 자격 요건을 확인하세요. 사용할 프로그래밍 언어에 따라 몇 개의 워크로드 및 컴포넌트가 필요합니다.
 
  • C++
    • 데스크톱 & 모바일 > C++로 데스크톱 개발
      • 우측 사이드바의 선택 사항에서 반드시 MSVC v141 - VS2017 C++ x64/x86 빌드 툴(v14.16)을 체크하세요. EOS SDK 샘플에서 이 빌드 툴을 사용합니다.
    • 게이밍 > C++로 게임 개발
  • C#
    • 데스크톱 & 모바일 > .NET 데스크톱 개발
VS2019 Workloads
Visual Studio 2019 워크로드
VS2019 MSVC141 Component
Visual Studio 2019 워크로드

EOS SDK C++ 및 C# 샘플을 컴파일하고 실행할 것이므로 상단의 모든 워크로드와 컴포넌트를 설치하세요.

SDK 다운로드하기

Visual Studio 설치 중에 개발자 포털에서 SDK를 다운로드할 수 있습니다. 별도의 언급이 없는 한, 이 연재글에서는 SDK 1.14.1을 사용합니다.
  1. https://dev.epicgames.com/portal/에서 개발자 포털에 로그인합니다.
  2. 좌측 메뉴에서 ‘SDK’를 선택합니다. SDK에서는 C, C#, iOS 및 Android SDK 다운로드와 제품 개요(SDK에 필요한 크리덴셜에 대한 간단한 개요 포함), SDK 변경 로그를 확인할 수 있습니다.
  3. SDK 버전 드롭다운 메뉴에서 ‘C SDK’를 선택하고 ‘다운로드’를 클릭합니다. C# SDK를 비롯한 기타 플랫폼도 같은 방식으로 작업합니다. 이 시리즈에서는 C#에 집중하지만, 다른 플랫폼에도 동일한 개념을 적용할 수 있습니다.
  4. 원하는 위치에 SDK를 저장하고 압축을 해제합니다.

SDK 폴더마다 Samples, SDK, ThirdPartyNotices라는 세 개의 하위 폴더가 있습니다. Samples 하위 폴더에는 플랫폼에 대한 솔루션 또는 프로젝트가 있으며, C SDK는 가장 포괄적인 샘플 세트를 제공합니다. SDK 하위 폴더에는 SDK 자체에 대한 바이너리, 라이브러리, 헤더 및 소스가 포함되며, Tools 폴더에는 개발자 인증 툴, 파일 복호화 툴, 안티 치트 무결성 툴재배포가 있습니다. ThirdPartyNotices에는 SDK에서 사용하는 서드 파티 소프트웨어 고지를 설명하는 텍스트 파일이 있습니다.

SDK 샘플 컴파일하기

SDK를 다운로드하고 Visual Studio를 설치한 상태에서 샘플을 컴파일하면, 모든 요소가 올바르게 설정되었는지 빠르게 확인하고 참조를 통해 특정 기능을 자세히 알아볼 수 있습니다.
  1. Visual Studio 2019의 C SDK ‘Samples‘ 폴더에서 ‘Samples.sln‘ 파일을 열어 시작합니다.
  2. 솔루션이 열린 상태에서 ‘Ctrl+Shift+B‘를 누르고 모든 프로젝트를 빌드합니다. 이때 각 프로젝트에 다음과 같은 오류 메시지 팝업이 표시될 수 있습니다.

Error MSB8036 The Windows SDK version 10.0.17763.0 was not found. Install the required version of Windows SDK or change the SDK version in the project property pages or by right-clicking the solution and selecting "Retarget solution".
  1. 이 오류를 해결하려면 ‘Solution Explorer‘에서 해당 솔루션 노드를 우클릭하고 ‘Retarget solution‘을 클릭합니다. 여기에서 설치한 Windows SDK 버전을 선택하면 되고(여기서는 10.0.19041.0), 필요에 따라 플랫폼 툴세트를 v142로 업그레이드할 수도 있습니다. 설정 중에 툴세트 v141를 이미 설치했으니 툴세트는 업그레이드하지 않겠습니다.
VS2019 Retarget Solution
C SDK 샘플용 리타깃 솔루션

 
  1. 솔루션이 리타깃되면 ‘Ctrl+Shift+B‘를 눌러 빌드합니다.
샘플을 실행하기 전에 크리덴셜을 입력해야 합니다. C SDK 샘플 프로젝트에서 각 프로젝트에 있는 Source\\SampleConstants.h 파일에 크리덴셜을 입력할 수 있습니다. 개발자 포털의 ‘SDK’ 페이지에서 제품 옆에 있는 ‘크리덴셜 가져오기’ 버튼을 클릭하여 모든 값을 빠르게 찾을 수 있습니다.

VS2019 SDK Credentials
SDK 페이지의 크리덴셜 가져오기 버튼

또는, 제품으로 이동한 후 좌측 메뉴의 ‘제품 세팅’을 클릭하여 값을 찾을 수도 있습니다. 제품 ID, 샌드박스 ID, 디플로이 ID, 클라이언트 ID, 클라이언트 암호가 필요합니다.

다음은 C# SDK 샘플을 컴파일하겠습니다.
  1. Visual Studio 2019의 C# SDK ‘Samples‘ 폴더에서 ‘Samples.sln‘ 파일을 열어 시작합니다.
  2. 여기서는 별다른 문제가 없어야 정상이니, ‘Ctrl+Shift+B‘를 눌러 모든 프로젝트를 빌드합니다.

C# 샘플 프로젝트는 모두 동일한 크리덴셜을 공유하며, 크리덴셜은 ‘Settings.cs‘의 ‘Common‘ 프로젝트에 있습니다.

C# 솔루션 설정하기

설치와 테스트가 끝났으니, C# 솔루션 설정을 시작할 차례입니다.
  1. Visual Studio 2019의 새 인스턴스를 열고 ‘Create a new project’를 선택합니다.
  2. 템플릿 검색(Alt+S) 검색창에서 ‘wpf‘를 입력하고 WPF Application [C#] [Windows] [Desktop] 항목을 클릭합니다. ‘Next’를 클릭하여 계속합니다.
  3. 프로젝트 이름(예: EOSCSharpSample), 위치 및 솔루션 이름(프로젝트 이름 기본값)을 입력합니다. ‘Next’를 클릭하여 계속합니다.
  4. 타깃 프레임워크로 ‘.NET Core 3.1(Long-term support)’을 선택하고 ‘Create’를 클릭하여 솔루션 생성을 완료합니다.
  5. ‘Solution Explorer‘에서 해당 솔루션 노드를 우클릭하고 ‘File Explorer‘에서 ‘Open Folder’를 클릭합니다. ‘SDK‘라는 새 폴더를 만들고 다운로드한 C# SDK의 SDK\\Source 하위 폴더를 여기에 복사합니다. 이 파일을 프로젝트에 포함해야 합니다.
  6. 복사한 SDK 소스 및 래퍼 파일을 포함하기 위해 프로젝트 파일을 수정하겠습니다. ‘Solution Explorer‘에서 해당 프로젝트 노드를 우클릭하고 ‘Edit Project File’을 클릭합니다.
  7. 다음 XML을 기존 ‘PropertyGroup‘ 노드 옆에 있는 ‘Project‘ 노드 내에 복사합니다.

<ItemGroup>
    <Compile Include="..\\SDK\\Source\\Core\\**">
        <Link>SDK\\Core\\%(RecursiveDir)%(Filename)%(Extension)</Link>
  </Compile>
  <Compile Include="..\\SDK\\Source\\Generated\\**">
    <Link>SDK\\Generated\\%(RecursiveDir)%(Filename)%(Extension)</Link>
  </Compile>
</ItemGroup>

 
  1. 다음으로는 SDK에 타기팅할 플랫폼을 알리기 위해 조건부 컴파일 기호를 추가해야 합니다. ‘Solution Explorer‘에서 해당 프로젝트 노드를 우클릭하고 ‘Properties’를 클릭합니다.
  2. 좌측의 ‘Build’ 탭을 클릭하고 EOS_PLATFORM_WINDOWS_32(또는 EOS_PLATFORM_WINDOWS_64)를 조건부 컴파일 기호 텍스트 상자에 입력합니다. 이에 따라 플랫폼 타깃을 매칭해야 하므로 드롭다운에서 x86(또는 x64)을 선택합니다.
  3. 마지막으로 SDK 바이너리를 애플리케이션에 포함해야 합니다. 이를 위해 다운로드한 C# SDK의 SDK\\Bin 하위 폴더에서 EOSSDK-Win32-Shipping.dll(또는 EOSSDK-Win64-Shipping.dll) 파일을 ‘Solution Explorer‘의 프로젝트에 복사합니다.
  4. ‘Solution Explorer‘에서 추가된 DLL을 클릭하고 ‘Copy to Output Directory’ 속성을 ‘Copy if newer’로 변경합니다.
  5. ‘Ctrl+Shift+B‘로 솔루션을 빌드하여 전부 컴파일되는지 확인하고 오류가 있다면 수정합니다.

간단한 Model-View-ViewModel 설명자

명확성과 모듈성을 유지하기 위해 Model-View-ViewModel 아키텍처 패턴으로 솔루션을 설정하고 각 서비스의 기능을 빌드하겠습니다. MVVM을 사용한 적이 없더라도, 잘 알려드릴 테니 걱정할 필요 없습니다. 다음은 사용할 개념에 대한 간단한 요약입니다.
 
  • 명령 - 코드 실행을 위해 View의 버튼에 바인딩할 기능
  • 변환기 - 원하는 변환(예: 빈 문자열을 false 부울 값으로 변환)에 따라 한 유형(예: 문자열)을 다른 유형(예: 부울)으로 변환하는 도우미 기능
  • 도우미 - ViewModel의 기본 변수 변경 시 UI 업데이트에 도움이 되는 INotifyPropertyChanged의 구현과 같은 일반 도우미 기능
  • 서비스 - 기능에 대한 주 클래스
  • ViewModel - View에서 사용할 값과 명령 인스턴스에 대한 컨테이너
  • View - 사용자에게 표시되는 UI 컴포넌트

이러한 개념을 구현하면서 기능을 설명하겠습니다.

EOS SDK 초기화

솔루션 설정을 마무리하기 위해 EOS SDK 초기화 코드를 구현하겠습니다. 그래야 이후 연재글에서 EOS 서비스를 더 추가할 수 있습니다.

EOS 기능은 서비스별 기능의 논리적 그룹을 제공하는 인터페이스로 그룹화됩니다. EOS의 기본 인터페이스를 플랫폼 인터페이스라고 하며, 다른 모든 인터페이스에 대한 액세스를 제공합니다. 이를 위해 우선 SDK를 초기화하고 애플리케이션 전체에서 사용할 수 있는 플랫폼 인터페이스의 인스턴스를 생성해야 합니다.
  1. ApplicationSettings.cs라는 프로젝트의 루트에 새 클래스를 추가하면서 시작합니다. 각 설정에 대해 자체 SDK 크리덴셜을 드롭해야 합니다.
public class ApplicationSettings
{

    public string ProductId { get; private set; } = "";

    public string ClientId { get; private set; } = "";
    public string ClientSecret { get; private set; } = "";

    public string SandboxId { get; private set; } = "";

    public string DeploymentId { get; private set; } = "";

    public PlatformInterface PlatformInterface { get; set; }

    public void Initialize(Dictionary<string, string> commandLineArgs)
    {
        // 전달했다면 명령줄 실행인자를 사용합니다
        ProductId = commandLineArgs.ContainsKey("-productid") commandLineArgs.GetValueOrDefault("-productid") : ProductId;
        SandboxId = commandLineArgs.ContainsKey("-sandboxid") commandLineArgs.GetValueOrDefault("-sandboxid") : SandboxId;
        DeploymentId = commandLineArgs.ContainsKey("-deploymentid") commandLineArgs.GetValueOrDefault("-deploymentid") : DeploymentId;
        ClientId = commandLineArgs.ContainsKey("-clientid") commandLineArgs.GetValueOrDefault("-clientid") : ClientId;
        ClientSecret = commandLineArgs.ContainsKey("-clientsecret") commandLineArgs.GetValueOrDefault("-clientsecret") : ClientSecret;
        }
}

 
  1. 이 파일은 SDK 크리덴셜, 주 PlatformInterface 인스턴스(SDK의 코어로서 다른 모든 서비스에 대한 액세스 제공), 명령줄 초기화 코드를 트래킹합니다. 에픽게임즈 스토어에 게임을 퍼블리싱하는 경우, 사용자 ID 같은 명령줄 실행인자를 통해 게임에 정보를 전달합니다. 앞으로 이 파일을 사용하여 초기화 변수(인증 크리덴셜 유형 및 범위 등)를 추적할 것입니다.
  2. 구문을 통해 파일에 관련 사항을 추가하여 알 수 없는 유형을 전부 해결합니다.
  3. 다음으로 프로젝트의 루트에 ‘ApplicationResources.xaml‘이라는 새로운 Resource Dictionary(WPF) 파일을 추가합니다. 지금은 비워 두어도 되지만, 이를 통해 이후 연재글에서 사용할 변환기에 참조를 추가할 것입니다. ‘App.xaml‘을 열고 다음 XAML을 포함하여 새 ‘ResourceDictionary‘를 추가합니다.
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionarySource="/ApplicationResources.xaml"/>
          </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
</Application.Resources>

 
  1. ‘App.xaml.cs‘를 열고 다음 코드를 삽입하여 ‘ApplicationSettings‘에 정적 참조를 만들고 전달되는 명령줄 실행인자를 파싱합니다.

public partial class App : Application
{

    public static ApplicationSettings Settings { get; set; }

    protected override void OnStartup(StartupEventArgs e)
    {
        // (존재한다면) 명령줄 실행인자를 가져와 기본 세팅을 덮어씁니다
        var commandLineArgsDict = new Dictionary<string, string>();
        for (int index = 0; index < e.Args.Length; index += 2)
        {
            commandLineArgsDict.Add(e.Args[index], e.Args[index + 1]);
        }

        Settings = new ApplicationSettings();
        Settings.Initialize(commandLineArgsDict);

        base.OnStartup(e);
    }
}
  1. 마지막으로 ‘MainWindow.xaml.cs‘를 사용하여 SDK를 설정하고 초기화합니다. 타이머를 추가하여 게임 틱을 시뮬레이션하면서 시작하겠습니다. EOS SDK는 이 타이머를 사용하여 서비스 호출에 대한 콜백 메서드를 트리거합니다.

private DispatcherTimer updateTimer;
private const float updateFrequency = 1 / 30f;
  1. 창 닫기 이벤트에 대한 이벤트 핸들러를 추가하여 PlatformInterface 인스턴스를 해제하고 셧다운 프로세스를 완료합니다.

public MainWindow()
{

    InitializeComponent();

    Closing += MainWindow_Closing;
}

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{

    App.Settings.PlatformInterface.Release();
     App.Settings.PlatformInterface = null;

    _ = PlatformInterface.Shutdown();
}
  1. MainWindow가 인스턴스화되면 SDK를 설정할 수 있도록 InitializeApplication() 함수를 정의할 것입니다.

private void InitializeApplication()
{

    var initializeOptions = new InitializeOptions()
    {
        ProductName = "EOSCSharpSample",
        ProductVersion = "1.0.0"
    };


        var result = PlatformInterface.Initialize(initializeOptions);
        Debug.WriteLine($"Initialize: {result}");

        _ = LoggingInterface.SetLogLevel(LogCategory.AllCategories, LogLevel.Info);
        _ = LoggingInterface.SetCallback((LogMessage message) => Debug.WriteLine($"[{message.Level}] {message.Category} - {message.Message}"));

    var options = new Options()
    {
        ProductId = App.Settings.ProductId,
        SandboxId = App.Settings.SandboxId,
        ClientCredentials = new ClientCredentials()
        {
            ClientId = App.Settings.ClientId,
            ClientSecret = App.Settings.ClientSecret
        },
        DeploymentId = App.Settings.DeploymentId,
         Flags = PlatformFlags.DisableOverlay,
        IsServer = false
    };

    PlatformInterface platformInterface PlatformInterface.Create(options);

    if (platformInterface == null)
    {
        Debug.WriteLine($"Failed to create platform. Ensure the relevant settings are set.");
    }

    App.Settings.PlatformInterface = platformInterface;

    updateTimer = new DispatcherTimer(DispatcherPriority.Render)
    {
        Interval = new TimeSpan(0, 0, 0, 0, (int)(updateFrequency * 1000))
    };

    updateTimer.Tick += (sender, e) => Update(updateFrequency);
    updateTimer.Start();
}


분석해 보겠습니다.
  • 일반적으로 EOS 서비스 호출은 Options 클래스의 인스턴스화로 구성되며, 호출 중인 함수로 전달됩니다. 여기서는 InitializeOptions를 인스턴스화해서 PlatformInterface의 Initialize() 함수로 전달하고 있습니다.
  • 이 함수는 즉시 결과를 반환하지만, 보통 서비스 호출에서 콜백 함수를 파라미터로 가져오며, 함수가 완료되면 트리거됩니다. 다음 연재글에서는 그 예시인 인증을 살펴보겠습니다.
  • 다음으로는 로깅 인터페이스로 로그를 받을 방법을 정의하겠습니다. 샘플 애플리케이션에서 모든 로그 메시지는 디버그 출력 창에 출력되지만, 여기에서 파일에 로그 쓰기를 설정하거나 이 작업을 수행할 클라우드 서비스를 설정할 수 있습니다.
  • 이후 ‘PlatformInterface.Create‘를 사용하여 동일한 Options -> 호출 패턴을 반복하여 PlatformInterface를 만들고 이후 앱 전체에서 검색할 수 있도록 ‘App.Settings‘의 인스턴스에 저장합니다.
  • 마지막으로 updateFrequency의 간격(여기서는 1/30)을 사용하는 타이머를 설정하고, 틱 이벤트 핸들러를 설정하고 시작합니다. 여기서는 API 콜백의 응답성을 위해 게임 틱 속도가 동일하도록 이 간격을 설정하겠습니다. SDK는 스레드로부터 안전하지 않으며 모든 SDK 호출은 이를 초기화한 동일한 스레드에서 이루어져야 합니다.
  1. 타이머 틱 이벤트 핸들러는 PlatformInterface Tick 메서드를 호출하여 비동기 콜백이 성공적으로 호출되도록 합니다.

private void Update(float updateFrequency)
{

    App.Settings.PlatformInterface?.Tick();
}
  1. 마지막으로 ‘MainWindow‘ 생성자에 InitializeApplication()에 대한 호출을 추가합니다.

이 시점에서 애플리케이션을 컴파일하고 실행할 수 있어야 하고, 디버그 출력 창에 다음과 같은 초기화 성공 로그 메시지가 표시되어야 합니다.

Initialize: Success
[Info] LogEOSOverlay - Overlay will not load, because it was explicitly disabled when creating the platform
[Info] LogEOSAntiCheat - [AntiCheatClient] Anti-cheat client not available. Verify that the game was started with the correct launcher if you intend to use it.
[Info] LogEOS - Updating Platform SDK Config, Time: 0.368525
[Info] LogEOS - SDK Config Platform Update Request Successful, Time: 0.821195
[Info] LogEOSAnalytics - Start Session (User: ...)
[Warning] LogEOSAnalytics - EOS SDK Analytics disabled for route [1].
[Info] LogEOS - Updating Product SDK Config, Time: 0.866974
[Info] LogEOSAnalytics - Start Session (User: ...)
[Info] LogEOS - SDK Config Product Update Request Successful, Time: 1.350656
[Info] LogEOS - SDK Config Data - Watermark: 82749226
[Info] LogEOS - ScheduleNextSDKConfigDataUpdate - Time: 1.350656, Update Interval: 325.699646

MVVM 아키텍처 빌드하기

이 연재글을 마무리하기 전에, 향후 연재글에서 추가 기능을 쉽게 삽입할 수 있도록 MVVM 아키텍처를 빌드해야 합니다.
  1. 프로젝트의 루트에 ‘Helpers‘라는 폴더를 만들고 시작합니다.
  2. 여기에서 MVVM 구현에 도움이 되는 도우미 클래스 두 개를 만들겠습니다. 이 기능을 다루지는 않겠지만, 다른 연재글에서 쉽게 찾아볼 수 있습니다. ‘BindableBase.cs‘라는 새 클래스를 만듭니다.

public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Equals(storage, value)) return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var eventHandler = PropertyChanged;
        if (eventHandler != null)
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
    }
}
  1. 다음으로 ‘CommandBase.cs‘라는 클래스를 만듭니다.

public class CommandBase : ICommand
{
    public virtual bool CanExecute(object parameter)
    {
        throw new NotImplementedException();
    }

    public virtual void Execute(object parameter)
    {
        throw new NotImplementedException();
    }

    public event EventHandler CanExecuteChanged;
    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, new EventArgs());
    }
}
  1. 이 두 클래스를 만든 뒤, 프로젝트의 루트에 ‘ViewModels‘라는 폴더를 만듭니다. 여기에 둘을 참조할 ViewModels와 ViewModelLocator 클래스를 저장할 것입니다. ‘MainViewModel.cs‘라는 클래스를 생성하면서 시작합니다.

public class MainViewModel : BindableBase
{
    private string _statusBarText;
    public string StatusBarText
    {
        get { return _statusBarText; }
        set { SetProperty(ref _statusBarText, value); }
    }

    public MainViewModel()
    {
    }
}

 
  1. 다음으로는 ‘ViewModelLocator.cs‘라는 클래스를 만듭니다.

public static class ViewModelLocator
{
    private static MainViewModel _main;
    public static MainViewModel Main
    {
        get { return _main ??= new MainViewModel(); }
    }
}
  1. 다음으로는 일부 UI 자동화에 도움이 되는 변환기를 몇 개 만듭니다. 프로젝트의 루트에 ‘Converters‘라는 폴더를 만들고 ‘StringToBooleanConverters.cs‘라는 클래스를 추가합니다.

[Bindable(BindableSupport.Default)]
public class StringToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || !(value is string))
        {
          return false;
        }

    ​​​​​​​    ​​​​​​​​​​​​​​​​​​​​​string stringValue = value as string;

    ​​​​​​​    ​​​​​​​​​​​​​​return !string.IsNullOrWhiteSpace(stringValue.Trim());
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
    ​​​​​​​    ​​​​​​​​​​​​​​​​​​​​​throw new NotImplementedException();
    }
}
  1. 그리고 ‘StringToVisibilityConverter.cs‘라는 클래스를 만듭니다.

[Bindable(BindableSupport.Default)]
public class StringToVisibilityConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
    ​​​​​​​    ​​​​​​​if (value == null || !(value is string))
        {
    ​​​​​​​    ​​​​​​​    ​​​​​​​return Visibility.Collapsed;
        }

    ​​​​​​​    ​​​​​​​string stringValue = value as string;

    ​​​​​​​    return string.IsNullOrWhiteSpace(stringValue.Trim()) ? Visibility.Collapsed : (object)Visibility.Visible;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
    ​​​​​​​    ​​​​​​​throw new NotImplementedException();
    }
}
  1. 마지막으로 프로젝트의 루트에서 ‘ApplicationResources.xaml‘을 열고 다음 XAML로 대체합니다. 프로젝트의 이름이 EOSCSharpSample로 지정되지 않았다면 xmlns:c="..." 옆의 네임스페이스를 변경해야 합니다.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:c="clr-namespace:EOSCSharpSample.Converters">

    <c:StringToVisibilityConverter x:Key="StringToVisibilityConverter" />
    <c:StringToBooleanConverter x:Key="StringToBooleanConverter" />

</ResourceDictionary>

코드 다운로드

아래에서 이 연재글에 쓰인 코드를 찾을 수 있습니다. ‘C# 솔루션 설정하기‘ 섹션의 5~9단계를 따라 솔루션에 SDK를 추가해야 하며, ApplicationSettings.cs를 편집하여 SDK 크리덴셜을 포함해야 합니다.
다음 연재글에서는 에픽 계정으로 로그인할 수 있도록 계정 서비스를 다뤄보겠습니다. 시리즈의 모든 연재글에 대한 간단한 개요는 첫 연재글의 시리즈 참조를 확인하시기 바랍니다.

    여러분의 성공이 곧 에픽의 성공입니다

    에픽은 통합되고 열려 있는 게임 커뮤니티를 지향합니다. 저희는 이 온라인 서비스를 누구나 이용할 수 있도록 무료로 제공함으로써 더 많은 개발자들이 자신만의 플레이어 커뮤니티를 서비스할 수 있도록 지원하는 것을 목표로 하고 있습니다.