Hello,
I am using Unity 3D to present 3D objects to a client right now, using the Web player. Right now you have to use the mouse and click into the web player to start some specific action there. The customer now likes me to implement regular URLs on the same website to control the actions within the web player. Would that be possible? Thanks!
1 Answer
1You can easily read the URL parameters from the containing website by using a script like this:
//C#
using UnityEngine;
using System.Collections;
public class URLParameters : MonoBehaviour
{
public static string TestData;
private static URLParameters m_Instance = null;
public static URLParameters Instance
{
get
{
if (m_Instance == null)
{
m_Instance = (URLParameters)FindObjectOfType(typeof(URLParameters));
if (m_Instance == null)
m_Instance = (new GameObject("URLParameters")).AddComponent<URLParameters>();
m_Instance.gameObject.name = "URLParameters";
DontDestroyOnLoad(m_Instance.gameObject);
}
return m_Instance;
}
}
private System.Action<URLParameters> m_OnDone = null;
private System.Action<URLParameters> m_OnDoneOnce = null;
private bool m_HaveInformation = false;
private string m_RawData;
private string m_Href;
private string m_Hash;
private string m_Host;
private string m_Hostname;
private string m_Pathname;
private string m_Port;
private string m_Protocol;
private string m_Search;
public bool HaveInformation
{
get {return m_HaveInformation;}
}
public string RawData
{
get {return m_RawData;}
}
public string Href
{
get {return m_Href;}
}
public string Hash
{
get {return m_Hash;}
}
public string Host
{
get {return m_Host;}
}
public string Hostname
{
get {return m_Hostname;}
}
public string Pathname
{
get {return m_Pathname;}
}
public string Port
{
get {return m_Port;}
}
public string Protocol
{
get {return m_Protocol;}
}
public string Search
{
get {return m_Search;}
}
public void RegisterOnDone(System.Action<URLParameters> aCallback)
{
m_OnDone += aCallback;
if (HaveInformation)
aCallback(this);
}
public void RegisterOnceOnDone(System.Action<URLParameters> aCallback)
{
if (HaveInformation)
aCallback(this);
else
m_OnDoneOnce += aCallback;
}
public void Request()
{
StartCoroutine(_Request());
}
private IEnumerator _Request()
{
m_HaveInformation = false;
if (Application.isWebPlayer)
Application.ExternalEval("GetUnity ().SendMessage ('" + gameObject.name + "', 'SetAddressComponents', location.href +'|'+ location.hash +'|'+ location.host +'|'+ location.hostname +'|'+ location.pathname +'|'+ location.port +'|'+ location.protocol +'|'+ location.search);");
else
{
yield return null;
SetAddressComponents(TestData);
}
}
public IEnumerator Start()
{
yield return null; // wait one frame to ensure all delegates are assigned.
Request();
}
public void SetAddressComponents (string aData)
{
string[] parts = aData.Split('|');
m_RawData = aData;
m_Href = parts[0];
m_Hash = parts[1];
m_Host = parts[2];
m_Hostname = parts[3];
m_Pathname = parts[4];
m_Port = parts[5];
m_Protocol = parts[6];
m_Search = parts[7];
m_HaveInformation = true;
if (m_OnDone != null)
m_OnDone(this);
if (m_OnDoneOnce != null)
{
m_OnDoneOnce(this);
m_OnDoneOnce = null;
}
}
}
It’s a singleton and don’t need to be added manually to any gameobject. You can just register a callback in any of your scripts:
//C#
void Start()
{
URLParameters.Instance.RegisterOnDone((url)=>{
Debug.Log("Parameter: " + url.Search);
});
}
This will do a lot steps for you. It will create a gameobject named “URLParameters”, attach the URLParameters script to it, registers the callback above and once the first frame has passed it injects a piece of javascript into the website which will report back the url already splitted into it’s parts.
Note: Invoking an URL in a browser will of course reload the website and it’s webplayer. You can prevent this by using the Hash / Anchor part of the URL, however you have to manually update the information in Untiy. The best solution would be to have a piece of Javascript in the website which handles URL changes and pass those changes to Unity.
The script above is ment to read the URL once at start, but you can call URLParameters.Instance.Request(); at any later time to Update the information. Keep in mind to not call it too frequently as it’s quite heavy.
Hello, wow, that was fast. Thank you very much for you reply. I will have to dive into it to understand what's going on there, but it already sounds great!
– Arndtvk