我是靠谱客的博主 精明斑马,最近开发中收集的这篇文章主要介绍在unity中序列化储存游戏元素,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

由于unity在运行时只能动态加载Resources目录下的文件,但是在有的情况下一些资源不能直接放在Resources目录下(比如UGUI的需要打包的散图)。如果需要动态加载在Resources目录外的游戏资源时,比较简单的方法是把这些资源放在一个prefab中,然后把相应的prefab放在Resources目录下。

参考了前辈写的一些东西,发现了另一种方法,即序列化这些资源的引用,把序列化之后的实例挂在一个prefab上,再把该预设放在Resources文件夹下,这样也可以实现动态加载游戏资源。并且和第一种方法相比,这样一个预设中可以放的游戏资源的引用数量可以很多,目录结构更清晰。

下面是一个例子,把sprite图的引用序列化在一个prefab当中:
其中Sprite文件夹在Assets目录下,可以有子文件夹,生成的prefab保存在Assets/Resources/Sprite下

public class SpriteList : MonoBehaviour
{
    [HideInInspector]
    [SerializeField]
    List<Sprite> spriteList = new List<Sprite>();

    public Sprite GetSprite(string name)
    {
        Sprite sprite = spriteList.Find((Sprite sp) => { return sp.name == name; });
        return sprite;
    }

    public void AddSprite(Sprite sp)
    {
        spriteList.Add(sp);
    }

}

下面是储存资源的方法:

    static void SaveSprite()
    {
        string targetDir = Application.dataPath + "/Resources/Sprite";

        if (!Directory.Exists(targetDir))
            Directory.CreateDirectory(targetDir);

        DirectoryInfo fromDirInfo = new DirectoryInfo(Application.dataPath + "/Sprite");

        foreach (DirectoryInfo dirInfo in fromDirInfo.GetDirectories())
        {
            MakePrefab(dirInfo, fromDirInfo, targetDir);
        }
    }

    static void MakePrefab(DirectoryInfo dirInfo, DirectoryInfo fromDirInfo, string targetDir)
    {
        string fieldName = dirInfo.Name;
        FileInfo[] allPngFiles = childDir.GetFiles("*.png", SearchOption.AllDirectories);

       GameObject go = new GameObject(fieldName);
       SpriteList sl = go.AddComponent<SpriteList >();

       string prefabParentFieldPath = string.Format("{0}/{1}", targetDir, fieldName);
       if (!Directory.Exists(prefabParentFieldPath))
       {
           Directory.CreateDirectory(prefabParentFieldPath);
       }
        //将sprite序列化在SpriteList 类中
       foreach (FileInfo pngFile in allPngFiles)
       {
           string assetPath = pngFile.FullName.Substring(pngFile.FullName.IndexOf("Assets"));
           Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
           if (sprite == null)
           {
               Debug.LogWarning(string.Format("It's not a sprite which is at "{0}"", assetPath));
               continue;
           }
           sl.AddSprite(sprite);
       }

       // 在对应文件夹内生成预设
       string prefabAllPath = string.Format("{0}/{1}.prefab", prefabParentFieldPath, fieldName);
       string prefabPath = prefabAllPath.Substring(prefabAllPath.IndexOf("Assets"));
       PrefabUtility.CreatePrefab(prefabPath, go);
       AssetDatabase.SaveAssets();
       AssetDatabase.Refresh();

       GameObject.DestroyImmediate(go);
}

以上这一步是在编辑器中运行的,生成prefab之后就可以在游戏运行时动态调用了,调用方法如下:

    public static Sprite GetSpriteByName(string folderName, string spriteName)
    {
        string Path = string.Format("Sprite/{0}", folderName);
        GameObject go = Resources.Load(Path) as GameObject;
        if (go != null)
        {
            SpriteList  sl = go.GetComponent<SpriteList >();
            if (sl != null)
            {
                return sl.GetSprite(spriteName);
            }
        }
        return null;
    }

除sprite外,unity中的其他内建元素也可以通过类似的方式序列化。不过用了UGUI之后发现还是NGUI的功能更多更好用啊。

最后

以上就是精明斑马为你收集整理的在unity中序列化储存游戏元素的全部内容,希望文章能够帮你解决在unity中序列化储存游戏元素所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部