UnityのWebGL環境でコピペが上手くいかなかったので,クリップボードに小細工をしてみる
経緯
Unity + WebGLでクリップボードを使おうとしたところ,GUIUtility.systemCopyBuffer
はUnity独自のクリップボードを使っているようで,通常のクリップボードとの連携ができませんでした.調べてみると,WebGLInputパッケージなどを使うとInputField
ではコピペできるようですが,私の環境では上手く動作しませんでした.
そこで,クリップボードの共有機能を自作することにしました.
概要
構造としてはこんな感じで実装します.
- Unity側のクリップボードを監視し,コピーされたら通常のクリップボードに上書きする処理
- 通常のクリップボードを監視し,コピーされたらUnity側のクリップボードに上書きする処理
実装方法
まずは,Unityでの処理を書いていきます.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;
public class CopyPaste : MonoBehaviour
{
#if UNITY_WEBGL && !UNITY_EDITOR
//コピー
[DllImport("__Internal")]
private static extern void CopyWebGL(string str);
//ペースト
[DllImport("__Internal")]
private static extern void PasteWeb();
private string unityClip;
private string webClip;
void Start()
{
unityClip = "";
webClip = "";
PasteWeb();
}
void Update()
{
if(GUIUtility.systemCopyBuffer != unityClip){
unityClip = GUIUtility.systemCopyBuffer;
CopyWebGL(unityClip);
Debug.Log("Copy unity to clip");
}
PasteWeb();
}
public void paste(string text){
if(text != webClip){
webClip = text;
GUIUtility.systemCopyBuffer = webClip;
}
}
#else
#endif
}
これを適当なゲームオブジェクトに張り付けておきます.
次にPluginsフォルダに以下のCopyWebGL.jslib
ファイルを作成します.
mergeInto(LibraryManager.library, {
CopyWebGL: function(str) {
if(navigator.clipboard){
navigator.clipboard.writeText(str) //httpでは使えない(httpsのみ)
.then(function(text){
});
}else{
var str = Pointer_stringify(str);
var listener = function(e){
e.clipboardData.setData("text/plain" , str);
e.preventDefault();
document.removeEventListener("copy", listener);
}
document.addEventListener("copy" , listener);
document.execCommand("copy");
}
},
PasteWeb: function() {
if(navigator.clipboard){
navigator.clipboard.readText()
.then(function(text){
SendMessage('CopyPaste', 'paste', text);
//クリップボードから取得したテキストを渡す(ゲームオブジェクト名,メソッド名,クリップボードの値)
});
}
}
});
これでクリップボードの共有ができるようになりました.
あとは,普通にGUIUtility.systemCopyBuffer
を使えばUnity外部ともコピペできます.
所感
コピペは問題なくできますが,Webページのロード時にクリップボードへのアクセス許可が必要になってしまいました.セキュリティ的な問題だと思いますので,早く公式の方で直感的にクリップボードが使える機能を実装してほしいものです…