HoloLens Unity program
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
5
down vote
favorite
I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.
An example is this:
string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags()
continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.
using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Linq;
using HoloToolkit.Unity;
using System.Collections.Generic;
using UnityEngine.UI;
using Newtonsoft.Json;
using System.Collections;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
#if !UNITY_EDITOR
using Windows.Networking.Sockets;
using Windows.Networking.Connectivity;
using Windows.Networking;
#endif
public class UDPCommunication : Singleton<UDPCommunication>
// Connection variables
private string port = "8000";
private string externalIP = "172.16.24.251";
private string externalPort = "8001";
public static int size = 0;
public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
public static List<string> varz;
public GameObject mainGameobject;
public GameObject upd1;
public GameObject upd2;
public GameObject upd3;
public GameObject upd4;
public GameObject canvas;
public GameObject Panel;
public GameObject image;
public GameObject imagetext;
public GameObject numbertext;
public Image testimg;
private GameObject getImageTags;
private GameObject getNumberTags;
private GameObject canvases;
private GameObject panels;
private GameObject tiles;
private GameObject texts;
private float scaler = 0.0125f;
// UI/Text elements
const string TurnOn = "on";
private uint sliderVal;
// Sets up a Queue
private string receivedmsg;
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
private void Awake()
IEnumerator updateTags()
yield return new WaitUntil(() => receivedmsg != null);
//string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
//string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
while (true)
var data = JToken.Parse(receivedmsg);
foreach (var value in data)
foreach (JArray arr in value)
for (int i = 0; i < arr.Count; i++)
foreach (var item in arr[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
var prop = token as JProperty;
var plc = (JObject)prop.Value;
string canvass = "Canvas" + i.ToString();
upd1 = transform.Find(canvass).gameObject;
upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
foreach (KeyValuePair<string, JToken> val in plc)
var plcvarkey = val.Key;
var plcvarvalue = val.Value;
if (plcvarvalue is JObject)
foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();
else
upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
//upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "True")
upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "False")
upd3.GetComponent<Image>().color = Color.red;
if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
upd4.GetComponent<Text>().text = plcvarvalue.ToString();
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
// Socket initialization
DatagramSocket socket;
#endif
#if !UNITY_EDITOR
IEnumerator initGUI()
yield return new WaitUntil(() => receivedmsg != null);
createUserInterface(receivedmsg);
Debug.Log("left initgui");
// use this for initialization
async void Start()
/*StartCoroutine(SendSliderValue());
Button btn_on = led1_button_on.GetComponent<Button>();
Button btn_off = led1_button_off.GetComponent<Button>();
Button btn1_on = led3_button_on.GetComponent<Button>();
Button btn1_off = led3_button_off.GetComponent<Button>();
btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
//string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
Debug.Log("Waiting for a connection...");
socket = new DatagramSocket();
socket.MessageReceived += Socket_MessageReceived;
//createUserInterface(receivedmsg);
HostName IP = null;
try
var icp = NetworkInformation.GetInternetConnectionProfile();
IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
.SingleOrDefault(
hn =>
hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
== icp.NetworkAdapter.NetworkAdapterId);
await socket.BindEndpointAsync(IP, port);
catch (Exception e)
Debug.Log(e.ToString());
Debug.Log(SocketError.GetStatus(e.HResult).ToString());
return;
SendMessage("test");
StartCoroutine(initGUI());
StartCoroutine(updateTags());
void TaskWithParameters(string message)
Debug.Log("sending Message");
SendMessage(message);
private async System.Threading.Tasks.Task SendMessage(string message)
using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))
using (var writer = new Windows.Storage.Streams.DataWriter(stream))
var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(data);
await writer.StoreAsync();
Debug.Log("Sent: " + message);
#else
// Use this for initialization.
void Start()
#endif
// Update is called once per frame.
void Update()
// Dequeues items until there are no more items on the queue.
while (ExecuteOnMainThread.Count > 0)
ExecuteOnMainThread.Dequeue().Invoke();
IEnumerator SendSliderValue()
Debug.Log("entered slider class");
GameObject theplayer = GameObject.Find("Hololens-Slider");
TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
while (true)
sliderVal = test.CurrentValue;
string s = "Slidervalue" + sliderVal.ToString();
SendMessage(s);
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
//this method gets called when a message is received
private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)
// Read the received message.
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
receivedmsg = await reader.ReadLineAsync();
//Debug.Log("MESSAGE: " + message);
// if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
// The message contains a JSON string which is received from the server.
if (ExecuteOnMainThread.Count == 0)
ExecuteOnMainThread.Enqueue(() =>
//Debug.Log(receivedmsg);
//pass msg to function here
);
#endif
public void createUserInterface(string jsonstring)
Debug.Log("entered create UI");
var root = JToken.Parse(jsonstring);
IterateJtoken(root);
canvases = new GameObject[abc.Count];
panels = new GameObject[abc.Count];
for (int i = 0; i < abc.Count; i++)
canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
canvases[i].name = "Canvas" + i;
canvases[i].transform.SetParent(mainGameobject.transform, false);
canvases[i].transform.position += new Vector3(i * 14, 0, 30);
panels[i] = Instantiate(Panel, transform.position, transform.rotation);
panels[i].name = "Panel";
panels[i].transform.SetParent(canvases[i].transform, false);
for (int z = 0; z < abc[i].Count; z++)
tiles = new GameObject[abc[i].Count];
texts = new GameObject[abc[i].Count];
tiles[z] = Instantiate(image, transform.position, transform.rotation);
tiles[z].name = abc[i].ElementAt(z).Key;
tiles[z].transform.SetParent(panels[i].transform, false);
texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
texts[z].name = abc[i].ElementAt(z).Key + "text";
texts[z].transform.SetParent(tiles[z].transform, false);
texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))
numbertext = Instantiate(imagetext, transform.position, transform.rotation);
numbertext.name = abc[i].ElementAt(z).Key + "value";
numbertext.transform.SetParent(tiles[z].transform, false);
texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);
public void IterateJtoken(JToken jtoken)
foreach (var value in jtoken)
foreach (JArray test in value)
for (int i = 0; i < test.Count; i++)
foreach (var item in test[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
if (token is JProperty)
var prop = token as JProperty;
//Console.WriteLine(prop.Name); //PLC name
var plc = (JObject)prop.Value;
Dictionary<string, string> variables = new Dictionary<string, string>();
foreach (KeyValuePair<string, JToken> val in plc)
if (val.Value is JObject)
JObject nestedobj = (JObject)val.Value;
foreach (JProperty nestedvariables in nestedobj.Properties())
size++;
//variables[nestedvariables.Name] = nestedvariables.Value.ToString();
var nestedVariableName = nestedvariables.Name;
var nestedVariableValue = nestedvariables.Value;
variables.Add(nestedVariableName, nestedVariableValue.ToString());
//Console.WriteLine(nestedVariableName+" "+nestedVariableValue);
else
size++;
//variables[val.Key] = val.Value.ToString();
var variableName = val.Key;
var variableValue = val.Value;
variables.Add(variableName, variableValue.ToString());
//Console.WriteLine(variableName+" "+variableValue);
abc.Add(new Dictionary<string, string>(variables));
The code's actually quite simple. For the function createUserInterface
, I generate a few public Gameobjects
, canvas, Panel, image and imagetext
. At the start of the function, the function IterateJtoken()
gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface
builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):
As for the updateTags function, the public string I've called receivedmsg
gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.
An example:
As you can see in the picture above, if I input the following string:
string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.
I would like to know if there is a way to make the methods updateTags()
, createUserInterface()
and IterateJToken()
more efficiently.
c# performance json unity3d
add a comment |Â
up vote
5
down vote
favorite
I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.
An example is this:
string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags()
continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.
using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Linq;
using HoloToolkit.Unity;
using System.Collections.Generic;
using UnityEngine.UI;
using Newtonsoft.Json;
using System.Collections;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
#if !UNITY_EDITOR
using Windows.Networking.Sockets;
using Windows.Networking.Connectivity;
using Windows.Networking;
#endif
public class UDPCommunication : Singleton<UDPCommunication>
// Connection variables
private string port = "8000";
private string externalIP = "172.16.24.251";
private string externalPort = "8001";
public static int size = 0;
public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
public static List<string> varz;
public GameObject mainGameobject;
public GameObject upd1;
public GameObject upd2;
public GameObject upd3;
public GameObject upd4;
public GameObject canvas;
public GameObject Panel;
public GameObject image;
public GameObject imagetext;
public GameObject numbertext;
public Image testimg;
private GameObject getImageTags;
private GameObject getNumberTags;
private GameObject canvases;
private GameObject panels;
private GameObject tiles;
private GameObject texts;
private float scaler = 0.0125f;
// UI/Text elements
const string TurnOn = "on";
private uint sliderVal;
// Sets up a Queue
private string receivedmsg;
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
private void Awake()
IEnumerator updateTags()
yield return new WaitUntil(() => receivedmsg != null);
//string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
//string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
while (true)
var data = JToken.Parse(receivedmsg);
foreach (var value in data)
foreach (JArray arr in value)
for (int i = 0; i < arr.Count; i++)
foreach (var item in arr[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
var prop = token as JProperty;
var plc = (JObject)prop.Value;
string canvass = "Canvas" + i.ToString();
upd1 = transform.Find(canvass).gameObject;
upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
foreach (KeyValuePair<string, JToken> val in plc)
var plcvarkey = val.Key;
var plcvarvalue = val.Value;
if (plcvarvalue is JObject)
foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();
else
upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
//upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "True")
upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "False")
upd3.GetComponent<Image>().color = Color.red;
if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
upd4.GetComponent<Text>().text = plcvarvalue.ToString();
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
// Socket initialization
DatagramSocket socket;
#endif
#if !UNITY_EDITOR
IEnumerator initGUI()
yield return new WaitUntil(() => receivedmsg != null);
createUserInterface(receivedmsg);
Debug.Log("left initgui");
// use this for initialization
async void Start()
/*StartCoroutine(SendSliderValue());
Button btn_on = led1_button_on.GetComponent<Button>();
Button btn_off = led1_button_off.GetComponent<Button>();
Button btn1_on = led3_button_on.GetComponent<Button>();
Button btn1_off = led3_button_off.GetComponent<Button>();
btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
//string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
Debug.Log("Waiting for a connection...");
socket = new DatagramSocket();
socket.MessageReceived += Socket_MessageReceived;
//createUserInterface(receivedmsg);
HostName IP = null;
try
var icp = NetworkInformation.GetInternetConnectionProfile();
IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
.SingleOrDefault(
hn =>
hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
== icp.NetworkAdapter.NetworkAdapterId);
await socket.BindEndpointAsync(IP, port);
catch (Exception e)
Debug.Log(e.ToString());
Debug.Log(SocketError.GetStatus(e.HResult).ToString());
return;
SendMessage("test");
StartCoroutine(initGUI());
StartCoroutine(updateTags());
void TaskWithParameters(string message)
Debug.Log("sending Message");
SendMessage(message);
private async System.Threading.Tasks.Task SendMessage(string message)
using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))
using (var writer = new Windows.Storage.Streams.DataWriter(stream))
var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(data);
await writer.StoreAsync();
Debug.Log("Sent: " + message);
#else
// Use this for initialization.
void Start()
#endif
// Update is called once per frame.
void Update()
// Dequeues items until there are no more items on the queue.
while (ExecuteOnMainThread.Count > 0)
ExecuteOnMainThread.Dequeue().Invoke();
IEnumerator SendSliderValue()
Debug.Log("entered slider class");
GameObject theplayer = GameObject.Find("Hololens-Slider");
TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
while (true)
sliderVal = test.CurrentValue;
string s = "Slidervalue" + sliderVal.ToString();
SendMessage(s);
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
//this method gets called when a message is received
private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)
// Read the received message.
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
receivedmsg = await reader.ReadLineAsync();
//Debug.Log("MESSAGE: " + message);
// if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
// The message contains a JSON string which is received from the server.
if (ExecuteOnMainThread.Count == 0)
ExecuteOnMainThread.Enqueue(() =>
//Debug.Log(receivedmsg);
//pass msg to function here
);
#endif
public void createUserInterface(string jsonstring)
Debug.Log("entered create UI");
var root = JToken.Parse(jsonstring);
IterateJtoken(root);
canvases = new GameObject[abc.Count];
panels = new GameObject[abc.Count];
for (int i = 0; i < abc.Count; i++)
canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
canvases[i].name = "Canvas" + i;
canvases[i].transform.SetParent(mainGameobject.transform, false);
canvases[i].transform.position += new Vector3(i * 14, 0, 30);
panels[i] = Instantiate(Panel, transform.position, transform.rotation);
panels[i].name = "Panel";
panels[i].transform.SetParent(canvases[i].transform, false);
for (int z = 0; z < abc[i].Count; z++)
tiles = new GameObject[abc[i].Count];
texts = new GameObject[abc[i].Count];
tiles[z] = Instantiate(image, transform.position, transform.rotation);
tiles[z].name = abc[i].ElementAt(z).Key;
tiles[z].transform.SetParent(panels[i].transform, false);
texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
texts[z].name = abc[i].ElementAt(z).Key + "text";
texts[z].transform.SetParent(tiles[z].transform, false);
texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))
numbertext = Instantiate(imagetext, transform.position, transform.rotation);
numbertext.name = abc[i].ElementAt(z).Key + "value";
numbertext.transform.SetParent(tiles[z].transform, false);
texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);
public void IterateJtoken(JToken jtoken)
foreach (var value in jtoken)
foreach (JArray test in value)
for (int i = 0; i < test.Count; i++)
foreach (var item in test[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
if (token is JProperty)
var prop = token as JProperty;
//Console.WriteLine(prop.Name); //PLC name
var plc = (JObject)prop.Value;
Dictionary<string, string> variables = new Dictionary<string, string>();
foreach (KeyValuePair<string, JToken> val in plc)
if (val.Value is JObject)
JObject nestedobj = (JObject)val.Value;
foreach (JProperty nestedvariables in nestedobj.Properties())
size++;
//variables[nestedvariables.Name] = nestedvariables.Value.ToString();
var nestedVariableName = nestedvariables.Name;
var nestedVariableValue = nestedvariables.Value;
variables.Add(nestedVariableName, nestedVariableValue.ToString());
//Console.WriteLine(nestedVariableName+" "+nestedVariableValue);
else
size++;
//variables[val.Key] = val.Value.ToString();
var variableName = val.Key;
var variableValue = val.Value;
variables.Add(variableName, variableValue.ToString());
//Console.WriteLine(variableName+" "+variableValue);
abc.Add(new Dictionary<string, string>(variables));
The code's actually quite simple. For the function createUserInterface
, I generate a few public Gameobjects
, canvas, Panel, image and imagetext
. At the start of the function, the function IterateJtoken()
gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface
builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):
As for the updateTags function, the public string I've called receivedmsg
gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.
An example:
As you can see in the picture above, if I input the following string:
string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.
I would like to know if there is a way to make the methods updateTags()
, createUserInterface()
and IterateJToken()
more efficiently.
c# performance json unity3d
add a comment |Â
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.
An example is this:
string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags()
continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.
using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Linq;
using HoloToolkit.Unity;
using System.Collections.Generic;
using UnityEngine.UI;
using Newtonsoft.Json;
using System.Collections;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
#if !UNITY_EDITOR
using Windows.Networking.Sockets;
using Windows.Networking.Connectivity;
using Windows.Networking;
#endif
public class UDPCommunication : Singleton<UDPCommunication>
// Connection variables
private string port = "8000";
private string externalIP = "172.16.24.251";
private string externalPort = "8001";
public static int size = 0;
public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
public static List<string> varz;
public GameObject mainGameobject;
public GameObject upd1;
public GameObject upd2;
public GameObject upd3;
public GameObject upd4;
public GameObject canvas;
public GameObject Panel;
public GameObject image;
public GameObject imagetext;
public GameObject numbertext;
public Image testimg;
private GameObject getImageTags;
private GameObject getNumberTags;
private GameObject canvases;
private GameObject panels;
private GameObject tiles;
private GameObject texts;
private float scaler = 0.0125f;
// UI/Text elements
const string TurnOn = "on";
private uint sliderVal;
// Sets up a Queue
private string receivedmsg;
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
private void Awake()
IEnumerator updateTags()
yield return new WaitUntil(() => receivedmsg != null);
//string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
//string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
while (true)
var data = JToken.Parse(receivedmsg);
foreach (var value in data)
foreach (JArray arr in value)
for (int i = 0; i < arr.Count; i++)
foreach (var item in arr[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
var prop = token as JProperty;
var plc = (JObject)prop.Value;
string canvass = "Canvas" + i.ToString();
upd1 = transform.Find(canvass).gameObject;
upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
foreach (KeyValuePair<string, JToken> val in plc)
var plcvarkey = val.Key;
var plcvarvalue = val.Value;
if (plcvarvalue is JObject)
foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();
else
upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
//upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "True")
upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "False")
upd3.GetComponent<Image>().color = Color.red;
if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
upd4.GetComponent<Text>().text = plcvarvalue.ToString();
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
// Socket initialization
DatagramSocket socket;
#endif
#if !UNITY_EDITOR
IEnumerator initGUI()
yield return new WaitUntil(() => receivedmsg != null);
createUserInterface(receivedmsg);
Debug.Log("left initgui");
// use this for initialization
async void Start()
/*StartCoroutine(SendSliderValue());
Button btn_on = led1_button_on.GetComponent<Button>();
Button btn_off = led1_button_off.GetComponent<Button>();
Button btn1_on = led3_button_on.GetComponent<Button>();
Button btn1_off = led3_button_off.GetComponent<Button>();
btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
//string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
Debug.Log("Waiting for a connection...");
socket = new DatagramSocket();
socket.MessageReceived += Socket_MessageReceived;
//createUserInterface(receivedmsg);
HostName IP = null;
try
var icp = NetworkInformation.GetInternetConnectionProfile();
IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
.SingleOrDefault(
hn =>
hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
== icp.NetworkAdapter.NetworkAdapterId);
await socket.BindEndpointAsync(IP, port);
catch (Exception e)
Debug.Log(e.ToString());
Debug.Log(SocketError.GetStatus(e.HResult).ToString());
return;
SendMessage("test");
StartCoroutine(initGUI());
StartCoroutine(updateTags());
void TaskWithParameters(string message)
Debug.Log("sending Message");
SendMessage(message);
private async System.Threading.Tasks.Task SendMessage(string message)
using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))
using (var writer = new Windows.Storage.Streams.DataWriter(stream))
var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(data);
await writer.StoreAsync();
Debug.Log("Sent: " + message);
#else
// Use this for initialization.
void Start()
#endif
// Update is called once per frame.
void Update()
// Dequeues items until there are no more items on the queue.
while (ExecuteOnMainThread.Count > 0)
ExecuteOnMainThread.Dequeue().Invoke();
IEnumerator SendSliderValue()
Debug.Log("entered slider class");
GameObject theplayer = GameObject.Find("Hololens-Slider");
TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
while (true)
sliderVal = test.CurrentValue;
string s = "Slidervalue" + sliderVal.ToString();
SendMessage(s);
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
//this method gets called when a message is received
private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)
// Read the received message.
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
receivedmsg = await reader.ReadLineAsync();
//Debug.Log("MESSAGE: " + message);
// if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
// The message contains a JSON string which is received from the server.
if (ExecuteOnMainThread.Count == 0)
ExecuteOnMainThread.Enqueue(() =>
//Debug.Log(receivedmsg);
//pass msg to function here
);
#endif
public void createUserInterface(string jsonstring)
Debug.Log("entered create UI");
var root = JToken.Parse(jsonstring);
IterateJtoken(root);
canvases = new GameObject[abc.Count];
panels = new GameObject[abc.Count];
for (int i = 0; i < abc.Count; i++)
canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
canvases[i].name = "Canvas" + i;
canvases[i].transform.SetParent(mainGameobject.transform, false);
canvases[i].transform.position += new Vector3(i * 14, 0, 30);
panels[i] = Instantiate(Panel, transform.position, transform.rotation);
panels[i].name = "Panel";
panels[i].transform.SetParent(canvases[i].transform, false);
for (int z = 0; z < abc[i].Count; z++)
tiles = new GameObject[abc[i].Count];
texts = new GameObject[abc[i].Count];
tiles[z] = Instantiate(image, transform.position, transform.rotation);
tiles[z].name = abc[i].ElementAt(z).Key;
tiles[z].transform.SetParent(panels[i].transform, false);
texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
texts[z].name = abc[i].ElementAt(z).Key + "text";
texts[z].transform.SetParent(tiles[z].transform, false);
texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))
numbertext = Instantiate(imagetext, transform.position, transform.rotation);
numbertext.name = abc[i].ElementAt(z).Key + "value";
numbertext.transform.SetParent(tiles[z].transform, false);
texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);
public void IterateJtoken(JToken jtoken)
foreach (var value in jtoken)
foreach (JArray test in value)
for (int i = 0; i < test.Count; i++)
foreach (var item in test[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
if (token is JProperty)
var prop = token as JProperty;
//Console.WriteLine(prop.Name); //PLC name
var plc = (JObject)prop.Value;
Dictionary<string, string> variables = new Dictionary<string, string>();
foreach (KeyValuePair<string, JToken> val in plc)
if (val.Value is JObject)
JObject nestedobj = (JObject)val.Value;
foreach (JProperty nestedvariables in nestedobj.Properties())
size++;
//variables[nestedvariables.Name] = nestedvariables.Value.ToString();
var nestedVariableName = nestedvariables.Name;
var nestedVariableValue = nestedvariables.Value;
variables.Add(nestedVariableName, nestedVariableValue.ToString());
//Console.WriteLine(nestedVariableName+" "+nestedVariableValue);
else
size++;
//variables[val.Key] = val.Value.ToString();
var variableName = val.Key;
var variableValue = val.Value;
variables.Add(variableName, variableValue.ToString());
//Console.WriteLine(variableName+" "+variableValue);
abc.Add(new Dictionary<string, string>(variables));
The code's actually quite simple. For the function createUserInterface
, I generate a few public Gameobjects
, canvas, Panel, image and imagetext
. At the start of the function, the function IterateJtoken()
gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface
builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):
As for the updateTags function, the public string I've called receivedmsg
gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.
An example:
As you can see in the picture above, if I input the following string:
string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.
I would like to know if there is a way to make the methods updateTags()
, createUserInterface()
and IterateJToken()
more efficiently.
c# performance json unity3d
I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.
An example is this:
string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags()
continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.
using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Linq;
using HoloToolkit.Unity;
using System.Collections.Generic;
using UnityEngine.UI;
using Newtonsoft.Json;
using System.Collections;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
#if !UNITY_EDITOR
using Windows.Networking.Sockets;
using Windows.Networking.Connectivity;
using Windows.Networking;
#endif
public class UDPCommunication : Singleton<UDPCommunication>
// Connection variables
private string port = "8000";
private string externalIP = "172.16.24.251";
private string externalPort = "8001";
public static int size = 0;
public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
public static List<string> varz;
public GameObject mainGameobject;
public GameObject upd1;
public GameObject upd2;
public GameObject upd3;
public GameObject upd4;
public GameObject canvas;
public GameObject Panel;
public GameObject image;
public GameObject imagetext;
public GameObject numbertext;
public Image testimg;
private GameObject getImageTags;
private GameObject getNumberTags;
private GameObject canvases;
private GameObject panels;
private GameObject tiles;
private GameObject texts;
private float scaler = 0.0125f;
// UI/Text elements
const string TurnOn = "on";
private uint sliderVal;
// Sets up a Queue
private string receivedmsg;
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
private void Awake()
IEnumerator updateTags()
yield return new WaitUntil(() => receivedmsg != null);
//string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
//string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
while (true)
var data = JToken.Parse(receivedmsg);
foreach (var value in data)
foreach (JArray arr in value)
for (int i = 0; i < arr.Count; i++)
foreach (var item in arr[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
var prop = token as JProperty;
var plc = (JObject)prop.Value;
string canvass = "Canvas" + i.ToString();
upd1 = transform.Find(canvass).gameObject;
upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
foreach (KeyValuePair<string, JToken> val in plc)
var plcvarkey = val.Key;
var plcvarvalue = val.Value;
if (plcvarvalue is JObject)
foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();
else
upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
//upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "True")
upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "False")
upd3.GetComponent<Image>().color = Color.red;
if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))
upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
upd4.GetComponent<Text>().text = plcvarvalue.ToString();
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
// Socket initialization
DatagramSocket socket;
#endif
#if !UNITY_EDITOR
IEnumerator initGUI()
yield return new WaitUntil(() => receivedmsg != null);
createUserInterface(receivedmsg);
Debug.Log("left initgui");
// use this for initialization
async void Start()
/*StartCoroutine(SendSliderValue());
Button btn_on = led1_button_on.GetComponent<Button>();
Button btn_off = led1_button_off.GetComponent<Button>();
Button btn1_on = led3_button_on.GetComponent<Button>();
Button btn1_off = led3_button_off.GetComponent<Button>();
btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
//string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
Debug.Log("Waiting for a connection...");
socket = new DatagramSocket();
socket.MessageReceived += Socket_MessageReceived;
//createUserInterface(receivedmsg);
HostName IP = null;
try
var icp = NetworkInformation.GetInternetConnectionProfile();
IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
.SingleOrDefault(
hn =>
hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
== icp.NetworkAdapter.NetworkAdapterId);
await socket.BindEndpointAsync(IP, port);
catch (Exception e)
Debug.Log(e.ToString());
Debug.Log(SocketError.GetStatus(e.HResult).ToString());
return;
SendMessage("test");
StartCoroutine(initGUI());
StartCoroutine(updateTags());
void TaskWithParameters(string message)
Debug.Log("sending Message");
SendMessage(message);
private async System.Threading.Tasks.Task SendMessage(string message)
using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))
using (var writer = new Windows.Storage.Streams.DataWriter(stream))
var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(data);
await writer.StoreAsync();
Debug.Log("Sent: " + message);
#else
// Use this for initialization.
void Start()
#endif
// Update is called once per frame.
void Update()
// Dequeues items until there are no more items on the queue.
while (ExecuteOnMainThread.Count > 0)
ExecuteOnMainThread.Dequeue().Invoke();
IEnumerator SendSliderValue()
Debug.Log("entered slider class");
GameObject theplayer = GameObject.Find("Hololens-Slider");
TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
while (true)
sliderVal = test.CurrentValue;
string s = "Slidervalue" + sliderVal.ToString();
SendMessage(s);
yield return new WaitForSeconds(0.5f);
#if !UNITY_EDITOR
//this method gets called when a message is received
private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)
// Read the received message.
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
receivedmsg = await reader.ReadLineAsync();
//Debug.Log("MESSAGE: " + message);
// if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
// The message contains a JSON string which is received from the server.
if (ExecuteOnMainThread.Count == 0)
ExecuteOnMainThread.Enqueue(() =>
//Debug.Log(receivedmsg);
//pass msg to function here
);
#endif
public void createUserInterface(string jsonstring)
Debug.Log("entered create UI");
var root = JToken.Parse(jsonstring);
IterateJtoken(root);
canvases = new GameObject[abc.Count];
panels = new GameObject[abc.Count];
for (int i = 0; i < abc.Count; i++)
canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
canvases[i].name = "Canvas" + i;
canvases[i].transform.SetParent(mainGameobject.transform, false);
canvases[i].transform.position += new Vector3(i * 14, 0, 30);
panels[i] = Instantiate(Panel, transform.position, transform.rotation);
panels[i].name = "Panel";
panels[i].transform.SetParent(canvases[i].transform, false);
for (int z = 0; z < abc[i].Count; z++)
tiles = new GameObject[abc[i].Count];
texts = new GameObject[abc[i].Count];
tiles[z] = Instantiate(image, transform.position, transform.rotation);
tiles[z].name = abc[i].ElementAt(z).Key;
tiles[z].transform.SetParent(panels[i].transform, false);
texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
texts[z].name = abc[i].ElementAt(z).Key + "text";
texts[z].transform.SetParent(tiles[z].transform, false);
texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))
numbertext = Instantiate(imagetext, transform.position, transform.rotation);
numbertext.name = abc[i].ElementAt(z).Key + "value";
numbertext.transform.SetParent(tiles[z].transform, false);
texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);
public void IterateJtoken(JToken jtoken)
foreach (var value in jtoken)
foreach (JArray test in value)
for (int i = 0; i < test.Count; i++)
foreach (var item in test[i])
var itemproperties = item.Parent;
foreach (JToken token in itemproperties)
if (token is JProperty)
var prop = token as JProperty;
//Console.WriteLine(prop.Name); //PLC name
var plc = (JObject)prop.Value;
Dictionary<string, string> variables = new Dictionary<string, string>();
foreach (KeyValuePair<string, JToken> val in plc)
if (val.Value is JObject)
JObject nestedobj = (JObject)val.Value;
foreach (JProperty nestedvariables in nestedobj.Properties())
size++;
//variables[nestedvariables.Name] = nestedvariables.Value.ToString();
var nestedVariableName = nestedvariables.Name;
var nestedVariableValue = nestedvariables.Value;
variables.Add(nestedVariableName, nestedVariableValue.ToString());
//Console.WriteLine(nestedVariableName+" "+nestedVariableValue);
else
size++;
//variables[val.Key] = val.Value.ToString();
var variableName = val.Key;
var variableValue = val.Value;
variables.Add(variableName, variableValue.ToString());
//Console.WriteLine(variableName+" "+variableValue);
abc.Add(new Dictionary<string, string>(variables));
The code's actually quite simple. For the function createUserInterface
, I generate a few public Gameobjects
, canvas, Panel, image and imagetext
. At the start of the function, the function IterateJtoken()
gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface
builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):
As for the updateTags function, the public string I've called receivedmsg
gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.
An example:
As you can see in the picture above, if I input the following string:
string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";
The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.
I would like to know if there is a way to make the methods updateTags()
, createUserInterface()
and IterateJToken()
more efficiently.
c# performance json unity3d
edited Jul 31 at 4:21
Jamalâ¦
30.1k11114225
30.1k11114225
asked Jul 30 at 14:25
hoek rand
261
261
add a comment |Â
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200588%2fhololens-unity-program%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password