Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

WebGL Copy - Paste for Input Field not working

Discussion in 'WebGL' started by MaT227, Sep 11, 2017.

  1. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Hi there,

    I am using Unity 2017.1.0p4 with TextMesh Pro from the Asset Store in WebGL.
    I am facing an issue with Copy - Paste. I am not able to copy something from outside the WebGL window inside an Input Field but it works if I copy something from Unity and past it inside the input.

    After a fast test here are the results.

    In Editor

    • UI InputField - Outside to Unity and Unity to Unity : OK
    • TextMeshPro Input FIield - Outside to Unity and Unity to Unity : OK
    WebGL
    • UI InputField - Outside to Unity : FAIL
    • TextMeshPro Input FIield - Outside to Unity : FAIL
    • UI InputField - Unity to Unity : OK
    • TextMeshPro Input FIield - Unity to Unity : OK
    It seems that it's more related to Unity itself than TextMesh Pro, does anybody have any idea about where does this comes from and if there's a way to fix this ?

    Thanks a lot !
     
  2. Schubkraft

    Schubkraft

    Unity Technologies

    Joined:
    Dec 3, 2012
    Posts:
    977
  3. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
  4. elhongo

    elhongo

    Joined:
    Aug 13, 2015
    Posts:
    35
  5. Deacon2099

    Deacon2099

    Joined:
    Nov 23, 2015
    Posts:
    3
    Here is a simple solution in two steps:
    1. create javascript library with function that calls javasript "prompt" window in which user can paste from clipboard.
    2. use "SendMessage" to send user's input from javascript to your Unity method.
    To do this first create file with extention .jslib and put it in Assets\Plugins folder in your project. Here is example code of this file:
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.  
    3.  
    4.   PasteHereWindow: function (sometext) {
    5.     var pastedtext= prompt("Please paste here:", "placeholder");
    6.     SendMessage("CopyPasteObject", "GetPastedText", pastedtext);
    7.   },
    8.  
    9. });
    Then in your scene create object with script that will activate javascript and then receive outcome (actually receiver can be different object and method than activator). In "SendMessage" you put name of obcject on your scene, method that is in any of scripts attached to this object and then the value (here string but can be other).

    This is example script for object called "CopyPasteObject":
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Runtime.InteropServices;
    3.  
    4. public class CopyPasteObjectScript : MonoBehaviour {
    5.  
    6.     [DllImport("__Internal")]
    7.     private static extern void PasteHereWindow(string gettext);
    8.  
    9.     string sometext = " xxxxxx ";
    10.  
    11.     private void OnGUI()
    12.     {
    13.         if(GUI.Button(new Rect(100, 100, 200, 50), "Press me, so you can paste text"))
    14.         {
    15.             PasteHereWindow("xxxx");
    16.         }
    17.         GUI.Label(new Rect(50, 50, 300, 50), "Your pasted text is: ");
    18.         GUI.Label(new Rect(150, 50, 300, 50), sometext);
    19.     }
    20.  
    21.     public void GetPastedText(string newpastedtext)
    22.     {
    23.         sometext = newpastedtext;
    24.     }
    25. }
    26.  
    You may receive some errors in Editor but it shold be fine when you Build and Run project.
     
    ina, Anh-Pham, savely00 and 1 other person like this.
  6. DerDrache

    DerDrache

    Joined:
    Aug 1, 2018
    Posts:
    1
    Tested it and it works for me, tyvm for sharing this code :)
     
  7. ina

    ina

    Joined:
    Nov 15, 2010
    Posts:
    958
    This should be included in Unity's WebGL templates or something

     
  8. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
  9. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    191
    CopyPaste.jslib
    Code (JavaScript):
    1. var CopyPastePlugin =
    2. {
    3.   CopyPasteReader: function(gObj, vName)
    4.   {
    5.       var gameObjectName = UTF8ToString(gObj);
    6.       var voidName = UTF8ToString(vName);
    7.       navigator.clipboard.readText().then(function(data) {
    8.         gameInstance.SendMessage(gameObjectName, voidName, data);
    9.       }, function() {
    10.         gameInstance.SendMessage(gameObjectName, voidName, "no text aviable in clipboard");
    11.       })
    12.   }
    13. };
    14. mergeInto(LibraryManager.library, CopyPastePlugin);

    in your code:
    Code (CSharp):
    1. [DllImport("__Internal")]
    2. public static extern void CopyPasteReader(string gObj, string vName);
    3.  
    4. //........
    5.  
    6. void Update()
    7. {
    8.     if (Input.GetKeyDown(KeyCode.V) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)))
    9.     {
    10.         CopyPasteReader("MYGAMEOBJECTNAME", "Paste");
    11.     }
    12. }
    13.  
    14. private void Paste(string pasteValue)
    15. {
    16.     Debug.Log(pasteValue);
    17. }
    18.  
    19.  
    Browser support, see here: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText

    Edit:
    It works only with https:// !!!
    Tested with Chrome, Firefox, Edge Opera and Safari.
    It works with Chrom and Opera. It does NOT work with Edge, Firefox and Safari ! (pearhaps someone else have a solution for this -> unknow funktion readText())
    online demo: https://standeditor.expoformer.ch/static/wp/copypaste/
     
    Last edited: Apr 10, 2019
  10. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    191
    Well, it seems navigator.clipboard.readText() is only aviable in Chrome and Opera yet.
    pearhaps i'ts a new feature and we have to wait.
     
  11. rpantaev

    rpantaev

    Joined:
    Oct 27, 2017
    Posts:
    4
    Kou-Yeung's solution works great without need for a paste clipboard. Simply add the WebGLSupport files to your assets and attach the script onto required inputfields. Nice job!
     
    tillmonkthered likes this.
  12. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    830
    Hello, i tried your package, it works for me only when the browser canvas is not in fullscreen mode. When in fullscreen mode it doesnt work,. Debugging shows that the text box no longer gets the focus, and no more messages when im typing into the text box. This happens once i click the zoom button below the game canvas on the browser.

    Before i click the zoom button everything works, i can type, copy, paste, everything, once i hit that zoom button everything stops working, any ideas what can cause that? Even if i come out of zoom it still dont work anymore.

    i did the same thing with your project and everything works even in zoom mode, i dont know whats wrong with mine!
     
  13. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
    thank you for report.
    i was comment in github issues.and have a workaround for fullscreen.
    > https://github.com/kou-yeung/WebGLInput/issues/2
    i will make it more simply...
     
  14. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    830
  15. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    1,698
    So this is a bit annoying (not the first major webgl unity issue hit)

    I will look at these solutions to allow pasting, but [again] could Unity please add built-in solutions?! @Schubkraft.
     
  16. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,401
    I don't think @kou-yeung's solution will work for me, because I don't have a standard Input field (I have a code editor; see https://miniscript.org/demo/ and click the Program button at the top).

    And @sumpfkraut's solution still doesn't work in the latest Firefox... I can't leave Firefox out; it's a major browser (and the one I happen to prefer).

    Note that copy/paste works within my WebGL app just fine... it's just that it can't exchange data with the system clipboard, and that makes it almost useless.

    Are there any other routes to explore?
     
  17. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    830
    I looked at your demo, im sure his copy/paste can work on your command line, isnt it a regular UI Input field?
     
  18. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,401
    No, I'm talking about the code editor. It is not a UI input field.
     
  19. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    830
    Maybe add a PASTE button, when user wants to paste they click that button, then you display a dialog box with a regular UI INPUT so they can paste into that using his method, then your code copies text from that into your custom code input.
     
    JoeStrout likes this.
  20. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
    from Firefox 63
    Firefox only supports reading the clipboard in browser extensions, using the "clipboardRead" extension permission.

    so,you can try the "Permissions API" to request permissions to use
    navigator.clipboard.readText()

    FYR:
    "Permissions API"
    https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API

    see the detail of readText and writeText
    https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText#Browser_compatibility
    https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText#Browser_compatibility

    *i will take a time to try it.
     
    Last edited: Jun 18, 2019
    rckprtr likes this.
  21. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    191
    This works with Chrome, Firefox, and Opera:
    Code (JavaScript):
    1. var CopyPastePlugin =
    2. {
    3.   CopyPasteReader: function(gObj, vName)
    4.   {
    5.       var gameObjectName = UTF8ToString(gObj);
    6.       var voidName = UTF8ToString(vName);
    7.       function getCpText( e )
    8.       {
    9.           e.preventDefault();
    10.           var pastedText = undefined;
    11.           if( window.clipboardData && window.clipboardData.getData )
    12.           {
    13.               pastedText = window.clipboardData.getData('Text');
    14.           }
    15.           else if( e.clipboardData && e.clipboardData.getData )
    16.           {
    17.               pastedText = e.clipboardData.getData('text/plain');
    18.           }
    19.           unityInstance.SendMessage(gameObjectName, voidName, pastedText);
    20.       }
    21.       if( navigator.userAgent.indexOf("Firefox") != -1 )
    22.       {
    23.           document.onpaste = getCpText;
    24.       }
    25.       else if( navigator.userAgent.indexOf("Edge") != -1 )
    26.       {
    27.           unityInstance.SendMessage(gameObjectName, voidName, "this browser is not supported.");
    28.       }
    29.       else if( navigator.userAgent.indexOf("Chrome") != -1 || navigator.userAgent.indexOf("Opera") != -1 )
    30.       {
    31.           navigator.clipboard.readText().then(function(data) {
    32.               unityInstance.SendMessage(gameObjectName, voidName, data);
    33.           }, function() {
    34.               unityInstance.SendMessage(gameObjectName, voidName, "no text aviable in clipboard");
    35.           })
    36.       }
    37.       else if( navigator.userAgent.indexOf("Safari") != -1 )
    38.       {
    39.           unityInstance.SendMessage(gameObjectName, voidName, "this browser is not supported.");
    40.       }
    41.       else
    42.       {
    43.           unityInstance.SendMessage(gameObjectName, voidName, "this browser is not supported.");
    44.       }
    45.   }
    46. };
    47. mergeInto(LibraryManager.library, CopyPastePlugin);
    For any reason (in Firefox) the first time you press Ctrl+V nothing happen. But then it works.
    Someone have a idea to fix this?
    Online Demo here: https://standeditor.expoformer.ch/static/wp/copypaste3/
     
    Last edited: Jun 18, 2019
    slidecrew and emidude like this.
  22. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,401
    Hmm, for me (in your demo) it doesn't work no matter how times I try. When I press cmd-V, the Edit menu highlights briefly, but no text appears. Using Firefox 67.0.2 (64-bit) on Mac.
     
    Last edited: Jul 26, 2019
  23. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    191
    Firefox 67.0.3 on windows works.
    Tested on different computers.
     
  24. tillmonkthered

    tillmonkthered

    Joined:
    Sep 5, 2017
    Posts:
    1
    This is working like a charm for me. Super easy. Thanks so much!
     
  25. joostbos

    joostbos

    Joined:
    Feb 4, 2015
    Posts:
    40
    @kou-yeung Thanks for this, great to have this functionality.

    To make things easier for my users I would like to use two buttons for copy and paste, rather than CTRL-C and CTRL-V. Could you help me with this? I have adapted the code for stand-alone and editor that I have used before. That uses a TextEditor. For use with WebGLInput I have tried the following, but that works strange :)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. //using WebGLSupport;
    6.  
    7. public class ClipboardButtonHandler : MonoBehaviour {
    8.     public InputField inputField;
    9.     //public WebGLInput webGlInputScript;
    10.  
    11.     // Use this for initialization
    12.     void Start () {
    13.        
    14.     }
    15.    
    16.     // Update is called once per frame
    17.     void Update () {
    18.        
    19.     }
    20.  
    21.     public void PasteFromClipboard()
    22.     {
    23.         inputField.GetComponent<WebGLSupport.WebGLInput>().OnSelect();
    24.  
    25.         var textEditor = new TextEditor();
    26.         textEditor.Paste();
    27.         textEditor.SelectAll();
    28.         inputField.text = textEditor.text;
    29.     }
    30.  
    31.     public void CopyToClipboard()
    32.     {
    33.         inputField.GetComponent<WebGLSupport.WebGLInput>().OnSelect();
    34.  
    35.         var textEditor = new TextEditor();
    36.         textEditor.text = inputField.text;
    37.         textEditor.SelectAll();
    38.         textEditor.Copy();
    39.     }
    40.  
    41. }
    I can copy and paste within the WebGL application from one field to another, but I can not copy to or paste from the clipboard.

    This is in the browser:

    WebGL Clipboard Copy Browser.png

    And this is the Unity setup. I attached the button handler script to the button itself and use the inputfield as parameter, so that I should have access to both the Unity inputfield and the WebGlInput or other script.
    WebGL Clipboard Copy Unity.png

    Thanks!
     
  26. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    7,635
    Just tried the WebGL IME solution which works but... The block of text data is losing formatting (line feeds) which is critical for parsing the data block in this case.

    Any ideas how to fix this, I suspect it's how the data is processed on the HTML side of things in the HTML text input field...?
     
  27. rckprtr

    rckprtr

    Joined:
    Apr 10, 2015
    Posts:
    1
    Amazing,

    I get an error:

    Uncaught TypeError: Cannot read property 'appendChild' of null

    I just added WebGLInput to the InputText object. Do I need to do anything else
     
  28. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
    1.can you tell me your Unity Version?

    2. are you edited canvas element id at index.html?
    because this plugins will add a input element to the canvas.
    after unity 2019.1 canvas id default is "unityContainer" ( FYR:https://github.com/kou-yeung/WebGLInput/blob/master/Assets/WebGLSupport/WebGLInput/WebGLInput.cs#L93 )
    if not found the element.it will throw "Cannot read property 'appendChild' of null".

    (maybe unity webgl templete has change the canvas id in the new version...
     
  29. Jinxology

    Jinxology

    Joined:
    Jul 13, 2013
    Posts:
    76
    Kou-yeung is correct. This error comes from using an old index.html WebGL template (in my case, a custom index.html). As of Unity 2019.1, the default index.html names the container "unityContainer" instead of "gameContainer". If you're using a custom or older index.html, just do a find/replace on that word and voila, works perfect.
    Thanks for this code!
     
  30. coldpizzapunk

    coldpizzapunk

    Joined:
    Aug 20, 2014
    Posts:
    25
    @kou-yeung
    FYI - I am using Unity 2020.1.0b5

    I get the error:
    TypeError: Cannot read property 'offsetWidth' of null at _WebGLInputCreate

    Looks like the container is now "unity-container"
    It works now that I changed that in the WEBGLInput.cs file.
     
    Racines and kou-yeung like this.
  31. greggman

    greggman

    Joined:
    Nov 30, 2013
    Posts:
    24
    I don't know if this works well but an attempt at a solution is to use the browser's copy and paste events. In paste pass that into Unity and append to the current InputField. On copy ask the inputfield to copy then pass unity's clipboard back to the browser

    Here's some code and a working example

    https://github.com/greggman/unity-webg-copy-and-paste

    note this solution is for `UnityEngine.UI.InputField` and `TMPro.TMP_InputField`. I didn't work on supporting any other text fields
     
    opponent019 likes this.
  32. Racines

    Racines

    Joined:
    Jan 20, 2014
    Posts:
    26
    Your solution work well for me, thanks for sharing it.
    I prefere this plugin instead of kou-yeung one because you still have access to the normal TMP feature like the mouse text selection.
    Also you don't need to add a script in each of your inputfield.

    @greggman Is it possible to implement a Tab hotkey feature to switch between inputfields?
     
  33. greggman

    greggman

    Joined:
    Nov 30, 2013
    Posts:
    24
  34. Racines

    Racines

    Joined:
    Jan 20, 2014
    Posts:
    26
    Yes you are probably right, thanks for the link
     
  35. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
    @Racines
    Because the purpose is different, @greggman 's solution is focus for copy & paste.
    my solution is focus for input "multibyte character set" (like Japanese).

    so, if you only use for "copy & paste". @greggman 's solution is good.
    but want to work for input "multibyte character set" i think my solution is good.

    thank you~
     
  36. Racines

    Racines

    Joined:
    Jan 20, 2014
    Posts:
    26
    @kou-yeung Thank you for clarification. I made some research about IME. In my case I have in my game a chat that support Asian languages. So I guess I need to support IME? Or Asian have other solution?
     
  37. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
    @Racines for Asian support IME is best, but you need test your "chat api" and DB can support multibyte character set or not.
    ( for commercial. maybe neet to check NG word for user text input....

    Of course, it is understood that it does not support IME. if it is made by overseas studio.:)
     
  38. Racines

    Racines

    Joined:
    Jan 20, 2014
    Posts:
    26
    @kou-yeung ok thanks for the informations. I will try to use your plugin when an Asian language is detected.
    I already checked the support for Chinese/Korean/Japanese font and database. I just did not knew about the need to support IME for webgl!
     
    kou-yeung likes this.
  39. filler03

    filler03

    Joined:
    Jul 27, 2011
    Posts:
    3
    Where is the WebGLSupport.unitypackage file? I am not seeing it on github.
     
  40. kou-yeung

    kou-yeung

    Joined:
    Sep 5, 2016
    Posts:
    21
  41. JazzCat-9

    JazzCat-9

    Joined:
    Sep 1, 2015
    Posts:
    12
    Kou-Yeung, thank you!!!! Your code was an absolute godsend for a crazy little free project I’m working on!!!!

    I dropped it in just as the README said to do, dragged it to my inputField, and it worked like a charm in my tests on both desktop/Firefox and iPad/Safari!

    Thank you for helping all of us! (My project would have stalled without this!!!)
     
    kou-yeung likes this.
  42. Hines94

    Hines94

    Joined:
    Feb 15, 2020
    Posts:
    4
    Hi all,
    Is there a way of adding a button to trigger copy or paste events on the input field?
    I have tried to look through kou-yeung's code but I cant find the right section
     
    GerDavid likes this.
  43. GerDavid

    GerDavid

    Joined:
    Aug 15, 2019
    Posts:
    6
    This works if you use copy button inside unity and paste into browser? i want that functionality, i use the @greggman approach for copy/paste but i cant make it work for this purpose using button to copy text from inputfield and paste into browser.
     
  44. GerDavid

    GerDavid

    Joined:
    Aug 15, 2019
    Posts:
    6
    @Hines94 do you find a way to make it work with copy button?
     
unityunity