LoginSignup
15
14

More than 3 years have passed since last update.

UE4のOnlineSubsystemをさわってみた

Last updated at Posted at 2019-05-27

UE4でネットワークとボイスチャットを利用したくてOnlineSubsystemを触ってみてたので内容をメモしておく。
UE4初心者なのとざっくり触ってみたうえで書いた内容なので過不足ありそう。
Windowsデスクトップ環境とOculus Goの環境で1:1通信で試した。
UE4.22.1かUE4.22.2の環境で確認。

ボイスチャット

基本的には[UE4] UE 4.19 でアップデートされたボイスチャット機能について|株式会社ヒストリアを参照した試した。

試す際にはまったところ

  • CreateSessionのPublicConnectionsやFindSessionsのMaxResultsを0より大きくする必要あり
  • OpenLevelのOptionsでListenを指定する必要あり
  • リンク先にもちゃんと書いてあるけどコンソールコマンド open を使ってサーバー IP アドレスを直接指定して接続する方法では利用不可(実際にできなかった)
  • Oculus Go(Android)でボイスチャットを試す場合、設定でExtra Permissionsにandroid.permission.RECORD_AUDIO設定が必要

音量の設定

[2020/06/23追記、UE4.25.1で確認]

SoundClassを作成してVolumeを調整し
[Edit] > [Project Settings] > [Audio] > [VOIP Sound Class]に設定する。
ボイスチャットの音量が小さい場合があったので上記の方法で調整した。

音声がちゃんと聞こえない時は

[2020/06/23追記、UE4.25.1で確認]

接続の帯域幅設定がデフォルトで低く音声パケットが破棄されるらしいので以下のような感じでDefaulEngine.iniに設定が必要(値は要調整)

 [/Script/Engine.Player]
  ConfiguredInternetSpeed=800000
  ConfiguredLanSpeed=800000

  [/Script/OnlineSubsystemUtils.IpNetDriver]
  MaxClientRate=800000
  MaxInternetClientRate=800000

[2021/10/28追記、UE4.25.4で確認]

単語間で音声が停止したりところどころ聞こえないような場合は以下を設定

[SystemSettings]
voice.SilenceDetectionThreshold=0.01
voice.MicNoiseGateThreshold=0.01

自分の音声のミュート、アンミュート

[2020/07/16追記、UE4.25.1で確認]

以下のようにしてできる。
Voice Chat (VoIP) using Platform Solutions参照

Online::GetVoiceInterface()->StopNetworkedVoice(0); // ミュート
Online::GetVoiceInterface()->StartNetworkedVoice(0); // アンミュート

OnlineSubsystemNull

接続範囲

  • FindSessionsで検索できる範囲はbroadcastが届くサブネットの範囲
    • 単一サブネットの家庭内LANなどでは可、複数のサブネットに分割された企業LANなどでは不可
  • コンソールでopen IPアドレスでサブネット範囲外に接続できるがボイスチャットは使えない

WindowsのFindSessionsでセッションが見つからない

OnlineSubsystemSteam

接続手順

基本的には公式サイトのドキュメントを参照すればいいがSetup Unreal Engine for Steam Multiplayer Game – takoji3 – Mediumが参考になる。

  • PCにSteamアプリが入っていてログインしておく必要がある。
  • うまく接続できると右下にsteamのアイコンがポップアップしPlayerStateのPlayerNameがsteamアカウントのものになる。
  • 基本FindSessionsなどでLanモードをオフにする方が良さそう(オンだと接続できなかったりした)

接続範囲

shippingビルド時の接続

shippingビルド版をローカルで動かす場合はビルドした結果のWindowsNoEditr/Binaries/Win64/steam_appid.txtを追加してアプリIDの数字を入れておく。
Steamにリリースする場合は不要そう。
Steam shipping build only works when adding steam_appid.txt - UE4 AnswerHub参照

OnlineSubsystemOculus

接続手順

基本的には公式サイトの手順参照

アプリの作成と設定

  • RiftかGoにあわせてアプリを作成する。
  • RiftとGo間で通信する場合はそれぞれのアプリを作成してグループ化しておく必要がある。
  • テストに使うOculusアカウントを登録しておく。
  • アプリの[プラットフォームサービス]>[ルームとマッチメイク]の設定でプールを作成しておく。
    • プールキーはメモしておく。
    • Should Pool Manage Rooms?ははいにしておく。

oculuspoolsetting.PNG

コンフィグの設定

公式サイトのDefaultEngine.iniの設定に追加して以下のサイトの設定を追加する。
Oculus Platform Features and Online Subsystems

  • VoIP
DefaultEngine.ini
[OnlineSubsystem]
DefaultPlatformService=Oculus
bHasVoiceEnabled=true

[Voice]
bEnabled=true
  • p2p
DefaultEngine.ini
[/Script/Engine.GameEngine]
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemOculus.OculusNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")

[/Script/OnlineSubsystemOculus.OculusNetDriver]
NetConnectionClassName="OnlineSubsystemOculus.OculusNetConnection"

プラグインの設定

基本的にはOnlineSubsystemOculusをオンにすればよい。
Oculus Audioプラグインは一応オンにしてるけど必要性は未検証。

RiftとGo用にAppIDを使い分ける

