はじめに
unityはディープリンクにも対応していますが、エディターには対応していませんでした。デバッグする際にエディターでも確認できると便利なので実装してみます。
やること
ディープリンクはURLを使ってアプリを開く仕組みです。通常「myapp://scheme」みたいに指定するところを、「http://localhost/scheme」と指定してもURLなので動くはずです。今回はエディターにwebサーバーを立てることで独自にディープリンクを処理させてみます。
webサーバーに関しては以下の記事の実装を使います。
ディープリンクのハンドリング
通常のハンドリングに加えて、webサーバーでもハンドリングできるようにします。
using System.Web; using UnityEngine; public class DeepLinkHandler : MonoBehaviour { public const int EditorSchemePort = 3333; public event System.Action<string> onDeepLinkRequest; #if UNITY_EDITOR Server m_Server; #endif private void OnEnable() { // 通常の処理 Application.deepLinkActivated += OnDeepLinkActivated; #if UNITY_EDITOR // エディター用の処理 m_Server = new Server(EditorSchemePort); m_Server.Route(new SchemeHandler(OnDeepLinkRequest)); m_Server.Start(); #endif } private void OnDisable() { // 通常の処理 Application.deepLinkActivated -= OnDeepLinkActivated; #if UNITY_EDITOR // エディター用の処理 m_Server.Stop(); #endif } void OnDeepLinkActivated(string url) { var uri = new System.Uri(url); var query = HttpUtility.ParseQueryString(uri.Query); var data = query.Get("data"); OnDeepLinkRequest(data); } void OnDeepLinkRequest(string data) { onDeepLinkRequest?.Invoke(data); } }
using System.Net; using System.Text; using System.Threading.Tasks; public class SchemeHandler : IRequestHandler { public string path => "/scheme"; public string method => "GET"; System.Action<string> m_Callback; public SchemeHandler(System.Action<string> callback) { m_Callback = callback; } public Task<bool> Handle(HttpListenerRequest req, HttpListenerResponse res) { var data = req.QueryString.Get("data"); res.StatusCode = 200; var text = Encoding.UTF8.GetBytes("success! open unity editor."); res.OutputStream.Write(text, 0, text.Length); res.Close(); m_Callback?.Invoke(data); return Task.FromResult(true); } }
動かしてみる
unityからブラウザを起動して、ブラウザからunityに処理を戻してみます。ついでにdata
も渡してみます。
server側
まずはwebページが必要なので、以下のようなindex.html
を作ります。
<html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1>My Deep Link Test page</h1> <p><a id="link" href="">unityに戻る</a></p> <script> const searchParams = new URLSearchParams(window.location.search); let scheme = searchParams.get("scheme"); scheme += "?data=ok"; document.getElementById("link").setAttribute("href", scheme); </script> </body> </html>
pythonで簡易サーバーを起動します。これでhttp://localhost:8080/
で上記HTMLのページが表示されます。
% cd test % python3 -m http.server --cgi 8080
note
const searchParams = new URLSearchParams(window.location.search); let scheme = searchParams.get("scheme"); scheme += "?data=ok";
ブラウザがアプリ起動に使うURLは、unityから渡してあげるようにします。ブラウザ側ではエディターから呼ばれたのか、アプリから呼ばれたのかわからないためです。
unity側
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Test : MonoBehaviour { [SerializeField] Text m_Message; [SerializeField] DeepLinkHandler m_DeepLinkHandler; void Start() { m_Message.text = "アイルビーバッグ"; } private void OnEnable() { m_DeepLinkHandler.onDeepLinkRequest += OnDeepLinkRequest; } private void OnDisable() { m_DeepLinkHandler.onDeepLinkRequest -= OnDeepLinkRequest; } public void OnOpenURL() { var scheme = "myapp://scheme"; #if UNITY_EDITOR scheme = "http://localhost:3333/scheme"; #endif Application.OpenURL(string.Format("http://localhost:8080?scheme={0}", scheme)); } void OnDeepLinkRequest(string data) { m_Message.text = string.Format("もどったぞ(data: {0})", data); } }
これで動きました。
おわり
ブラウザからエディターを操作してる感じがして、なんだか面白いです。ほかにも活かせそうだと思いました。