文章作者:松阳
本文出自 阿修罗道,禁止用于商业用途,转载请注明出处。
原文链接:http://blog.youkuaiyun.com/fansongy/article/details/48740091
创建预设
我们在使用编辑器时会有需求使用代码创建预设。在Unity3d的编辑器接口中,有PrefabUtility
类可以使用它来创建预设。
封装实现
函数使用比较简单,查询文档 即可。要注意的是,如果没有父级目录,调用这个接口时会报错。因此我封装了一个函数保证它的父级目录是存在的
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Text;
using System.IO;
public class TestFolder : MonoBehaviour {
[MenuItem("try/makePrefab")]
public static void make() {
string path = "Assets/test/testDir/test.prefab";
GameObject obj = new GameObject();
obj.transform.position = Vector3.forward;
makePrefab(path,obj);
}
public static void makePrefab(string path,GameObject obj) {
makeParentDirExist(path);
Object prefab = PrefabUtility.CreateEmptyPrefab(path);
PrefabUtility.ReplacePrefab(obj,prefab,ReplacePrefabOptions.ConnectToPrefab);
}
public static string getParentPath(string path,char splitFlag='/') {
string[] dirs = path.Split(splitFlag);
StringBuilder str = new StringBuilder();
for(int i = 0;i<dirs.Length-1;++i) {
str.Append(dirs[i]).Append(splitFlag);
}
//cut down the last splitFlag
string result = str.ToString();
if(result.EndsWith(splitFlag.ToString())) {
result = result.Substring(0,result.Length-1);
}
return result;
}
public static string getParentName(string path,char splitFlag='/') {
string[] dirs = path.Split(splitFlag);
if(dirs.Length <2) {
return "";
} else {
return dirs[dirs.Length-2];
}
}
public static void makeParentDirExist(string path) {
string pDir = getParentPath(path);
if(!AssetDatabase.IsValidFolder(pDir)) {
makeParentDirExist(pDir);
AssetDatabase.CreateFolder(getParentPath(pDir),getParentName(path));
AssetDatabase.Refresh();
} else {
return;
}
}
}
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Text;
using System.IO;
public class TestFolder : MonoBehaviour {
[MenuItem("try/makePrefab")]
public static void make() {
string path = "Assets/test/testDir/test.prefab";
GameObject obj = new GameObject();
obj.transform.position = Vector3.forward;
makePrefab(path,obj);
}
public static void makePrefab(string path,GameObject obj) {
makeParentDirExist(path);
Object prefab = PrefabUtility.CreateEmptyPrefab(path);
PrefabUtility.ReplacePrefab(obj,prefab,ReplacePrefabOptions.ConnectToPrefab);
}
public static string getParentPath(string path,char splitFlag='/') {
string[] dirs = path.Split(splitFlag);
StringBuilder str = new StringBuilder();
for(int i = 0;i<dirs.Length-1;++i) {
str.Append(dirs[i]).Append(splitFlag);
}
//cut down the last splitFlag
string result = str.ToString();
if(result.EndsWith(splitFlag.ToString())) {
result = result.Substring(0,result.Length-1);
}
return result;
}
public static string getParentName(string path,char splitFlag='/') {
string[] dirs = path.Split(splitFlag);
if(dirs.Length <2) {
return "";
} else {
return dirs[dirs.Length-2];
}
}
public static void makeParentDirExist(string path) {
string pDir = getParentPath(path);
if(!AssetDatabase.IsValidFolder(pDir)) {
makeParentDirExist(pDir);
AssetDatabase.CreateFolder(getParentPath(pDir),getParentName(path));
AssetDatabase.Refresh();
} else {
return;
}
}
}
调用
准备好预设的路径和GameObject,调用makePrefab
即可在对应目录生成预设。其中路径必须是以Assets
为根,并作为开头。
注意
目前有个坑,父级目录不能以'/'结尾。如果是这样,IsValidFolder
与 CreateFolder
会搜索其子级目录,导致一些不期望的结果