DefaultEngine.iniのOnlineSubsystemOculusセクションにRiftAppIdにRift用アプリのIDを設定、GearVRAppIdにGo用アプリのIDを設定する。

OnlineSubsystemOculus.cppを見ると以下のようになっている

[EditorDIR]/Engine/Plugins/Online/OnlineSubsystemOculus/Source/Private/OnlineSubsystemOculus.cpp

FString FOnlineSubsystemOculus::GetAppId() const
{
    // Try to get the platform specific field before the generic one
#if PLATFORM_WINDOWS
    auto AppId = GConfig->GetStr(TEXT("OnlineSubsystemOculus"), TEXT("RiftAppId"), GEngineIni);
#elif PLATFORM_ANDROID
    auto AppId = GConfig->GetStr(TEXT("OnlineSubsystemOculus"), TEXT("GearVRAppId"), GEngineIni);
#endif
    if (!AppId.IsEmpty()) {
        return AppId;
    }
#if PLATFORM_WINDOWS
    UE_LOG_ONLINE(Warning, TEXT("Could not find 'RiftAppId' key in engine config.  Trying 'OculusAppId'.  Move your oculus app id to 'RiftAppId' to use in your rift app and make this warning go away."));
#elif PLATFORM_ANDROID
    UE_LOG_ONLINE(Warning, TEXT("Could not find 'GearVRAppId' key in engine config.  Trying 'OculusAppId'.  Move your oculus app id to 'GearVRAppId' to use in your gearvr app make this warning go away."));
#endif
    return GConfig->GetStr(TEXT("OnlineSubsystemOculus"), TEXT("OculusAppId"), GEngineIni);
}

セッションの接続

ブループリントを利用した接続ではデフォルトのFindSessions、CreateSessionの代わりにOculusのFind Matchmaking Sessions、Create Sessionを使ってそれぞのOculus Matchmakeing Poolに作成したプールのキーを指定する。

UE4 Blueprints - Oculus Find Sessions Matchmaking (0 results found) — Oculus参照

うまくいくとCreateSessionでPlayerStateのPlayerNameがOculusアカウントのものになる。

Oculus GoでFindSessionやCreateSessionで失敗する

以下のサイトにあるようにUE4 Editorから起動ではできない。
パッケージ化してGoにインストールして起動する必要がある(リリースチャンネルを使うと楽、アルファテストが格段に捗るリリースチャンネルの使い方【OculusGo】 - Qiita参照)。
The user isn't signed in — Oculus参照

ボイスチャット

以下のサイトにあるようにブループリントからは不可でC++から実施する必要がある。
Cannot join an Oculus session: "Cannot map local player to unique net ID" — Oculus
android.permission.RECORD_AUDIOの権限追加が必要か未検証。

ひとまず以下のようなC++とブループリントで接続できた。

[プロジェクト名].Build.cs
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class VoiceChatOculusCpp : ModuleRules
{
    public VoiceChatOculusCpp(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string[] 
        {
            "Core", 
            "CoreUObject", 
            "Engine", 
            "InputCore", 
            "HeadMountedDisplay",
            "LibOVRPlatform",
            "OnlineSubsystem",
        });

        PrivateDependencyModuleNames.AddRange(new string[]
        {
            "OnlineSubsystemOculus",
        });
    }
}
サードパーソンのCharactor.h
...

class AVoiceChatOculusCppCharacter : public ACharacter
{
    ...

public:
    ...
    UFUNCTION(BlueprintCallable)
    bool RegisterRemoteTalker(FString PlayerId);

    UFUNCTION(BlueprintCallable)
    FString GetNetId();
};
サードパーソンのCharactor.cpp
...
#include "Online.h"
#include "OVR_Platform.h"

...

bool AVoiceChatOculusCppCharacter::RegisterRemoteTalker(FString PlayerId)
{
    auto uniqueNetId = Online::GetIdentityInterface()->CreateUniquePlayerId(PlayerId);
    UE_LOG(LogTemp, Log, TEXT("uniqueNetId=%s"), *(uniqueNetId->ToString()));
    return Online::GetVoiceInterface()->RegisterRemoteTalker(*uniqueNetId);
}

FString AVoiceChatOculusCppCharacter::GetNetId()
{
    auto uniqueNetId = Online::GetIdentityInterface()->GetUniquePlayerId(0);
    if (!uniqueNetId.IsValid()) {
        return FString(TEXT(""));
    }

    uint64* RawUniqueId = (uint64*)uniqueNetId->GetBytes();
    ovrID OculusId(*RawUniqueId);
    char Idstr[21];
    ovrID_ToString(Idstr, sizeof(Idstr), OculusId);
    return FString(ANSI_TO_TCHAR(Idstr));
}

OnlineSubsystemOculusVoiceChatBP.PNG

TestEventはサーバーで実行に設定し、クライアント側で自分のOculusユーザのID取得してサーバー側からそのIDに接続している。

接続範囲

OculusPlatformについて - Qiitaにもあるように基本Oculusデバイスでの利用になる。

その他のOnlineSubsystemXXX

UE4エディタのサポートしている範囲だと[EditorDIR]/Engine/Plugins/Online/OnlineSubsystemXXX/Source/Private/OnlineSubsystemXXX.cppかPublic/OnlineSubsystemXXX.hあたりを見たがセッションやボイスチャットはサポートしてなさそうだった。

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14