JsonUtility.FromJson 不能设置{ get; set; }

本文介绍如何在Unity中使用JsonUtility解析从API获取的JSON数据,并通过具体代码示例展示了如何将JSON数据映射到C#类中,解决在设置属性时遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  http://json2csharp.chahuo.com/ 根据json数据生成的类,如下;

/*
     *其JsonUtility.FromJson 不能设置{ get; set; },一直报空引用,需要设置实例对象异常,最后我把{ get; set; }删了就可以存进来了,我真的想······
     *public class Data {
        public string A  { get; set; }
        public string B  { get; set; }
        public string C  { get; set; }
        public string D  { get; set; }
    }

    public class RootObject {
        public List<Data> data { get; set; }
        public string total  { get; set; }
    }
     *
     */

[System.Serializable]
    public class Item
    {

        public string A;
        public string B;
        public string C;
        public string D;

    }

    // 接受 api 返回的 json 数据
    [System.Serializable]
    public class ItemData
    {

        public List<Item> data;
        public int total;

    }

    void Start()
    {
        if (!File.Exists(JsonPath()))
            {
                Debug.LogError("读取的文件不存在!");
                return;
            }
//            string jsonString = File.ReadAllText(Application.dataPath + "/Data/ItemJsonFromApi.json");
            string json = File.ReadAllText(JsonPath());
        ItemData itemDate = JsonUtility.FromJson<ItemData>(json);
        Debug.Log(itemDate.total);
        foreach (var item in itemDate.data)
        {
            Debug.Log(item.A);
        }
    }
    //保存json文件路径
    string JsonPath()
        {
            return Application.streamingAssetsPath + "/trouble.json";
        }

 

///////////json 数据

{
    "data": [
        {
            "A": "zhanXXXXXXXXXXXg",
            "B": "00000000zhangXXXXXXXX",
            "C": "gun1.png",
            "D":"DDDD"
        },
        {
            "A": 2,
            "B": "gun2",
            "C": "gun2.png",
            "D":"DDDD"
        },
        {
            "A": 3,
            "B": "gun3",
            "C": "gun1.png",
            "D":"DDDD"
        },
        {
            "A": 4,
            "B": "gun4",
            "C": "gun2.png",
            "D":"DDDD"
        }
    ],
    "total": 333
}

