GameObject.Find not working with string var - unity3d

I cannot get GameObject.Find to work by passing a string variable as an agrument.
Here is the code:
public IEnumerator GetControls(string uri)
{
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
yield return webRequest.SendWebRequest();
controls = new JSONObject(webRequest.downloadHandler.text);
GameObject controlGO;
string keyName;
foreach (JSONObject control in controls)
{
keyName = control["keyName"].ToString();
controlGO = GameObject.Find(keyName); //WONT FIND IT
controlGO = GameObject.Find("growLight3"); //WILL FIND IT
}
}
}

Related

Unity, PropertyDrawer.GetPropertyHeight doesn't get called in multiple arrays on element change

I've started rewriting my Curve tool to deal with problem of drawing it in array and other reasons. All was well till I tried to click between editors in array and list elements. Sometimes Previously edited element retains its height until other element of that collection gets edited or curve field gets edited. I have no idea how to tell Unity it should refresh field heights. I've tried EditorUtility.SetDirty(targetObject); with or without EditorGUI.BeginChangeCheck(); EditorGUI.EndChangeCheck();
Number on left is OtherCurve.z, it's a way to deferenciate which PropertyDrawer you are debugging in code. Labels are temporal.
public class OtherTestScript : MonoBehaviour
{
public OtherCurve curve;
public OtherCurve[] curveArray;
public List<OtherCurve> curveList;
}
Curve tool repository at last commit with the issue
To test download this commit code and put it in Assets/Plugins/ and add these to your Packages/manifest.json:
"st.one-line": "https://github.com/slavniyteo/one-line.git#master",
"st.rect-ex": "https://github.com/slavniyteo/rect-ex.git#master",
This code stays there, I'm not going to hide it from public or rewrite history of the repository.
After trying to recreate this behaviour on a simpler example I've found out that my technique works...
Edited: Appears that using GUI.Label(..) to draw label in Editor and not using any other EditorGUI components caused GetPropertyHeight not being called. So If I wouldn't stop at this bug, it would disappear when I replaced that GUI.Label placeholder with actually meaningful code. I feel empty for wasting that much time to figure this out.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.SceneManagement;
using System.Reflection;
using System.Linq;
using System.Text.RegularExpressions;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
#endif
public class PropertyThing : MonoBehaviour
{
public CustomThing thing;
public List<CustomThing> thingList;
public CustomThing[] thingArray;
[Serializable]
public class CustomThing
{
#if UNITY_EDITOR
public bool _isEdited;
#endif
public string field;
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(CustomThing))]
public class CustomThingInspector : PropertyDrawer
{
private UnityEngine.Object targetObject;
private CustomThing value;
private static Action FinishCurrentEditorAction;
private static void FinishCurrentEditor() => FinishCurrentEditorAction();
private static void FinishCurrentEditor(Scene s) => FinishCurrentEditorAction();
private string EditButtonText(bool editing) => editing ? "Stop Edit" : "Edit";
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
GetObjects(property);
return value._isEdited ? 38 : 18;
}
private void GetObjects(SerializedProperty property)
{
targetObject = property.serializedObject.targetObject;
value = property.GetValue<CustomThing>();
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var c = GUI.color;
GetObjects(property);
EditorGUI.BeginProperty(position, label, property);
var firstline = new Rect(position.x, position.y, position.width, 18);
var editor = new Rect(position.x, position.y + 20, position.width, position.height - 20);
var brect = EditorGUI.PrefixLabel(firstline, label);
if (value._isEdited) GUI.color = Color.red * .6666f + Color.white * .3333f;
if (GUI.Button(brect, EditButtonText(value._isEdited)))
{
EditPressed();
}
GUI.color = c;
if (value._isEdited)
EditorGUI.PropertyField(editor, property.FindPropertyRelative("field"));
EditorGUI.EndProperty();
GUI.color = c;
}
private void EditPressed()
{
value._isEdited = !value._isEdited;
if (value._isEdited)
StartEditor(value);
else
FinishEditor(value);
}
private void StartEditor(CustomThing thing)
{
var capturedThing = thing;
FinishCurrentEditorAction?.Invoke();
FinishCurrentEditorAction = () => {
FinishEditor(capturedThing);
EditorUtility.SetDirty(targetObject);
FinishCurrentEditorAction = null;
};
capturedThing._isEdited = true;
SceneView.duringSceneGui += OnEditorSceneView;
}
private void FinishEditor(CustomThing thing)
{
Selection.selectionChanged -= FinishCurrentEditor;
EditorSceneManager.sceneClosed -= FinishCurrentEditor;
AssemblyReloadEvents.beforeAssemblyReload -= FinishCurrentEditor;
SceneView.duringSceneGui -= OnEditorSceneView;
thing._isEdited = false;
FinishCurrentEditorAction = null;
}
private void OnEditorSceneView(SceneView obj)
{
if (targetObject is Component c)
Handles.Label(c.transform.position, c.gameObject.name);
else
Handles.Label(Vector3.zero, targetObject.name);
}
}
#endif
}
public static class SerializedUtility
{
public static T GetValue<T>(this SerializedProperty property) where T : class
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath.Replace(".Array.data", "");
string[] fieldStructure = path.Split('.');
Regex rgx = new Regex(#"\[\d+\]");
for (int i = 0; i < fieldStructure.Length; i++)
{
if (fieldStructure[i].Contains("["))
{
int index = System.Convert.ToInt32(new string(fieldStructure[i].Where(c => char.IsDigit(c)).ToArray()));
obj = GetFieldValueWithIndex(rgx.Replace(fieldStructure[i], ""), obj, index);
}
else
{
obj = GetFieldValue(fieldStructure[i], obj);
}
}
return (T)obj;
}
public static bool SetValue<T>(this SerializedProperty property, T value) where T : class
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath.Replace(".Array.data", "");
string[] fieldStructure = path.Split('.');
Regex rgx = new Regex(#"\[\d+\]");
for (int i = 0; i < fieldStructure.Length - 1; i++)
{
if (fieldStructure[i].Contains("["))
{
int index = System.Convert.ToInt32(new string(fieldStructure[i].Where(c => char.IsDigit(c)).ToArray()));
obj = GetFieldValueWithIndex(rgx.Replace(fieldStructure[i], ""), obj, index);
}
else
{
obj = GetFieldValue(fieldStructure[i], obj);
}
}
string fieldName = fieldStructure.Last();
if (fieldName.Contains("["))
{
int index = System.Convert.ToInt32(new string(fieldName.Where(c => char.IsDigit(c)).ToArray()));
return SetFieldValueWithIndex(rgx.Replace(fieldName, ""), obj, index, value);
}
else
{
Debug.Log(value);
return SetFieldValue(fieldName, obj, value);
}
}
private static object GetFieldValue(string fieldName, object obj, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
return field.GetValue(obj);
}
return default(object);
}
private static object GetFieldValueWithIndex(string fieldName, object obj, int index, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
object list = field.GetValue(obj);
if (list.GetType().IsArray)
{
return ((object[])list)[index];
}
else if (list is IEnumerable)
{
return ((IList)list)[index];
}
}
return default(object);
}
public static bool SetFieldValue(string fieldName, object obj, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
field.SetValue(obj, value);
return true;
}
return false;
}
public static bool SetFieldValueWithIndex(string fieldName, object obj, int index, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
{
FieldInfo field = obj.GetType().GetField(fieldName, bindings);
if (field != null)
{
object list = field.GetValue(obj);
if (list.GetType().IsArray)
{
((object[])list)[index] = value;
return true;
}
else if (value is IEnumerable)
{
((IList)list)[index] = value;
return true;
}
}
return false;
}
}

