{"id":337532,"date":"2022-08-26T09:00:17","date_gmt":"2022-08-26T09:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=337532"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=337532","title":{"rendered":"<span>Unity: \u0412\u044b\u0431\u043e\u0440 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430 WebGL \u0441\u0431\u043e\u0440\u043a\u0435<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431 \u043a\u0430\u043a \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0444\u0430\u0439\u043b\u044b, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b. \u0418 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0435\u043c \u0442\u0435\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 JS \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u0437 C# \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 Unity.<\/p>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f js \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 Plugins, \u044d\u0442\u043e <a href=\"https:\/\/docs.unity3d.com\/2017.2\/Documentation\/Manual\/SpecialFolders.html\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b .jslib, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0448 JS \u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 JS \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437:<\/p>\n<p>[DllImport(&#171;__Internal&#187;)] static extern void [JSFunctionName]();  , \u0433\u0434\u0435 [JSFunctionName] &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 .jslib .<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443, \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u0437 C# \u0432 JS \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0438\u043c\u044f GameObject \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<p>MyGameInstance.SendMessage(&#8216;MyGameObject&#8217;, &#8216;MyFunction&#8217;, [var]);  , \u0433\u0434\u0435 MyGameObject &#8212; \u0438\u043c\u044f \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, MyFunction &#8212; \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, [var] &#8212; \u0447\u0438\u0441\u043b\u043e \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a GameObject.<a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/GameObject.SendMessage.html\" rel=\"noopener noreferrer nofollow\">SendMessage()<\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 .jslib \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 mergeInto(), \u043f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<pre><code class=\"javascript\">mergeInto(LibraryManager.library,  { \/\/ Your code here   Hello: function () {     window.alert(\"Hello, world!\");   } });<\/code><\/pre>\n<p>\u0418\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">var SomeObject = { \/\/ Your code here   Hello: function () {     window.alert(\"Hello, world!\");   } };  mergeInto(LibraryManager.library, SomeObject);<\/code><\/pre>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/docs.unity3d.com\/Manual\/webgl-interactingwithbrowserscripting.html\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 Unity<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0432\u0435\u0442<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435\u0441\u044c Visual Studio, \u0442\u043e \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u044f .jslib \u0444\u0430\u0439\u043b\u043e\u0432 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u0441 JavaScript \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3d5\/14a\/81e\/3d514a81e2178919a4ef66a81287d3b5.png\" width=\"1309\" height=\"221\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3d5\/14a\/81e\/3d514a81e2178919a4ef66a81287d3b5.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u0431\u0430\u0437\u0443, \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0412\u044b \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JS \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0438\u0437 C# \u043d\u0430 Unity. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0434\u043b\u044f \u0430\u0432\u0430\u0442\u0430\u0440\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c js \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a Unity \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u0435\u0431-\u0444\u043e\u0440\u043c\u0435 \u0447\u0435\u0440\u0435\u0437 C#. \u0418 \u0442\u0430\u043a, \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 .jslib \u0444\u0430\u0439\u043b\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 Unity \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c .jslib \u0444\u0430\u0439\u043b \u0438\u0437 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0432 \u043f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0435 \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u044d\u0442\u043e \u0434\u043e\u043b\u0433\u043e \u0438 \u043d\u0435 \u0443\u0434\u043e\u0431\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442, \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u0432 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code class=\"cs\">\/\/ Assets\/Editor\/JSLibFileCreator.cs using System.IO; using UnityEditor;  public class JSLibFileCreator {     [MenuItem(\"Assets\/Create\/JS Script\", priority = 80)]     private static void CreateJSLibFile()     {       \/\/ \u0428\u0430\u0431\u043b\u043e\u043d \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0447\u0442\u043e \u0431\u044b \u0444\u0430\u0439\u043b \u043d\u0435 \u0431\u044b\u043b \u043f\u0443\u0441\u0442\u044b\u043c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e         var asset =             \"mergeInto(LibraryManager.library,\\n\" +             \"{\\n\" +             \"\\t\/\/ Your code here\\n\" +             \"});\"; \/\/ \u0411\u0435\u0440\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u043e\u043a\u043d\u0435 Project         string path = AssetDatabase.GetAssetPath(Selection.activeObject);         if (path == \"\")         {             path = \"Assets\";         }         else if (Path.GetExtension(path) != \"\")         {             path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), \"\");         } \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c .jslib \u0444\u0430\u0439\u043b \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c         ProjectWindowUtil.CreateAssetWithContent(AssetDatabase.GenerateUniqueAssetPath(path + \"\/JSScript.jslib\"), asset);         \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0430\u0441\u0441\u0435\u0442\u044b       AssetDatabase.SaveAssets();     } } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c .jslib \u0444\u0430\u0439\u043b\u044b \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0435\u0439 \u0433\u043e\u043b\u043e\u0432\u043d\u043e\u0439 \u0431\u043e\u043b\u0438, \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9b8\/834\/bdf\/9b8834bdff0156db6af4230541d49d50.png\" alt=\"\u041d\u0443\u0436\u043d\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u041f\u041a\u041c \u0432 \u043e\u043a\u043d\u0435 Project, \u0432\u044b\u0431\u0440\u0430\u0442\u044c Create \u0438 \u0437\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 JS Script\" title=\"\u041d\u0443\u0436\u043d\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u041f\u041a\u041c \u0432 \u043e\u043a\u043d\u0435 Project, \u0432\u044b\u0431\u0440\u0430\u0442\u044c Create \u0438 \u0437\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 JS Script\" width=\"863\" height=\"424\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9b8\/834\/bdf\/9b8834bdff0156db6af4230541d49d50.png\"\/><figcaption>\u041d\u0443\u0436\u043d\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u041f\u041a\u041c \u0432 \u043e\u043a\u043d\u0435 Project, \u0432\u044b\u0431\u0440\u0430\u0442\u044c Create \u0438 \u0437\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 JS Script<\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/499\/e36\/b4a\/499e36b4a1613ab9dc206cc698372d4e.png\" width=\"281\" height=\"189\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/499\/e36\/b4a\/499e36b4a1613ab9dc206cc698372d4e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u0435\u0433\u043e, \u0438 \u0443\u0432\u0438\u0434\u0438\u043c \u043d\u0430\u0448 \u0448\u0430\u0431\u043b\u043e\u043d:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cb8\/207\/78b\/cb820778b1e1104f96ead7a55d8b638f.png\" width=\"554\" height=\"190\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cb8\/207\/78b\/cb820778b1e1104f96ead7a55d8b638f.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<pre><code class=\"javascript\">\/\/ Assets\/Plugins\/WebGL\/JSFileUploader.jslib mergeInto(LibraryManager.library,     {         InitFileLoader: function (callbackObjectName, callbackMethodName) { \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 C# \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 UTF8             FileCallbackObjectName = UTF8ToString(callbackObjectName);             FileCallbackMethodName = UTF8ToString(callbackMethodName);            \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c input \u0434\u043b\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432, \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0435\u0449\u0435 \u043d\u0435\u0442             var fileuploader = document.getElementById('fileuploader');             if (!fileuploader) {                 console.log('Creating fileuploader...');                 fileuploader = document.createElement('input');                 fileuploader.setAttribute('style', 'display:none;');                 fileuploader.setAttribute('type', 'file');                 fileuploader.setAttribute('id', 'fileuploader');                 fileuploader.setAttribute('class', 'nonfocused');                 document.getElementsByTagName('body')[0].appendChild(fileuploader);                  fileuploader.onchange = function (e) {                     var files = e.target.files;                    \/\/ \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d - \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c unfocus                   \/\/ \u041f\u043e\u043c\u0435\u0442\u043a\u0430: \u0415\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u0444\u0430\u0439\u043b \u043d\u0435                   \/\/ \u0432\u044b\u0431\u0440\u0430\u043d, \u0442\u043e \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c SendMessage \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u043c\u0443                   \/\/ null, \u0432\u043c\u0435\u0441\u0442\u043e ResetFileLoader() if (files.length === 0) {                         ResetFileLoader();                         return;                     }                                        console.log('ObjectName: ' + FileCallbackObjectName + ';\\nMethodName: ' + FileCallbackMethodName + ';');                     SendMessage(FileCallbackObjectName, FileCallbackMethodName, URL.createObjectURL(files[0]));                 };             }              console.log('FileLoader initialized!');         },   \/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438, \u0442.\u043a. \u0437\u0430\u0449\u0438\u0442\u0430 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 click()   \/\/ \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e         RequestUserFile: function (extensions) {           \/\/ \u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 UTF8             var str = UTF8ToString(extensions);             var fileuploader = document.getElementById('fileuploader');            \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c fileuploader \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 - \u0437\u0430\u0434\u0430\u0435\u043c \u0435\u0433\u043e           \/\/ \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 Blazor.NET             if (fileuploader === null)                 InitFileLoader(FileCallbackObjectName, FileCallbackMethodName);            \/\/ \u0417\u0430\u0434\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f             if (str !== null || str.match(\/^ *$\/) === null)                 fileuploader.setAttribute('accept', str);            \/\/ \u0424\u043e\u043a\u0443\u0441 \u043d\u0430 \u0438\u043d\u043f\u0443\u0442 \u0438 \u043a\u043b\u0438\u043a             fileuploader.setAttribute('class', 'focused');             fileuploader.click();         },    \/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430   \/\/ \u0415\u0451 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0437 RequestUserFile \u0438\u043b\u0438 fileUploader.onchange   \/\/ \u0430 \u043d\u0435 \u0438\u0437 C#, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u043d\u043e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0432\u044b\u0437\u043e\u0432 \u0438\u0437 C# \u043a\u0430\u043a \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043c\u0435\u0440   \/\/ \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432         ResetFileLoader: function () {             var fileuploader = document.getElementById('fileuploader');              if (fileuploader) {               \/\/ \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u043d\u043f\u0443\u0442 \u0438\u0437 \u0444\u043e\u043a\u0443\u0441\u0430                 fileuploader.setAttribute('class', 'nonfocused');             }         },     });<\/code><\/pre>\n<p>\u0418 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0431\u0435\u0440\u0442\u043a\u0443, \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f js \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/p>\n<pre><code class=\"cs\">\/\/ Assets\/Scripts\/FileUploader.cs using System; using System.Runtime.InteropServices; using UnityEngine;  \/\/ \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 - \u043f\u043e\u043c\u043e\u0448\u043d\u0438\u043a, \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 public class FileUploader : MonoBehaviour {     private void Start()     {     \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0435\u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u043c\u044b\u043c         DontDestroyOnLoad(gameObject);     }      \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 JS \u0447\u0435\u0440\u0435\u0437 SendMessage     void FileRequestCallback(string path)     {     \/\/ \u041e\u0442\u0441\u044b\u043b\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 FileUploaderHelper         FileUploaderHelper.SetResult(path);     } }  public static class FileUploaderHelper {     static FileUploader fileUploaderObject;     static Action&lt;string> pathCallback;      static FileUploaderHelper()     {         string methodName = \"FileRequestCallback\"; \/\/ \u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0446\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c, \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c :)         string objectName = typeof(FileUploaderHelper).Name; \/\/ \u0410 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 - \u043f\u043e\u043c\u043e\u0448\u043d\u0438\u043a \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b FileUploader         var wrapperGameObject = new GameObject(objectName, typeof(FileUploader));         fileUploaderObject = wrapperGameObject.GetComponent&lt;FileUploader>();        \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c JS \u0447\u0430\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b FileUploader         InitFileLoader(objectName, methodName);     }      \/\/\/ &lt;summary>     \/\/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.     \/\/\/ \u0414\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f!     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"callback\">\u0411\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f Http \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443&lt;\/param>     \/\/\/ &lt;param name=\"extensions\">\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c, \u043f\u0440\u0438\u043c\u0435\u0440: \".jpg, .jpeg, .png\"&lt;\/param>     public static void RequestFile(Action&lt;string> callback, string extensions = \".jpg, .jpeg, .png\")     {         RequestUserFile(extensions);         pathCallback = callback;     }      \/\/\/ &lt;summary>     \/\/\/ \u0414\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"path\">\u041f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443&lt;\/param>     public static void SetResult(string path)     {         pathCallback.Invoke(path);         Dispose();     }      private static void Dispose()     {         ResetFileLoader();         pathCallback = null;     }    \/\/ \u041d\u0438\u0436\u0435 \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e .jslib \u0444\u0430\u0439\u043b\u0430     [DllImport(\"__Internal\")]     private static extern void InitFileLoader(string objectName, string methodName);      [DllImport(\"__Internal\")]     private static extern void RequestUserFile(string extensions);      [DllImport(\"__Internal\")]     private static extern void ResetFileLoader(); } <\/code><\/pre>\n<p>\u0418 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0435 \u043a\u0430\u043a \u0430\u0432\u0430\u0442\u0430\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"cs\">\/\/ Assets\/Scripts\/AvatarController.cs using System.Collections; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI;  public class AvatarController : MonoBehaviour { \/\/ \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 UI \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0430\u0432\u0430\u0442\u0430\u0440\u0430 \u0432 Canvas     public Image avatarImage;      \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u043e\u0439 (Button \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442)     public void UpdateAvatar()     {     \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f         FileUploaderHelper.RequestFile((path) =>          {         \/\/ \u0415\u0441\u043b\u0438 \u043f\u0443\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 - \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c             if (string.IsNullOrWhiteSpace(path))                 return;              \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438             StartCoroutine(UploadImage(path));             });     }      \/\/ \u041a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438     IEnumerator UploadImage(string path)     {     \/\/ \u0422\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430         Texture2D texture;          \/\/ using \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 Dispose, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u043f\u0443\u0442\u0438 \u043a \u0444\u0430\u0439\u043b\u0443         using (UnityWebRequest imageWeb = new UnityWebRequest(path, UnityWebRequest.kHttpVerbGET))         { \/\/ \u0417\u0430\u0434\u0430\u0435\u043c \"\u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u0435\u043b\u044c\" \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0443             imageWeb.downloadHandler = new DownloadHandlerTexture();              \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441, \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430             yield return imageWeb.SendWebRequest();              \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0438\u0437 \"\u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u0435\u043b\u044f\"             texture = ((DownloadHandlerTexture)imageWeb.downloadHandler).texture;         }  \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043f\u0440\u0430\u0439\u0442 \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0430\u0432\u0430\u0442\u0430\u0440\u0430 \u043d\u0430 UI         avatarImage.sprite = Sprite.Create(             texture,              new Rect(0.0f, 0.0f, texture.width, texture.height),              new Vector2(0.5f, 0.5f));     } } <\/code><\/pre>\n<p>\u0418 \u0442\u0430\u043a \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0441\u0446\u0435\u043d\u043a\u0443:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b6f\/db3\/438\/b6fdb3438913480bab7eab9327505f21.png\" alt=\"\u0413\u043b\u0430\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 - AvatarImage \u0438 Button.\" title=\"\u0413\u043b\u0430\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 - AvatarImage \u0438 Button.\" width=\"1911\" height=\"820\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b6f\/db3\/438\/b6fdb3438913480bab7eab9327505f21.png\"\/><figcaption>\u0413\u043b\u0430\u0432\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 &#8212; AvatarImage \u0438 Button.<\/figcaption><\/figure>\n<details class=\"spoiler\">\n<summary>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445<\/summary>\n<div class=\"spoiler__content\">\n<details class=\"spoiler\">\n<summary>Edge<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f27\/71a\/244\/f2771a244952fc36913892c07de6d6a8.png\" width=\"1452\" height=\"456\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f27\/71a\/244\/f2771a244952fc36913892c07de6d6a8.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d9a\/6e0\/97a\/d9a6e097ae4f3f445d7443be16bec6e0.png\" width=\"1455\" height=\"980\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d9a\/6e0\/97a\/d9a6e097ae4f3f445d7443be16bec6e0.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Chrome<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3e4\/f35\/37f\/3e4f3537f5df6750cec0f28d98f689dc.png\" width=\"1597\" height=\"448\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3e4\/f35\/37f\/3e4f3537f5df6750cec0f28d98f689dc.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/82d\/d0d\/6a0\/82dd0d6a0b80c554dc21bbb6e4b02611.png\" width=\"1450\" height=\"980\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/82d\/d0d\/6a0\/82dd0d6a0b80c554dc21bbb6e4b02611.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Firefox<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8dc\/406\/0f1\/8dc4060f1d9de30e7bf2b9540b776956.png\" width=\"1585\" height=\"449\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8dc\/406\/0f1\/8dc4060f1d9de30e7bf2b9540b776956.png\"\/><figcaption><\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4b1\/e8c\/494\/4b1e8c494248db324a746963279c2899.png\" width=\"1448\" height=\"978\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4b1\/e8c\/494\/4b1e8c494248db324a746963279c2899.png\"\/><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/details>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0443\u0442\u044c \u043a \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0443 \u0447\u0435\u0440\u0435\u0437 1 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"cs\">Action&lt;string> callback = (str) => { \/* Your file handler code here*\/ }; FileUploaderHelper.RequestFile(callback);  \/\/ \u0418\u043b\u0438 \u0442\u0430\u043a, \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043d\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435, \u043e\u0441\u043e\u0431\u044b\u0435 \u0444\u0430\u0439\u043b\u044b:  FileUploaderHelper.RequestFile(callback, \".txt, .docx, .csv\");<\/code><\/pre>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0432\u0441\u0435\u0445 \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u043c\u043e\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u0412\u0430\u043c \u0432 \u0412\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445! \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\u043c \u0438 \u043a\u0440\u0438\u0442\u0438\u043a\u0435, \u043d\u043e \u0445\u043e\u0447\u0443 \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0431\u044b\u043b\u0430 \u0432\u044b\u0440\u0435\u0437\u0430\u043d\u0430 \u0438\u0437 \u043c\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0441 \u043d\u0443\u043b\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0443\u0442 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<p>\u041a\u043e\u0434 \u043d\u0430 GitHub:<\/p>\n<p><a href=\"https:\/\/github.com\/AlexMorOR\/Unity-UserFileUploader\" rel=\"noopener noreferrer nofollow\">AlexMorOR\/Unity-UserFileUploader: There is a script which allow you to request files from user. (github.com)<\/a>  <\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/684772\/\"> https:\/\/habr.com\/ru\/post\/684772\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431 \u043a\u0430\u043a \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0444\u0430\u0439\u043b\u044b, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b. \u0418 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0435\u043c \u0442\u0435\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 JS \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u0437 C# \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 Unity.<\/p>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f js \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 Plugins, \u044d\u0442\u043e <a href=\"https:\/\/docs.unity3d.com\/2017.2\/Documentation\/Manual\/SpecialFolders.html\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b .jslib, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0448 JS \u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 JS \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437:<\/p>\n<p>[DllImport(&#171;__Internal&#187;)] static extern void [JSFunctionName]();  , \u0433\u0434\u0435 [JSFunctionName] &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 .jslib .<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443, \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u0437 C# \u0432 JS \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0438\u043c\u044f GameObject \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<p>MyGameInstance.SendMessage(&#8216;MyGameObject&#8217;, &#8216;MyFunction&#8217;, [var]);  , \u0433\u0434\u0435 MyGameObject &#8212; \u0438\u043c\u044f \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, MyFunction &#8212; \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, [var] &#8212; \u0447\u0438\u0441\u043b\u043e \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a GameObject.<a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/GameObject.SendMessage.html\" rel=\"noopener noreferrer nofollow\">SendMessage()<\/a>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 .jslib \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 mergeInto(), \u043f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<pre><code class=\"javascript\">mergeInto(LibraryManager.library,  { \/\/ Your code here   Hello: function () {     window.alert(\"Hello, world!\");   } });<\/code><\/pre>\n<p>\u0418\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">var SomeObject = { \/\/ Your code here   Hello: function () {     window.alert(\"Hello, world!\");   } };  mergeInto(LibraryManager.library, SomeObject);<\/code><\/pre>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/docs.unity3d.com\/Manual\/webgl-interactingwithbrowserscripting.html\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 Unity<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0432\u0435\u0442<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435\u0441\u044c Visual Studio, \u0442\u043e \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u044f .jslib \u0444\u0430\u0439\u043b\u043e\u0432 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u0441 JavaScript \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u0431\u0430\u0437\u0443, \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0412\u044b \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JS \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0438\u0437 C# \u043d\u0430 Unity. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0434\u043b\u044f \u0430\u0432\u0430\u0442\u0430\u0440\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c js \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a Unity \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u0435\u0431-\u0444\u043e\u0440\u043c\u0435 \u0447\u0435\u0440\u0435\u0437 C#. \u0418 \u0442\u0430\u043a, \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 .jslib \u0444\u0430\u0439\u043b\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 Unity \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c .jslib \u0444\u0430\u0439\u043b \u0438\u0437 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0432 \u043f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0435 \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u044d\u0442\u043e \u0434\u043e\u043b\u0433\u043e \u0438 \u043d\u0435 \u0443\u0434\u043e\u0431\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442, \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u0432 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code class=\"cs\">\/\/ Assets\/Editor\/JSLibFileCreator.cs using System.IO; using UnityEditor;  public class JSLibFileCreator {     [MenuItem(\"Assets\/Create\/JS Script\", priority = 80)]     private static void CreateJSLibFile()     {       \/\/ \u0428\u0430\u0431\u043b\u043e\u043d \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0447\u0442\u043e \u0431\u044b \u0444\u0430\u0439\u043b \u043d\u0435 \u0431\u044b\u043b \u043f\u0443\u0441\u0442\u044b\u043c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e         var asset =             \"mergeInto(LibraryManager.library,\\n\" +             \"{\\n\" +             \"\\t\/\/ Your code here\\n\" +             \"});\"; \/\/ \u0411\u0435\u0440\u0435\u043c \u043f\u0443\u0442\u044c \u0434\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u043e\u043a\u043d\u0435 Project         string path = AssetDatabase.GetAssetPath(Selection.activeObject);         if (path == \"\")         {             path = \"Assets\";         }         else if (Path.GetExtension(path) != \"\")         {             path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), \"\");         } \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c .jslib \u0444\u0430\u0439\u043b \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c         ProjectWindowUtil.CreateAssetWithContent(AssetDatabase.GenerateUniqueAssetPath(path + \"\/JSScript.jslib\"), asset);         \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0430\u0441\u0441\u0435\u0442\u044b       AssetDatabase.SaveAssets();     } } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c .jslib \u0444\u0430\u0439\u043b\u044b \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0435\u0439 \u0433\u043e\u043b\u043e\u0432\u043d\u043e\u0439 \u0431\u043e\u043b\u0438, \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><figcaption>\u041d\u0443\u0436\u043d\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u041f\u041a\u041c \u0432 \u043e\u043a\u043d\u0435 Project, \u0432\u044b\u0431\u0440\u0430\u0442\u044c Create \u0438 \u0437\u0430\u0442\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 JS Script<\/figcaption><\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0442\u043a\u0440\u043e\u0435\u043c \u0435\u0433\u043e, \u0438 \u0443\u0432\u0438\u0434\u0438\u043c \u043d\u0430\u0448 \u0448\u0430\u0431\u043b\u043e\u043d:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<pre><code class=\"javascript\">\/\/ Assets\/Plugins\/WebGL\/JSFileUploader.jslib mergeInto(LibraryManager.library,     {         InitFileLoader: function (callbackObjectName, callbackMethodName) { \/\/ \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 C# \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 UTF8             FileCallbackObjectName = UTF8ToString(callbackObjectName);             FileCallbackMethodName = UTF8ToString(callbackMethodName);            \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c input \u0434\u043b\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432, \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0435\u0449\u0435 \u043d\u0435\u0442             var fileuploader = document.getElementById('fileuploader');             if (!fileuploader) {                 console.log('Creating fileuploader...');                 fileuploader = document.createElement('input');                 fileuploader.setAttribute('style', 'display:none;');                 fileuploader.setAttribute('type', 'file');                 fileuploader.setAttribute('id', 'fileuploader');                 fileuploader.setAttribute('class', 'nonfocused');                 document.getElementsByTagName('body')[0].appendChild(fileuploader);                  fileuploader.onchange = function (e) {                     var files = e.target.files;                    \/\/ \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u043d - \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c unfocus                   \/\/ \u041f\u043e\u043c\u0435\u0442\u043a\u0430: \u0415\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u0444\u0430\u0439\u043b \u043d\u0435                   \/\/ \u0432\u044b\u0431\u0440\u0430\u043d, \u0442\u043e \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c SendMessage \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u043c\u0443                   \/\/ null, \u0432\u043c\u0435\u0441\u0442\u043e ResetFileLoader() if (files.length === 0) {                         ResetFileLoader();                         return;                     }                                        console.log('ObjectName: ' + FileCallbackObjectName + ';\\nMethodName: ' + FileCallbackMethodName + ';');                     SendMessage(FileCallbackObjectName, FileCallbackMethodName, URL.createObjectURL(files[0]));                 };             }              console.log('FileLoader initialized!');         },   \/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438, \u0442.\u043a. \u0437\u0430\u0449\u0438\u0442\u0430 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 click()   \/\/ \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e         RequestUserFile: function (extensions) {           \/\/ \u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 UTF8             var str = UTF8ToString(extensions);             var fileuploader = document.getElementById('fileuploader');            \/\/ \u0415\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c fileuploader \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 - \u0437\u0430\u0434\u0430\u0435\u043c \u0435\u0433\u043e           \/\/ \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 Blazor.NET             if (fileuploader === null)                 InitFileLoader(FileCallbackObjectName, FileCallbackMethodName);            \/\/ \u0417\u0430\u0434\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f             if (str !== null || str.match(\/^ *$\/) === null)                 fileuploader.setAttribute('accept', str);            \/\/ \u0424\u043e\u043a\u0443\u0441 \u043d\u0430 \u0438\u043d\u043f\u0443\u0442 \u0438 \u043a\u043b\u0438\u043a             fileuploader.setAttribute('class', 'focused');             fileuploader.click();         },    \/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430   \/\/ \u0415\u0451 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0437 RequestUserFile \u0438\u043b\u0438 fileUploader.onchange   \/\/ \u0430 \u043d\u0435 \u0438\u0437 C#, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u043d\u043e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0432\u044b\u0437\u043e\u0432 \u0438\u0437 C# \u043a\u0430\u043a \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043c\u0435\u0440   \/\/ \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432         ResetFileLoader: function () {             var fileuploader = document.getElementById('fileuploader');              if (fileuploader) {               \/\/ \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u043d\u043f\u0443\u0442 \u0438\u0437 \u0444\u043e\u043a\u0443\u0441\u0430                 fileuploader.setAttribute('class', 'nonfocused');             }         },     });<\/code><\/pre>\n<p>\u0418 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0431\u0435\u0440\u0442\u043a\u0443, \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f js \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/p>\n<pre><code class=\"cs\">\/\/ Assets\/Scripts\/FileUploader.cs using System; using System.Runtime.InteropServices; using UnityEngine;  \/\/ \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 - \u043f\u043e\u043c\u043e\u0448\u043d\u0438\u043a, \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 public class FileUploader : MonoBehaviour {     private void Start()     {     \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043d\u0435\u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u043c\u044b\u043c         DontDestroyOnLoad(gameObject);     }      \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 JS \u0447\u0435\u0440\u0435\u0437 SendMessage     void FileRequestCallback(string path)     {     \/\/ \u041e\u0442\u0441\u044b\u043b\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 FileUploaderHelper         FileUploaderHelper.SetResult(path);     } }  public static class FileUploaderHelper {     static FileUploader fileUploaderObject;     static Action&lt;string> pathCallback;      static FileUploaderHelper()     {         string methodName = \"FileRequestCallback\"; \/\/ \u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0444\u043b\u0435\u043a\u0446\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c, \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c :)         string objectName = typeof(FileUploaderHelper).Name; \/\/ \u0410 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 - \u043f\u043e\u043c\u043e\u0448\u043d\u0438\u043a \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b FileUploader         var wrapperGameObject = new GameObject(objectName, typeof(FileUploader));         fileUploaderObject = wrapperGameObject.GetComponent&lt;FileUploader>();        \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c JS \u0447\u0430\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b FileUploader         InitFileLoader(objectName, methodName);     }      \/\/\/ &lt;summary>     \/\/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.     \/\/\/ \u0414\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f!     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"callback\">\u0411\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f Http \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443&lt;\/param>     \/\/\/ &lt;param name=\"extensions\">\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c, \u043f\u0440\u0438\u043c\u0435\u0440: \".jpg, .jpeg, .png\"&lt;\/param>     public static void RequestFile(Action&lt;string> callback, string extensions = \".jpg, .jpeg, .png\")     {         RequestUserFile(extensions);         pathCallback = callback;     }      \/\/\/ &lt;summary>     \/\/\/ \u0414\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"path\">\u041f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443&lt;\/param>     public static void SetResult(string path)     {         pathCallback.Invoke(path);         Dispose();     }      private static void Dispose()     {         ResetFileLoader();         pathCallback = null;     }    \/\/ \u041d\u0438\u0436\u0435 \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e .jslib \u0444\u0430\u0439\u043b\u0430     [DllImport(\"__Internal\")]     private static extern void InitFileLoader(string objectName, string methodName);      [DllImport(\"__Internal\")]     private static extern void RequestUserFile(string extensions);      [DllImport(\"__Internal\")]     private static extern void ResetFileLoader(); } <\/code><\/pre>\n<p>\u0418 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0435 \u043a\u0430\u043a \u0430\u0432\u0430\u0442\u0430\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"cs\">\/\/ Assets\/Scripts\/AvatarController.cs using System.Collections; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI;  public class AvatarController : MonoBehaviour { \/\/ \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 UI \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0430\u0432\u0430\u0442\u0430\u0440\u0430 \u0432 Canvas     public Image avatarImage;      \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u043e\u0439 (Button \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442)     public void UpdateAvatar()     {     \/\/ \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f         FileUploaderHelper.RequestFile((path) =>          {         \/\/ \u0415\u0441\u043b\u0438 \u043f\u0443\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 - \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c             if (string.IsNullOrWhiteSpace(path))                 return;              \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438             StartCoroutine(UploadImage(path));        <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-337532","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337532","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=337532"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337532\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=337532"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=337532"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=337532"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}