现在我来说一下目前的情况,首先我的系统目前结构是Config(GridConfig.cs),Core(GridData.cs,GridObjectType.cs,TerrainType.cs),DataModels(ChessData.cs,GridCell.cs,StructureData.cs,TerrainConfig.cs,TerrainData.cs,TokenData.cs),Initialization(GameInitializer.cs),Managers(GameDataManager.cs,GridManager.cs,TerrainGenerator.cs),Objects(GirdObject.cs,StructureObject.cs,TerrainObject.cs),GridBugView.cs,InputHandler.cs,然后Scene目前是GameManager(搭载GameInitializer(没拖拽TerrainGenerator,DataManager)和GameDataManager),GridSystem(GirdManager(已拖动Config,Tilemap,DefaultTile为None)和TerrainGenerator(已拖动Tilemap,Config,DefaultTerrain为null)),Grid(Tilemap)这些,然后sprite地形我做了几个,分别是Terrains(结构为空物体搭载sprite)和它的Forest, Grass, Village,Water变体,tag什么的都没设置呢,然后人物也是一样的结构但不是Terrains的变体,只做了一个叫TestCharacter,别的先不做,你看着办吧,然后有非常多的报错,你先看看代码然后给我一个整理之后的正确可运行版本,告诉我都需要做什么using System.Collections.Generic; using UnityEngine; using UnityEngine.Tilemaps; namespace gridstudy { [CreateAssetMenu(menuName = "Grid/GridConfig")] public class GridConfig : ScriptableObject { public int GridWidth = 10; public int GridHeight = 10; public TileBase DefaultTile; [SerializeField] private List<TerrainConfig> _terrainConfigs = new List<TerrainConfig>(); [Header("Prefabs")] public GameObject TerrainPrefab; public GameObject StructurePrefab; public GameObject ChessPrefab; public GameObject TokenPrefab; public TerrainConfig GetTerrainConfig(TerrainType type) { return _terrainConfigs.Find(c => c.type == type); } public List<TerrainConfig> GetAllTerrainConfigs() { return new List<TerrainConfig>(_terrainConfigs); } } }using System.Collections.Generic; using UnityEngine; namespace gridstudy { [System.Serializable] public class GridData { public int width; public int height; public GridCell[,] cells; public GridData(int w, int h) { width = w; height = h; cells = new GridCell[w, h]; } } }namespace gridstudy { public enum GridObjectType { Terrain, Structure, Chess, Token } }namespace gridstudy { public enum TerrainType { Grass, Water, Mountain, Forest, Desert, Road } }using System.Collections; using UnityEngine; namespace gridstudy { // ChessData.cs [CreateAssetMenu(menuName = "Unit/ChessData")] public class ChessData : ScriptableObject { public string unitName; public int moveRange; public int attackPower; } }using System.Collections.Generic; using UnityEngine; namespace gridstudy { [System.Serializable] public class GridCell { public Vector2Int coordinate; public TerrainData terrain; // TODO: 实现以下类 public StructureData structure; public ChessData chess; public List<TokenData> tokens; public GridCell(Vector2Int coord) { coordinate = coord; tokens = new List<TokenData>(); } } }using System.Collections; using UnityEngine; namespace gridstudy { [CreateAssetMenu(menuName = "Structure/StructureData")] public class StructureData : ScriptableObject { public string structureName; public int health; public int buildCost; } }using UnityEngine; using UnityEngine.Tilemaps; namespace gridstudy { [CreateAssetMenu(menuName = "Terrain/TerrainConfig")] public class TerrainConfig : ScriptableObject { public TerrainType type; public TileBase tile; public int movementCost = 1; public bool isWalkable = true; public bool isBuildable = false; } }using UnityEngine; namespace gridstudy { [System.Serializable] public class TerrainData { public TerrainType type; public Vector2Int coordinate; public int variantIndex; [System.NonSerialized] public bool isOccupied; } }using System.Collections; using UnityEngine; namespace gridstudy { [CreateAssetMenu(menuName = "Item/TokenData")] public class TokenData : ScriptableObject { public string itemName; public Sprite icon; } }using UnityEngine; namespace gridstudy { public class GameInitializer : MonoBehaviour { [SerializeField] private TerrainGenerator _terrainGenerator; [SerializeField] private GameDataManager _dataManager; void Start() { if (!_dataManager.LoadGame()) InitializeNewGame(); GridData gridData = _dataManager.GetGridData(); _terrainGenerator.InitializeGrid(gridData.width, gridData.height); } private void InitializeNewGame() { GridData newGrid = new GridData(10, 8); _dataManager.SetGridData(newGrid); } void OnApplicationQuit() { _dataManager.SaveGame(); } } }using UnityEngine; namespace gridstudy { public class GameDataManager : MonoBehaviour { private const string SAVE_KEY = "GridData"; private GridData _currentGridData; public void SaveGame() { if (_currentGridData == null) return; string jsonData = JsonUtility.ToJson(_currentGridData); PlayerPrefs.SetString(SAVE_KEY, jsonData); PlayerPrefs.Save(); Debug.Log("Game data saved successfully"); } public bool LoadGame() { if (PlayerPrefs.HasKey(SAVE_KEY)) { string jsonData = PlayerPrefs.GetString(SAVE_KEY); _currentGridData = JsonUtility.FromJson<GridData>(jsonData); Debug.Log("Game data loaded successfully"); return true; } return false; } public GridData GetGridData() => _currentGridData; public void SetGridData(GridData data) => _currentGridData = data; // 在 GameDataManager 中添加 public void SaveFullGameState() { // 收集所有网格对象数据 foreach (var cell in _currentGridData.cells) { if (cell.terrain != null) SaveTerrainData(cell.terrain); if (cell.structure != null) SaveStructureData(报错)(cell.structure); } // 保存到PlayerPrefs(实际项目应使用文件存储) PlayerPrefs.SetString("GameState", JsonUtility.ToJson(_currentGridData)); } private void SaveTerrainData(TerrainData data) { // 实现具体保存逻辑 } } }using System.Collections.Generic; using UnityEngine; using UnityEngine.Tilemaps; namespace gridstudy { public class GridManager : MonoBehaviour { [SerializeField] private GridConfig _config; [SerializeField] private Tilemap _terrainTilemap; [SerializeField] private TileBase _defaultTile; private GridCell[,] _gridData; private Dictionary<Vector2Int, List<GridObject>> _objectsMap = new(); private Dictionary<GridObjectType, GameObject> _prefabMap; void Awake() { // 初始化prefab映射 _prefabMap = new Dictionary<GridObjectType, GameObject> { { GridObjectType.Terrain, _config.TerrainPrefab }, { GridObjectType.Structure, _config.StructurePrefab }, { GridObjectType.Chess, _config.ChessPrefab }, { GridObjectType.Token, _config.TokenPrefab } }; } public void GenerateGrid(int width, int height) { _gridData = new GridCell[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { _gridData[x, y] = new GridCell(new Vector2Int(x, y)); Vector3Int tilePos = new Vector3Int(x, y, 0); _terrainTilemap.SetTile(tilePos, _defaultTile); } } } public GridCell GetCellData(Vector2Int coord) { return _gridData[coord.x, coord.y]; } public void PlaceObject<T>(GridObjectType type, Vector2Int gridPos, T data) where T: ScriptableObject { if (!_prefabMap.TryGetValue(type, out GameObject prefab)) return; GameObject instance = Instantiate(prefab, GridToWorld(gridPos), Quaternion.identity); GridObject gridObject = instance.GetComponent<GridObject>(); gridObject.GridPosition = gridPos; // 更新数据层 GridCell cell = GetCellData(gridPos); switch (type) { case GridObjectType.Terrain: cell.terrain = data as TerrainData; break; case GridObjectType.Structure: cell.structure = data as StructureData; break; // ...其他类型处理 } if (!_objectsMap.ContainsKey(gridPos)) _objectsMap[gridPos] = new List<GridObject>(); _objectsMap[gridPos].Add(gridObject); gridObject.OnPlaced(); } private Vector3 GridToWorld(Vector2Int gridPos) { return new Vector3(gridPos.x + 0.5f, gridPos.y + 0.5f, 0); } } }using UnityEngine; using UnityEngine.Tilemaps; namespace gridstudy { public class TerrainGenerator : MonoBehaviour { [Header("References")] [SerializeField] private Tilemap _terrainTilemap; [SerializeField] private GridConfig _gridConfig; [Header("Terrain Settings")] [SerializeField] private TerrainConfig _defaultTerrain; private TerrainType[,] _terrainLayout; private GridData _gridData; public void InitializeGrid(int width, int height) { _gridData = new GridData(width, height); _terrainLayout = new TerrainType[width, height]; GenerateBaseTerrain(); RenderTerrainToTilemap(); } private void GenerateBaseTerrain() { for (int x = 0; x < _gridData.width; x++) { for (int y = 0; y < _gridData.height; y++) { _gridData.cells[x, y] = new GridCell(new Vector2Int(x, y)); TerrainType terrainType = GetTerrainTypeForPosition(x, y); _terrainLayout[x, y] = terrainType; _gridData.cells[x, y].terrain = new TerrainData { type = terrainType, coordinate = new Vector2Int(x, y), variantIndex = Random.Range(0, 3) }; } } } private TerrainType GetTerrainTypeForPosition(int x, int y) { if (x == 0 || y == 0 || x == _gridData.width - 1 || y == _gridData.height - 1) return TerrainType.Water; return TerrainType.Grass; } private void RenderTerrainToTilemap() { for (int x = 0; x < _gridData.width; x++) { for (int y = 0; y < _gridData.height; y++) { Vector3Int tilePos = new Vector3Int(x, y, 0); TerrainType type = _gridData.cells[x, y].terrain.type; TerrainConfig config = _gridConfig.GetTerrainConfig(type); _terrainTilemap.SetTile(tilePos, config != null ? config.tile : _defaultTerrain.tile); } } } public TerrainConfig GetTerrainConfig(Vector2Int coord) { if (IsValidCoordinate(coord)) { TerrainType type = _gridData.cells[coord.x, coord.y].terrain.type; return _gridConfig.GetTerrainConfig(type); } return null; } private bool IsValidCoordinate(Vector2Int coord) { return coord.x >= 0 && coord.x < _gridData.width && coord.y >= 0 && coord.y < _gridData.height; } } }using UnityEngine; namespace gridstudy { public abstract class GridObject : MonoBehaviour { public GridObjectType ObjectType { get; protected set; } public Vector2Int GridPosition { get; set; } public virtual void OnPlaced() { } public virtual void OnRemoved() { } } }using System; using UnityEngine; namespace gridstudy { public class StructureObject : GridObject { public event Action<StructureObject> OnStructureDestroyed; private void Awake() { ObjectType = GridObjectType.Structure; } public override void OnPlaced() { // 建筑放置逻辑 } } }using UnityEngine; namespace gridstudy { public class TerrainObject : GridObject { [SerializeField] private SpriteRenderer _renderer; public void Initialize(TerrainData data, TerrainConfig config) { Data = data; _renderer.sprite = config.tile.sprite; // 从Tile获取Sprite(报错) } } }using gridstudy; using System.Collections; using UnityEngine; namespace gridstudy { // 网格调试视图 public class GridDebugView : MonoBehaviour { [SerializeField] private GridManager _gridManager; [SerializeField] private bool _showGrid = true; void OnDrawGizmos() { if (!_showGrid || _gridManager == null) return; for (int x = 0; x < _gridManager.GridWidth; x++) { for (int y = 0; y < _gridManager.GridHeight; y++) { Gizmos.DrawWireCube( new Vector3(x + 0.5f, y + 0.5f, 0), Vector3.one ); } } } } }using UnityEngine; namespace gridstudy { public class InputHandler : MonoBehaviour { [SerializeField] private Camera _mainCamera; [SerializeField] private GridManager _gridManager; void Update() { if (Input.GetMouseButtonDown(0)) { Vector3 worldPos = _mainCamera.ScreenToWorldPoint(Input.mousePosition); Vector2Int gridPos = new Vector2Int( Mathf.FloorToInt(worldPos.x), Mathf.FloorToInt(worldPos.y) ); // 示例:在点击位置创建草地 TerrainData terrainData = ScriptableObject.CreateInstance<TerrainData>();(报错) terrainData.type = TerrainType.Grass; terrainData.coordinate = gridPos; _gridManager.PlaceObject(报错)( GridObjectType.Terrain, gridPos, terrainData ); } } } }
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值