🥽

【Unity】MetaQuest2上のアプリケーションでTCP通信をする

2023/12/08に公開

概要

PCVRではなく、MetaQuest2上で動作するアプリからTCP通信をするときにハマったので解決策を紹介しようと思います。
OpenXR Pluginパッケージのバージョンの違いにより設定方法が変わるようです。OpenXR Plugin 1.8.1以前をお使いの方は OpenXR 1.8.1以前の場合 を参照ください[1]

環境

Windows11
MetaQuest2
Unity2022.3.14f1
OpenXR Plugin 1.9.1

設定のやり方

  1. Project Settingsを開き
    Player -> Other Settings-> Internet Access
    をAutoからRequireに

  2. また、Project Settingsから
    XR Plug-in Management -> OpenXR
    AndroidタブからMeta Quest Supportの歯車マークを選択

Force Remove Internet Permissionのチェックボックスを外します

操作は以上です。
念のため、Clean Buildをしておきましょう。

OpenXR 1.8.1以前の場合

未検証です。

  1. Project Settingsを開き
    Player -> Other Settings-> Internet Access
    をAutoからRequireに

  2. Player -> Publishing SettingsCustom Main Manifestのチェックボックスをオンにして、
    Assets -> Plugins -> AndroidにあるAndroidManifest.xmlに以下を追加します。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools">
    <application>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

試す

スクリプトを記述します

SelfIPAddr.cs
using System.Net;
using TMPro;
using UnityEngine;

public class SelfIPAddr : MonoBehaviour
{
    public TMP_Text IpAddrText;
    void Start()
    {
        IpAddrText.text = "";
        
        IPHostEntry ipEntry = Dns.GetHostEntry(Dns.GetHostName());
        foreach (var ipAddr in ipEntry.AddressList)
        {
            IpAddrText.text += $"IP Address {ipAddr}\n";
        }
    }
}

やっていることは単純で、Dns.GetHostEntry(Dns.GetHostName())で情報を取得したあとにIPアドレスのリストをforeachでぐるぐる回してテキストに書き込んでいます。

適当なGameObjectを用意して先程のスクリプトをアタッチします。
また、適当なCanvasとTMPのTextを用意してIpAddrTextプロパティにセットします。

PC上で実行するとTextにPCのプライベートIPアドレスが表示されると思います。
また、MetaQuestで実行するとMetaQuestのプライベートIPアドレスが表示されるはずです。
127.0.0.1になる場合は設定が間違っています。

おわりに

MetaQuestで通信しようと思ったら日本語の情報が全然なくてすごい困りました。
特に、Force Remove Internet Permissionの設定項目が新しいバージョンによって増えたせいで余計に混乱しました。
この記事が誰かのお役に立てれば幸いです。

参考にしたもの

https://forum.unity.com/threads/unity-removes-android-permission-internet-in-the-build-apk-after-build-is-completed.1466654/
https://www.reddit.com/r/vrdev/comments/s60zrc/oculus_quest_2_not_allowing_tcp_socket/
https://www.reddit.com/r/OculusQuest/comments/iyfs21/tcp_connection/
https://answers.unity.com/questions/875062/tcp-data-sending-with-android.html
https://stackoverflow.com/questions/37493936/android-internet-permission-in-unity

脚注
  1. https://docs.unity3d.com/Packages/com.unity.xr.openxr@1.8/changelog/CHANGELOG.html#181---2023-06-09 ↩︎

Discussion