Read Events from EventHub in Unity3D and HoloLens

We are trying to show events from an Azure EventHub in our HoloLens application. When we run our project in Unity 3D, it works and paint the data from the events.
But when we deploy the same solution on the HoloLens, we don't receive events and also we don't receive any error.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit.UI;
using TMPro;
using System;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Azure.Messaging.EventHubs;
using Azure.Messaging.EventHubs.Processor;
using Azure.Storage.Blobs;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.MixedReality.Toolkit.Examples.Demos
{
[AddComponentMenu("Scripts/MRTK/Examples/SliderLunarLander")]
public class Manager : MonoBehaviour
{
[SerializeField]
public Animator helice2;
public TextMeshPro textovelocidad;
public EventProcessorClient processor;
public BlobContainerClient storageClient;
private const string storageConnectionString = "XXXX";
private const string blobContainerName = "XXXX";
private const string eventHubsConnectionString = "XXXX";
private const string consumerGroup = "hololens";
private const string EventHubName = "XXXX";
private float? speedValue;
private string errorText = string.Empty;
private CancellationToken cancellationToken;
async void Start()
{
errorText = "Init EventReader...";
storageClient = new BlobContainerClient(storageConnectionString, blobContainerName);
var clientOptions = new EventProcessorClientOptions()
{
ConnectionOptions = new EventHubConnectionOptions ()
{
TransportType = EventHubsTransportType.AmqpWebSockets
}
};
processor = new EventProcessorClient
(
storageClient,
consumerGroup,
eventHubsConnectionString,
clientOptions
);
processor.ProcessEventAsync += processEventHandler;
processor.ProcessErrorAsync += processErrorHandler;
errorText = "Start EventReader...";
await processor.StartProcessingAsync();
try
{
//The processor performs its work in the background; block until cancellation
//to allow processing to take place.
errorText = "Infinite Loop...";
await Task.Delay(Timeout.Infinite);
}
catch (TaskCanceledException tcex)
{
//This is expected when the delay is canceled.
textoError.text = tcex.Message;
}
//Debug.Log("Device client initialited...");
}
public void OnSliderUpdated(SliderEventData eventData)
{
helice2.speed = eventData.NewValue;
}
async void OnDestroy()
{
try
{
await processor.StopProcessingAsync();
}
finally
{
//To prevent leaks, the handlers should be removed when processing is complete.
processor.ProcessEventAsync -= processEventHandler;
processor.ProcessErrorAsync -= processErrorHandler;
}
}
private void Update()
{
if (speedValue != null)
{
helice2.speed = float.Parse(speedValue.ToString());
}
textovelocidad.text = (helice2.speed).ToString("F2") + " r.p.m.";
textovelocidad.text += " | " + infoText;
textoError.text = errorText;
}
async Task processEventHandler(ProcessEventArgs eventArgs)
{
try
{
// Write the body of the event to the console window
//Console.WriteLine("\tRecevied event: {0}", Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray()));
infoText = " Event Received ";
string json = Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray());
var deviceTurbine = JsonSerializer.Deserialize<DeviceTurbine>(json);
if (deviceTurbine != null)
{
speedValue = deviceTurbine.speed;
}
// Update checkpoint in the blob storage so that the app receives only new events the next time it's run
await eventArgs.UpdateCheckpointAsync(eventArgs.CancellationToken);
}
catch (Exception ex)
{
// Handle the exception from handler code
// Debug.LogError(ex.Message);
errorText = ex.Message;
}
}
Task processErrorHandler(ProcessErrorEventArgs eventArgs)
{
try
{
// Write details about the error to the console window
//Console.WriteLine($"\tPartition '{ eventArgs.PartitionId}': an unhandled exception was encountered. This was not expected to happen.");
//Console.WriteLine(eventArgs.Exception.Message);
errorText = eventArgs.Exception.Message;
}
catch
{
// Handle the exception from handler code
errorText = eventArgs.Exception.Message;
}
return Task.CompletedTask;
}
}
class DeviceTurbine
{
private float _speed;
private DateTime _timestamp;
private string _deviceId;
public float speed
{
get; set;
}
public DateTime timestamp
{
get;set;
}
public string deviceId
{
get; set;
}
}
}

