Unity - Web Interaction

From NoskeWiki
Revision as of 17:06, 6 February 2019 by NoskeWiki (talk | contribs) (Created page with "==About== {{DaughterPage|mother=Unity}} Unity is a multi-platform 3D game engine. In addition to compiling to Windows and OS X executables, Unity can also export to a "U...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

About

NOTE: This page is a daughter page of: Unity


Unity is a multi-platform 3D game engine. In addition to compiling to Windows and OS X executables, Unity can also export to a "Unity web player" format where 3D content is embedded into the page (similar to the way Flash embeds into a page) and can be displayed after installing the plugin (which is relatively easy). This article gives some code snippets and links specific for unity communicating with the browser and uploading/downloading information from the web. Note that all my Scripts are in C# because it's the most powerful way to program in Unity.


Talking to the Internet with Unity

There are various ways Unity can upload and download information from the web. The key Unity classes to achieve this are:

  • WWW - a small utility module for retrieving the contents of URLs (text, image or even movies!).
  • WWWForm - a helper class to generate form data to post to web servers using the WWW class.
  • Application - access's Unity's run-time data, which also include the function "ExternalCall()", which can communicate with JavaScript on a webpage, and "OpenURL()", which opens any URL in a browser.

Some specifics of these classes and how Unity interacts with the web is outlined below.


Unity Web Player and Browser Communication

Unity web player can communication with the web browser, without reloading pages, via JavaScript functions in the webpage. To call a function in Unity using JavaScript on your page:

unityObject.getObjectById("UnityContent").SendMessage("MyObject", "MyFunction", "Hello from web page");

And call a JavaScript function from Unity you can use the Application.ExternalCall():

Application.ExternalCall("JSFunctionOnPage", "The game says hello");

And using "Application.ExternalEval()", you can even execute arbitrary browser code without even needing a JavaScript function. The following example can be used to prevent deep linking to your web player content, by checking the URL and redirecting it if's not the URL expected.

Application.ExternalEval("if(document.location.host != 'unity3d.com') { document.location='http://unity3d.com'; }");

See: Resources - Unity Web Player and browser communication for more information


Opening Web Page

You can open any webpage/URL using the Application class:

Application.OpenURL("http://unity3d.com/");

In the editor or standalone player this opens a new page in the default browser and it bring to the front. When executed in the web player, the page the plugin is contained in will be redirected to the URL - thus to open in a new window you'd need to call a JavaScript function on the webpage (see above).


Loading HTML Content

To load text/images/movies from any URL you can use Unity's WWW class:

WWW www = new WWW(url);
yield return www;
string htmlText = www.text;


Displaying HTML Content

Although Unity can load data (including text) from any URL, it cannot natively render HTML. There is a plugin called "HtmlTexturePlugin", which renders web content to a texture, but currently only works on Unity MAC.


Posting Content to a WebPage

Unity can "post" data to a URL, using the WWWForm class

// Create a Web Form:
WWWForm form = new WWWForm();
form.AddField("frameCount", Time.frameCount.ToString());
form.AddBinaryData("fileUpload", bytes, "screenShot.png", "image/png");  // You can also upload image data
// Upload to a cgi script:
WWW w = WWW("http://www.my-server.com/cgi-bin/screenshot.pl", form);
yield w;    // Wait for this to finish.
(w.error != null) ? print(w.error) : print("Finished Uploading Screenshot");


By sending information to CGI script (eg: a php page) it then becomes possible to interact with and save information to a database. See: WWWForm for an extended example where a screenshot is saved to a SQL database using a perl script.


Loading Images from a URL

Unity can natively open JPEG and PNG files from a URL using "WWW.LoadImageIntoTexture". The C# code for this is:

Texture textWebPic;
WWW www = new WWW("http://images.earthcam.com/ec_metros/ourcams/fridays.jpg "); 
yield www;     // wait until the download is done
www.LoadImageIntoTexture(textWebPic);  // Assign the downloaded image to the main texture of the object.


Importantly "yield" only works on a script/class which extends "MonoObject" and is applied to a GameObject. To load a web image from a normal class you can have to keep calling "WWW.isDone()" to wait until the texture is ready and then load it as demonstrated here:

if(www.isDone)    // won't return true until finished loading... see also: "progress"
  picTexture = www.texture;    // works the same as "LoadImageIntoTexture"


Here is a more full example which uses a MonoBehaviour and a StartCoroutine (so it doesn't block everything else happening).

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ImageLoaderMono : MonoBehaviour {
  // INSTRUCTIONS: Drag ImageLoaderMono onto any
  // object in the scene, then add a "UI > RawImage"
  // and drag that in as the `rawImage`.
  public RawImage rawImage;

  // Loads first image.
  void Start () {
    DownloadImage("http://gyanendushekhar.com/wp-content/uploads/2017/07/SampleImage.png");
  }

  // Starts an image download.
  public void DownloadImage(string url)
  {
    StartCoroutine(coDownloadImage(url, rawImage));
    Debug.Log(rawImage);
  }

  IEnumerator coDownloadImage(string imageUrl, RawImage rawImageIn)
  {
    WWW www = new WWW(imageUrl);    
    yield return www;
    rawImageIn.texture = www.texture;
  }

  // Attach this to a button.
  public void LoadTestImage() {
    DownloadImage("http://lorempixel.com/400/400/");  // Random jpg.
  }
}

Here's a video demo.

Saving Web Based Unity Data using PlayerPrefs (Unity's Equivalent to Cookies)

Web-based Unity content can save data to the local machine using the PlayerPrefs class. Each webplayer URL can save up 1 megabyte of data, consisting of either ints, floats or strings. Examples follow:

PlayerPrefs.SetInt("Player Score", 10);          // To save an integer value.
print (PlayerPrefs.GetInt("Player Score"));      // To retrieve the integer value.

PlayerPrefs.SetFloat("Player Lap Time", 29.3);     // To save a float.
print (PlayerPrefs.GetFloat("Player Lap Time"));   // To load a float.

PlayerPrefs.SetString("Player Name", "Duck");      // To save a string.
print ("Welcome back, " + PlayerPrefs.GetString("Player Name") + "!");  // To load that string.

PlayerPrefs also works on the Unity standalone player, although will save in different locations depending on whether it's Windows or OS X (see: Reference - PlayerPrefs). I'm not quite sure if Unity can access browser cookies (if so I imagine it would need to involve JavaScript on the webpage), but "PlayerPrefs" seems like a great solution - especially if your browser has disabled these cookies.


See Also

  • Unity - main Unity article
  • Unity - Textures - code snippets and tips for dealing with images and textures


Links