If I’m understanding correctly you have a file of card data that you want to load into a Scriptable Object Card?
Assuming the file data is JSON format:
{
"cards": [
{
"cardName": "Fireball",
"description": "Deals 5 damage to a target.",
"manaCost": 3,
"attack": 0,
"defense": 0,
"rarity": "Common"
},
{
"cardName": "Healing Touch",
"description": "Restores 5 health to a friendly target.",
"manaCost": 2,
"attack": 0,
"defense": 0,
"rarity": "Uncommon"
}
// Add more cards as needed
]
}
and your scriptable object ‘Card’ is something like this
using UnityEngine;
[CreateAssetMenu(fileName = "NewCard", menuName = "Card")]
public class Card : ScriptableObject
{
public string cardName;
public string description;
public int manaCost;
public int attack;
public int defense;
public string rarity;
}
You will need to create a data class for the JSON deserialization, as you cannot directly deserialize to an SO.
using System;
using System.Collections.Generic;
[Serializable]
public class CardDataList
{
public List<CardData> cards;
}
[Serializable]
public class CardData
{
public string cardName;
public string description;
public int manaCost;
public int attack;
public int defense;
public string rarity;
}
Then you can create a custom editor window to import your card assets.
using UnityEngine;
using UnityEditor;
using System.IO;
public class CardImporter : EditorWindow
{
private string jsonFilePath = "Assets/Resources/Data/cards.json";
private string outputFolder = "Assets/Resources/Cards";
[MenuItem("Tools/Card Importer")]
public static void ShowWindow()
{
GetWindow<CardImporter>("Card Importer");
}
private void OnGUI()
{
GUILayout.Label("Import Cards from JSON", EditorStyles.boldLabel);
jsonFilePath = EditorGUILayout.TextField("JSON File Path", jsonFilePath);
outputFolder = EditorGUILayout.TextField("Output Folder", outputFolder);
if (GUILayout.Button("Import Cards"))
{
ImportCards();
}
}
private void ImportCards()
{
if (!File.Exists(jsonFilePath))
{
EditorUtility.DisplayDialog("Error", "JSON file not found at " + jsonFilePath, "OK");
return;
}
string jsonContent = File.ReadAllText(jsonFilePath);
CardDataList cardDataList = JsonUtility.FromJson<CardDataList>(jsonContent);
if (cardDataList == null || cardDataList.cards == null)
{
EditorUtility.DisplayDialog("Error", "Failed to parse JSON.", "OK");
return;
}
// Ensure the output folder exists
if (!AssetDatabase.IsValidFolder(outputFolder))
{
AssetDatabase.CreateFolder("Assets/Resources", "Cards");
}
foreach (CardData data in cardDataList.cards)
{
// Create a new Card asset
Card card = ScriptableObject.CreateInstance<Card>();
card.cardName = data.cardName;
card.description = data.description;
card.manaCost = data.manaCost;
card.attack = data.attack;
card.defense = data.defense;
card.rarity = data.rarity;
// Assign additional fields as needed
// Define the asset path
string assetPath = Path.Combine(outputFolder, data.cardName + ".asset").Replace("\\", "/");
// Check if the asset already exists to avoid duplicates
Card existingCard = AssetDatabase.LoadAssetAtPath<Card>(assetPath);
if (existingCard != null)
{
// Optionally update existing asset
EditorUtility.CopySerialized(card, existingCard);
EditorUtility.SetDirty(existingCard);
Debug.Log("Updated existing card: " + data.cardName);
}
else
{
// Create new asset
AssetDatabase.CreateAsset(card, assetPath);
Debug.Log("Created new card: " + data.cardName);
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("Import Complete", "Cards have been imported successfully.", "OK");
}
}
They key parts of this script is deserializing your data:
CardDataList cardDataList = JsonUtility.FromJson<CardDataList>(jsonContent);
And then creating new Scriptable Objects from that deserialized data
Card card = ScriptableObject.CreateInstance<Card>();
..
AssetDatabase.CreateAsset(card, assetPath);
..
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
If you’re doing it frequently you can probably hardcode the json and output paths and change it to a menu item