Open OSM pbf results in Protobuf exception

Using OSMSharp I am having trouble to open a stream for a file (which I can provide on demand)
The error occurs in PBFReader (line 104)
using (var tmp = new LimitedStream(_stream, length))
{
header = _runtimeTypeModel.Deserialize(tmp, null, _blockHeaderType) as BlobHeader;
}
and states: "ProtoBuf.ProtoException: 'Invalid field in source data: 0'" which might mean different things as I have read in this SO question.
The file opens and is visualized with QGis so is not corrupt in my opinion.
Can it be that the contracts do not match? Is OsmSharp/core updated to the latest .proto files for OSM from here (although not sure if this is the real original source for the definition files).
And what might make more sense, can it be that the file I attached is generated for v2 of OSM PBF specification?
In the code at the line of the exception I see the following comment which makes me wonder:
// TODO: remove some of the v1 specific code.
// TODO: this means also to use the built-in capped streams.
// code borrowed from: http://stackoverflow.com/questions/4663298/protobuf-net-deserialize-open-street-maps
// I'm just being lazy and re-using something "close enough" here
// note that v2 has a big-endian option, but Fixed32 assumes little-endian - we
// actually need the other way around (network byte order):
// length = IntLittleEndianToBigEndian((uint)length);
BlobHeader header;
// again, v2 has capped-streams built in, but I'm deliberately
// limiting myself to v1 features
So this makes me wonder if OSM Sharp is (still) up-to-date.
My sandbox code looks like this:
using OsmSharp.Streams;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using OsmSharp.Tags;
namespace OsmSharp
{
class Program
{
private const string Path = #"C:\Users\Bernoulli IT\Documents\Applications\Argaleo\Test\";
private const string FileNameAntarctica = "antarctica-latest.osm";
private const string FileNameOSPbf = "OSPbf";
private const Boolean useRegisterSource = false;
private static KeyValuePair<string, string> KeyValuePair = new KeyValuePair<string, string>("joep", "monita");
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
//string fileName = $#"{Path}\{FileNameAntarctica}.pbf";
string fileName = $#"{Path}\{FileNameOSPbf}.pbf";
string newFileName = $"{fileName.Replace(".pbf", string.Empty)}-{Guid.NewGuid().ToString().Substring(0, 4)}.pbf";
Console.WriteLine("*** Complete");
string fileNameOutput = CompleteFlow(fileName, newFileName);
Console.WriteLine("");
Console.WriteLine("*** Display");
DisplayFlow(fileNameOutput);
Console.ReadLine();
}
private static string CompleteFlow(string fileName, string newFileName)
{
// 1. Open file and convert to bytes
byte[] fileBytes = FileToBytes(fileName);
// 2. Bytes to OSM stream source (pbf)
PBFOsmStreamSource osmStreamSource;
osmStreamSource = BytesToOsmStreamSource(fileBytes);
osmStreamSource.MoveNext();
if (osmStreamSource.Current() == null)
{
osmStreamSource = FileToOsmStreamSource(fileName);
osmStreamSource.MoveNext();
if (osmStreamSource.Current() == null)
{
throw new Exception("No current in stream.");
}
}
// 3. Add custom tag
AddTag(osmStreamSource);
// 4. OSM stream source to bytes
//byte[] osmStreamSourceBytes = OsmStreamSourceToBytes(osmStreamSource);
// 5. Bytes to file
//string fileNameOutput = BytesToFile(osmStreamSourceBytes, newFileName);
OsmStreamSourceToFile(osmStreamSource, newFileName);
Console.WriteLine(newFileName);
return newFileName;
}
private static void DisplayFlow(string fileName)
{
// 1. Open file and convert to bytes
byte[] fileBytes = FileToBytes(fileName);
// 2. Bytes to OSM stream source (pbf)
BytesToOsmStreamSource(fileBytes);
}
private static byte[] FileToBytes(string fileName)
{
Console.WriteLine(fileName);
return File.ReadAllBytes(fileName);
}
private static PBFOsmStreamSource BytesToOsmStreamSource(byte[] bytes)
{
MemoryStream memoryStream = new MemoryStream(bytes);
memoryStream.Position = 0;
PBFOsmStreamSource osmStreamSource = new PBFOsmStreamSource(memoryStream);
foreach (OsmGeo element in osmStreamSource.Where(osmGeo => osmGeo.Tags.Any(tag => tag.Key.StartsWith(KeyValuePair.Key))))
{
foreach (Tag elementTag in element.Tags.Where(tag => tag.Key.StartsWith(KeyValuePair.Key)))
{
Console.WriteLine("!!!!!!!!!!!!!! Tag found while reading !!!!!!!!!!!!!!!!!!".ToUpper());
}
}
return osmStreamSource;
}
private static PBFOsmStreamSource FileToOsmStreamSource(string fileName)
{
using (FileStream fileStream = new FileInfo(fileName).OpenRead())
{
PBFOsmStreamSource osmStreamSource = new PBFOsmStreamSource(fileStream);
return osmStreamSource;
}
}
private static void AddTag(PBFOsmStreamSource osmStreamSource)
{
osmStreamSource.Reset();
OsmGeo osmGeo = null;
while (osmGeo == null)
{
osmStreamSource.MoveNext();
osmGeo = osmStreamSource.Current();
if(osmGeo?.Tags == null)
{
osmGeo = null;
}
}
osmGeo.Tags.Add("joep", "monita");
Console.WriteLine($"{osmGeo.Tags.FirstOrDefault(tag => tag.Key.StartsWith(KeyValuePair.Key)).Key} - {osmGeo.Tags.FirstOrDefault(tag => tag.Key.StartsWith(KeyValuePair.Key)).Value}");
}
private static byte[] OsmStreamSourceToBytes(PBFOsmStreamSource osmStreamSource)
{
MemoryStream memoryStream = new MemoryStream();
PBFOsmStreamTarget target = new PBFOsmStreamTarget(memoryStream, true);
osmStreamSource.Reset();
target.Initialize();
UpdateTarget(osmStreamSource, target);
target.Flush();
target.Close();
return memoryStream.ToArray();
}
private static string BytesToFile(byte[] bytes, string fileName)
{
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
}
return fileName;
}
private static void OsmStreamSourceToFile(PBFOsmStreamSource osmStreamSource, string fileName)
{
using (FileStream fileStream = new FileInfo(fileName).OpenWrite())
{
PBFOsmStreamTarget target = new PBFOsmStreamTarget(fileStream, true);
osmStreamSource.Reset();
target.Initialize();
UpdateTarget(osmStreamSource, target);
target.Flush();
target.Close();
}
}
private static void UpdateTarget(OsmStreamSource osmStreamSource, OsmStreamTarget osmStreamTarget)
{
if (useRegisterSource)
{
osmStreamTarget.RegisterSource(osmStreamSource, osmGeo => true);
osmStreamTarget.Pull();
}
else
{
bool isFirst = true;
foreach (OsmGeo osmGeo in osmStreamSource)
{
Tag? tag = osmGeo.Tags?.FirstOrDefault(t => t.Key == KeyValuePair.Key);
switch (osmGeo.Type)
{
case OsmGeoType.Node:
if (isFirst)
{
for (int indexer = 0; indexer < 1; indexer++)
{
(osmGeo as Node).Tags.Add(new Tag(KeyValuePair.Key + Guid.NewGuid(), KeyValuePair.Value));
}
isFirst = false;
}
osmStreamTarget.AddNode(osmGeo as Node);
break;
case OsmGeoType.Way:
osmStreamTarget.AddWay(osmGeo as Way);
break;
case OsmGeoType.Relation:
osmStreamTarget.AddRelation(osmGeo as Relation);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
}
}
Already I posted this question on the GITHube page of OSMSharp as is linked here. Any help would be very appreciated.

Unity WebGL - accessing StreamingAssets folder from build uploaded in LMS /Server

I couldn't access the files StreamingAssets folder from WebGL build which is uploaded in LMS server, I kept those files in StreamingAssets folder to update it for future use. Followed the instruction given in unity manual, working fine in editor, but with direct build run and in LMS its not working.
http://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html
Posted in forums, they ask to follow the manual, but its not working. Please find the script attached here for more details. Check the coroutine function named ' userDetailsXmlPath ' which called at start of the game.
public string filePath = Application.streamingAssetsPath + "/UserDetails.xml";
public string result = "";
IEnumerator userDetailsXmlPath()
{
print (filePath);
if (filePath.Contains ("://") || filePath.Contains (":///")) {
WWW www = new WWW (filePath);
yield return www;
result = www.text;
print (result);
FetchUserDetails ();
} else {
result = File.ReadAllText (filePath);
print (result);
FetchUserDetails ();
}
}
public void FetchUserDetails()
{
XmlDocument userXml1 = new XmlDocument ();
// userXml1.Load(Application.streamingAssetsPath + "/UserDetails.xml");
// userXml1.Load(Application.dataPath + "js/UserDetails 1.xml");
// userXml1.LoadXml(userXml.text);
userXml1.LoadXml(result);
XmlNodeList userList = userXml1.GetElementsByTagName ("user");
foreach(XmlNode userValue in userList)
{
XmlNodeList userContent = userValue.ChildNodes;
objUser = new Dictionary<string, string>();
foreach(XmlNode value in userContent)
{
objUser.Add (value.Name, value.InnerText);
}
userFullDetails.Add (objUser);
userCountInXml = userList.Count;
userId = new string[userList.Count];
questionSetOfUser = new string[userList.Count];
}
AssignUserXmlValuesToArray ();
}
Please guild me to resolve this issue.
Access StreamingAssets path folder using WWW class https://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html
public string filePath = Application.streamingAssetsPath + "/UserDetails.xml";
public string result = "";
void Awake ()
{
filePath = Application.streamingAssetsPath + "/UserDetails.xml";
}
void Start ()
{
StartCoroutine(userDetailsXmlPath() );
}
IEnumerator userDetailsXmlPath()
{
print (filePath);
if (filePath.Contains ("://") || filePath.Contains (":///")) {
WWW www = new WWW (filePath);
yield return www;
result = www.text;
print (result);
FetchUserDetails ();
} else {
result = File.ReadAllText (filePath);
print (result);
FetchUserDetails ();
}
}
public void FetchUserDetails()
{
XmlDocument userXml1 = new XmlDocument ();
userXml1.LoadXml(result);
XmlNodeList userList = userXml1.GetElementsByTagName ("user");
foreach(XmlNode userValue in userList)
{
XmlNodeList userContent = userValue.ChildNodes;
objUser = new Dictionary<string, string>();
foreach(XmlNode value in userContent)
{
objUser.Add (value.Name, value.InnerText);
}
userFullDetails.Add (objUser);
userCountInXml = userList.Count;
userId = new string[userList.Count];
questionSetOfUser = new string[userList.Count];
}
AssignUserXmlValuesToArray ();
}

Unity3D WWW Post data async

I want to post a JSON to a website using the WWW class, But I get this answer from the server: "Synchronization problem.". Is there a way to change from sync to async? Thank You
You can run your WWW job in a coroutine (WWW supports this well):
using UnityEngine;
public class PostJSON : MonoBehaviour {
void Start () {
string url = "http://your_url_endpoint";
WWWForm form = new WWWForm();
Hashtable headers = form.headers;
headers["Content-Type"] = "application/json";
Hashtable data = new Hashtable();
data["message"] = "a sample message sent to service as json";
string json = JSON.JsonEncode(data);
byte[] bytes = Encoding.UTF8.GetBytes(json);
WWW www = new WWW(url, bytes, headers);
StartCoroutine(WaitForRequest(www));
}
IEnumerator WaitForRequest(WWW www)
{
yield return www
// check for errors
if (www.error == null)
{
Debug.Log("WWW Ok!: " + www.data);
} else {
Debug.Log("WWW Error: "+ www.error);
}
}
}
Here you have a running project which I use to talk to a json based REST service called KiiCloud:
http://blog.kii.com/?p=2939
HTH
The answer from German was very helpful, but I made some tweaks so that it'll compile and run (with sample serialization / deserialization bits).
Just pass in the BaseUrl you want to post to, i.e.
http://www.domain.com/somecontroller/someaction or whatever.
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class Person
{
public string Name;
}
[Serializable]
public class Response
{
public string SomeValue;
}
public class PostJSON : MonoBehaviour
{
public string BaseUrl;
private WWWForm form;
private Dictionary<string, string> headers = null;
void Start ()
{
var basUrlNotSpecified = string.IsNullOrEmpty(BaseUrl);
if(basUrlNotSpecified)
{
Debug.LogWarning("BaseUrl value not specified. Post abandoned.");
return;
}
form = new WWWForm();
headers = form.headers;
headers["Content-Type"] = "application/json";
headers["Accept"] = "application/json";
var person = new Person
{
Name = "Iulian Palade"
};
var json = JsonUtility.ToJson(person);
byte[] bytes = Encoding.UTF8.GetBytes(json);
WWW www = new WWW(BaseUrl, bytes, headers);
StartCoroutine(WaitForRequest(www));
}
IEnumerator WaitForRequest(WWW www)
{
yield return www;
if (www.error == null)
{
Debug.Log("WWW Ok!: " + www.text);
var response = JsonUtility.FromJson<Response>(www.text);
Debug.Log(response.SomeValue);
}
else
{
Debug.Log("WWW Error: "+ www.error);
}
}
}