So, we are building a generic JSON parser in Unity without relying on external libraries like Newtonsoft.Json
. Why? Well, this approach gives us complete control and avoids external dependencies, but it requires a bit more elbow grease. Fear not, we’ll craft a robust solution that handles any JSON response (well it tries) and stores the results for further use.
Why Go Library-Free?
- No External Dependencies: No need to import or maintain third-party libraries.
- Performance: Tailored to your project’s specific needs.
- Learning Experience: Dive deeper into the inner workings of JSON parsing.
What Are We Building?
Our goal is to:
- Parse JSON responses (single objects and arrays).
- Support Unity-friendly structures like
List<T>
. - Handle nested JSON manually.
Step 1: Setting the Scene
- Open Unity and create a new script called
GenericJSONParser.cs
. - No external libraries are allowed just native Unity C#.
Step 2: JSON Basics in C#
JSON is essentially a combination of:
- Objects: Key-value pairs, e.g.,
{ "key": "value" }
. - Arrays: Lists of objects or values, e.g.,
[ { "key": "value" }, { "key2": "value2" } ]
.
The core tools we’ll use to parse JSON in Unity:
Dictionary<string, object>
: Represents JSON objects.List<object>
: Represents JSON arrays.- Unity’s
JsonUtility
: For serializing and deserializing simple objects.
Step 3: Writing the Core Parser
Here’s our JSON parser that can process generic data and handle arrays or single objects.
GenericJSONParser.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class GenericJSONParser
{
// Parse a JSON string into a Dictionary or List
public static object ParseJSON(string json)
{
json = json.Trim();
if (json.StartsWith("{") && json.EndsWith("}"))
{
// JSON Object
return ParseJSONObject(json);
}
else if (json.StartsWith("[") && json.EndsWith("]"))
{
// JSON Array
return ParseJSONArray(json);
}
else
{
Debug.LogError("Invalid JSON format.");
return null;
}
}
// Parse JSON Object
private static Dictionary<string, object> ParseJSONObject(string json)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
json = json.Substring(1, json.Length - 2); // Remove { and }
string[] pairs = SplitJSONPairs(json);
foreach (string pair in pairs)
{
string[] keyValue = pair.Split(new[] { ':' }, 2);
string key = StripQuotes(keyValue[0].Trim());
object value = ParseValue(keyValue[1].Trim());
dict[key] = value;
}
return dict;
}
// Parse JSON Array
private static List<object> ParseJSONArray(string json)
{
List<object> list = new List<object>();
json = json.Substring(1, json.Length - 2); // Remove [ and ]
string[] values = SplitJSONArray(json);
foreach (string value in values)
{
list.Add(ParseValue(value.Trim()));
}
return list;
}
// Parse an individual value
private static object ParseValue(string value)
{
if (value.StartsWith("\"") && value.EndsWith("\""))
{
return StripQuotes(value);
}
else if (value.StartsWith("{"))
{
return ParseJSONObject(value);
}
else if (value.StartsWith("["))
{
return ParseJSONArray(value);
}
else if (value.Equals("true", StringComparison.OrdinalIgnoreCase))
{
return true;
}
else if (value.Equals("false", StringComparison.OrdinalIgnoreCase))
{
return false;
}
else if (value.Equals("null", StringComparison.OrdinalIgnoreCase))
{
return null;
}
else if (double.TryParse(value, out double number))
{
return number;
}
return value;
}
// Utility: Split JSON pairs in objects
private static string[] SplitJSONPairs(string json)
{
List<string> pairs = new List<string>();
int bracketCount = 0;
int startIndex = 0;
for (int i = 0; i < json.Length; i++)
{
char c = json[i];
if (c == '{' || c == '[') bracketCount++;
if (c == '}' || c == ']') bracketCount--;
if (c == ',' && bracketCount == 0)
{
pairs.Add(json.Substring(startIndex, i - startIndex).Trim());
startIndex = i + 1;
}
}
pairs.Add(json.Substring(startIndex).Trim());
return pairs.ToArray();
}
// Utility: Split JSON values in arrays
private static string[] SplitJSONArray(string json)
{
return SplitJSONPairs(json);
}
// Utility: Remove quotes from a string
private static string StripQuotes(string str)
{
if (str.StartsWith("\"") && str.EndsWith("\""))
{
return str.Substring(1, str.Length - 2);
}
return str;
}
}
Step 4: Testing the Parser
Here’s how we’ll test it with simple and nested JSON examples.
1: Parsing Simple JSON
void Start()
{
string simpleJSON = "{ \"Name\": \"Alice\", \"Level\": 10, \"Experience\": 120.5 }";
Dictionary<string, object> parsed = GenericJSONParser.ParseJSON(simpleJSON) as Dictionary<string, object>;
Debug.Log($"Name: {parsed["Name"]}");
Debug.Log($"Level: {parsed["Level"]}");
Debug.Log($"Experience: {parsed["Experience"]}");
}
2: Parsing JSON Arrays
void Start()
{
string arrayJSON = "[{ \"Name\": \"Alice\", \"Level\": 10 }, { \"Name\": \"Bob\", \"Level\": 12 }]";
List<object> parsed = GenericJSONParser.ParseJSON(arrayJSON) as List<object>;
foreach (var obj in parsed)
{
var player = obj as Dictionary<string, object>;
Debug.Log($"Name: {player["Name"]}, Level: {player["Level"]}");
}
}
3: Nested JSON
void Start()
{
string nestedJSON = "{ \"Team\": \"Warriors\", \"Players\": [{ \"Name\": \"Alice\", \"Level\": 10 }, { \"Name\": \"Bob\", \"Level\": 12 }] }";
Dictionary<string, object> parsed = GenericJSONParser.ParseJSON(nestedJSON) as Dictionary<string, object>;
Debug.Log($"Team: {parsed["Team"]}");
List<object> players = parsed["Players"] as List<object>;
foreach (var obj in players)
{
var player = obj as Dictionary<string, object>;
Debug.Log($"Name: {player["Name"]}, Level: {player["Level"]}");
}
}
Key Features of This Parser
- Handles Both Objects and Arrays: Automatically detects JSON format and processes accordingly.
- Supports Nested JSON: Works recursively to handle complex structures.
- Unity-Compatible: Outputs data as
Dictionary<string, object>
orList<object>
for flexibility.
Conclusion
Building a generic JSON parser in unity from scratch is a rewarding challenge that sharpens your understanding of JSON structures and C#. While it takes a bit more effort than using libraries, this approach is highly customizable and avoids external dependencies.
Now you’ve got a lightweight, reusable parser that works for any JSON format no libraries required. Happy coding! 🚀
If you have any issues or suggestions, please do comment down below!!! and thanks for reading 😊👍
If you want to learn how to create a Generic CRUD API in PHP, then you can find the source code here
or if you want to develop a routing system you can check that out Create a Dynamic PHP Routing System from Scratch