You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity技术咨询:如何从JSON文件中加载Sprite?

从JSON加载Sprite的解决方案

首先得明确:JSON是纯文本格式,没办法直接存储Sprite(图片二进制数据),所以我们的思路是在JSON里存储Sprite的引用信息(比如路径、资源标识),然后在代码中根据这些信息去加载对应的Sprite资源。下面我结合常见游戏场景(以Unity为例)给你详细说明:

第一步:调整JSON结构,存储Sprite引用

先修改你的JSON,加入Sprite的路径/标识字段,比如:

{
  "characterData": {
    "name": "Warrior",
    "health": 100,
    "characterSpritePath": "Sprites/Characters/Warrior_Idle",
    "uiIconPath": "UI/Icons/Warrior_Icon"
  }
}

这里的characterSpritePathuiIconPath就是Sprite在资源目录中的相对路径(根据你用的资源管理方式调整)。

第二步:定义对应的数据类(以C#为例)

和你加载文本数据一样,先定义能和JSON映射的序列化类:

[System.Serializable]
public class CharacterData
{
    public string name;
    public int health;
    public string characterSpritePath;
    public string uiIconPath;
}

[System.Serializable]
public class GameData
{
    public CharacterData characterData;
}

第三步:加载JSON并读取Sprite

根据你使用的资源管理方式,有几种常见的加载方案:

方案1:使用Unity Resources系统加载

如果你的Sprite放在Resources文件夹下,代码可以这样写:

using UnityEngine;
using UnityEngine.UI;

public class JsonSpriteLoader : MonoBehaviour
{
    // 绑定UI和渲染组件
    public Text characterNameText;
    public Image uiIconImage;
    public SpriteRenderer characterSpriteRenderer;

    void Start()
    {
        // 读取JSON文件(假设JSON在Resources/GameData.json)
        TextAsset jsonText = Resources.Load<TextAsset>("GameData");
        if (jsonText == null)
        {
            Debug.LogError("找不到GameData JSON文件!");
            return;
        }

        // 解析JSON到数据类
        GameData gameData = JsonUtility.FromJson<GameData>(jsonText.text);

        // 加载文本数据(这部分你已经会了)
        characterNameText.text = gameData.characterData.name;

        // 加载角色Sprite
        Sprite characterSprite = Resources.Load<Sprite>(gameData.characterData.characterSpritePath);
        if (characterSprite != null)
        {
            characterSpriteRenderer.sprite = characterSprite;
        }
        else
        {
            Debug.LogWarning($"找不到指定路径的Sprite:{gameData.characterData.characterSpritePath}");
        }

        // 加载UI图标Sprite
        Sprite uiIcon = Resources.Load<Sprite>(gameData.characterData.uiIconPath);
        if (uiIcon != null)
        {
            uiIconImage.sprite = uiIcon;
        }
        else
        {
            Debug.LogWarning($"找不到指定路径的UI图标:{gameData.characterData.uiIconPath}");
        }
    }
}

⚠️ 注意:Resources加载要求资源必须放在Resources文件夹下,路径是相对于该文件夹的相对路径,不能带文件后缀。

方案2:使用Unity Addressable Assets系统加载

如果你的项目用了Addressable(更适合大型项目),加载代码会改成异步加载:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class JsonSpriteLoader : MonoBehaviour
{
    public Text characterNameText;
    public Image uiIconImage;
    public SpriteRenderer characterSpriteRenderer;

    void Start()
    {
        TextAsset jsonText = Resources.Load<TextAsset>("GameData");
        if (jsonText == null)
        {
            Debug.LogError("找不到GameData JSON文件!");
            return;
        }

        GameData gameData = JsonUtility.FromJson<GameData>(jsonText.text);
        characterNameText.text = gameData.characterData.name;

        // 异步加载角色Sprite
        Addressables.LoadAssetAsync<Sprite>(gameData.characterData.characterSpritePath).Completed += OnCharacterSpriteLoaded;
        // 异步加载UI图标
        Addressables.LoadAssetAsync<Sprite>(gameData.characterData.uiIconPath).Completed += OnUiIconLoaded;
    }

    private void OnCharacterSpriteLoaded(AsyncOperationHandle<Sprite> handle)
    {
        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            characterSpriteRenderer.sprite = handle.Result;
        }
        else
        {
            Debug.LogWarning($"加载角色Sprite失败:{handle.DebugName}");
        }
        Addressables.Release(handle); // 记得释放资源
    }

    private void OnUiIconLoaded(AsyncOperationHandle<Sprite> handle)
    {
        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            uiIconImage.sprite = handle.Result;
        }
        else
        {
            Debug.LogWarning($"加载UI图标失败:{handle.DebugName}");
        }
        Addressables.Release(handle);
    }
}

方案3:加载本地文件系统的Sprite

如果你的Sprite是保存在本地磁盘(比如PersistentDataPath),可以通过读取二进制文件转换为Sprite:

using UnityEngine;
using UnityEngine.UI;
using System.IO;

public class JsonSpriteLoader : MonoBehaviour
{
    public Text characterNameText;
    public Image uiIconImage;
    public SpriteRenderer characterSpriteRenderer;

    void Start()
    {
        TextAsset jsonText = Resources.Load<TextAsset>("GameData");
        if (jsonText == null)
        {
            Debug.LogError("找不到GameData JSON文件!");
            return;
        }

        GameData gameData = JsonUtility.FromJson<GameData>(jsonText.text);
        characterNameText.text = gameData.characterData.name;

        // 拼接本地文件全路径
        string characterSpriteFullPath = Application.persistentDataPath + "/" + gameData.characterData.characterSpritePath;
        if (File.Exists(characterSpriteFullPath))
        {
            // 读取图片二进制数据
            byte[] imageBytes = File.ReadAllBytes(characterSpriteFullPath);
            // 创建Texture2D并加载图片
            Texture2D texture = new Texture2D(2, 2);
            texture.LoadImage(imageBytes);
            // 转换为Sprite
            Sprite characterSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
            characterSpriteRenderer.sprite = characterSprite;
        }
        else
        {
            Debug.LogWarning($"本地图片不存在:{characterSpriteFullPath}");
        }
    }
}

关键注意事项

  • 永远不要在JSON里直接存储图片二进制数据:这会让JSON文件体积暴增,且加载效率极低,存储路径/标识是最优方案。
  • 确保Sprite的路径和JSON中存储的完全匹配,注意大小写(部分平台区分大小写)。
  • 异步加载时要处理加载失败的情况,避免空引用报错。

内容的提问来源于stack exchange,提问作者make move

火山引擎 最新活动