概述
由于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中序列化储存游戏元素所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复