写代码(尤其是UI部分)时经常需要填写路径来查找需要操作的物体:
Transform btn = transform.Find("AAA\bbb\ccc");
以及通过Resource或Asset加载资源:
GameObject go = Resources.Load<GameObject>("UI/Prefab/CardList/CardListItem");
这样的重复工作很多而且容易写错路径,最好能通过鼠标选择需要查找的场景中物体或者资源,直接生成相关代码,包括路径定义、物体变量定义、物体查找、组件获取、注册事件、查找资源等代码。用VS开发WindowForm程序,其设计工具就可以直接生成相关代码,因为直接操作文件比较担心出错时会覆盖掉某些已有代码,功能写起来也麻烦,要写一整套检查工具。这里搞个简化版,生成代码后直接复制到剪贴板中,手动到需要的地方粘贴一下,虽然比WindowForm要Low一万倍,但简洁方便代码少,实际用起来效果也还行。
using System.IO;
using UnityEngine;
using UnityEditor;
/// <summary>
/// 查找物体或资源的路径,生成代码
/// @Author: DidYouSeeMyBug
/// @CreateTime: 2018/7/2 17:58
/// @Desc: 可生成代码:声明并查找场景中物体,查找组件,添加组件事件,声明并查找项目资源
/// </summary>
public class FindEditor : MonoBehaviour
{
[MenuItem("TOOL/FindCode &F")]
public static void FindCode()
{
string code = string.Empty;
string resPath = "Assets/Resources/";
string[] btnStr = {"Btn", "btn"};
string[] groupStr = {"Group", "group"};
// 选择资源
UnityEngine.Object[] arr = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets);
if (null != arr && 0 != arr.Length)
{
string definePathCode = string.Empty;
string definePrefCode = string.Empty;
string findCode = string.Empty;
for (int i = 0; i < arr.Length; i++)
{
UnityEngine.Object obj = arr[i];
string assetPath = AssetDatabase.GetAssetPath(obj);
if (assetPath.StartsWith(resPath))
{
string ext = Path.GetExtension(assetPath);
int pathLength = assetPath.Length - resPath.Length - ext.Length;
assetPath = assetPath.Substring(resPath.Length, pathLength);
string name = obj.name.Replace(" ", string.Empty);
string pathStr = string.Format("path_{0}", name);
string prefabStr = string.Format("{0}_{1}", ext.Substring(1), name);
string type = obj.GetType().Name;
definePathCode = string.Format("{0}private const string {1} = \"{2}\";\r\n", definePathCode,
pathStr, assetPath);
definePrefCode = string.Format("{0}private {1} {2};\r\n", definePrefCode, type, prefabStr);
findCode = string.Format("{0}{1} = Resources.Load<{2}>({3});\r\n", findCode, prefabStr, type,
pathStr);
}
}
code = string.Format("{0}\r\n{1}\r\n{2}", definePathCode, definePrefCode, findCode);
}
else
{
// 选择场景
string defineCode = string.Empty;
string findCode = string.Empty;
string addCallbackCode = string.Empty;
string callbackCode = string.Empty;
for (int i = 0; i < Selection.transforms.Length; i++)
{
var selecTransform = Selection.transforms[i];
string name = selecTransform.name;
string path = string.Empty;
while (null != selecTransform)
{
path = string.Format("{0}/{1}", selecTransform.name, path);
selecTransform = selecTransform.parent;
}
if (StartWithStrs(ref name, ref groupStr))
{
Debug.Log("Group...");
}
if (StartWithStrs(ref name, ref btnStr))
{
Debug.Log("Find Btn");
defineCode = string.Format("{0}\tButton {1}; \r\n", defineCode, name);
string TransName = string.Format("{0}Transform", name);
string transCode = string.Format("Transform {0} = transform.Find(\"{1}\"); ", TransName, path);
string componentCode = string.Format("\r\nif (null != {0})\r\n\t{1}\r\n\t\t{2} = {0}.GetComponent<Button>();\r\n\t{3}\r\n",
TransName, "{", name, "}");
findCode = string.Format("{0}\t{1}{2}", findCode, transCode, componentCode);
addCallbackCode =
string.Format("{0}\tif (null != {1})\r\n{2}\r\n\t{1}.onClick.AddListener(On{1});\r\n\t{3}\r\n",
addCallbackCode, name, "{", "}");
callbackCode = string.Format("{0}\tpublic void On{1}(){2}{3}\r\n", callbackCode, name, "{", "}");
}
else
{
defineCode = string.Format("{0}\tTransform {1}; \r\n", defineCode, name);
findCode = string.Format("{0}\t{1} = transform.Find(\"{2}\"); \r\n", findCode, name, path);
}
}
code = string.Format("{0}\r\n{1}\r\n{2}\r\n{3}", defineCode, findCode, addCallbackCode, callbackCode);
}
GUIUtility.systemCopyBuffer = code;
Debug.Log("Found!");
}
/// <summary>
/// 是否以数组中的字符串开头
/// </summary>
/// <param name="str">目标字符串</param>
/// <param name="strs">检测字符串</param>
/// <returns></returns>
static bool StartWithStrs(ref string str, ref string[] strs)
{
for (int i = 0; i < strs.Length; i++)
{
if (str.StartsWith(strs[i]))
{
return true;
}
}
return false;
}
}
使用时直接选择需要的物体或者资源,ALT+F,即可生成代码。
可以根据需求修改Editor代码,更改生成代码的格式,样式,增加更多事件的支持等,还可以做一些其他处理,比如上面的代码在根据查找物名称生成变量名的时候会剔除空格,还可以在路径名前面加上@等等。
最开始这一套东西是我在做ulua工作的时候写的,所以也是Lua版本,查找物体生成Lua代码,那个版本的功能更多一些,还支持成组的物体,等下有空我再发一版Lua的。
以下为自动生成的代码,感觉格式和命名都很统一的代码看起来会很顺眼。
// 资源路径
private const string path_BerserkerStrikeLV1 = "CardSprites/BerserkerStrikeLV1";
private const string path_CardChioce = "UI/Prefab/PopWindow/CardChioce";
private const string path_FloraAnimController = "Animator/FloraAnimController";
private const string path_CardDetail = "UI/Prefab/PopWindow/CardDetail";
private const string path_MainAudioMixer = "AudioMixer/MainAudioMixer";
// 资源
private Texture2D png_BerserkerStrikeLV1;
private GameObject prefab_CardChioce;
private AnimatorController controller_FloraAnimController;
private GameObject prefab_CardDetail;
private AudioMixerController mixer_MainAudioMixer;
// 场景物体
Button BtnAwards;
Button BtnCards;
Button BtnMonsters;
Button BtnClose;
Transform TabGroup;
// 加载资源
png_BerserkerStrikeLV1 = Resources.Load<Texture2D>(path_BerserkerStrikeLV1);
prefab_CardChioce = Resources.Load<GameObject>(path_CardChioce);
controller_FloraAnimController = Resources.Load<AnimatorController>(path_FloraAnimController);
prefab_CardDetail = Resources.Load<GameObject>(path_CardDetail);
mixer_MainAudioMixer = Resources.Load<AudioMixerController>(path_MainAudioMixer);
// 查找物体
Transform BtnAwardsTransform = transform.Find("UIAchievementBook/UIAchievementBook/BG/BtnAwards/");
if (null != BtnAwardsTransform)
{
BtnAwards = BtnAwardsTransform.GetComponent<Button>();
}
Transform BtnCardsTransform = transform.Find("UIAchievementBook/UIAchievementBook/BG/BtnCards/");
if (null != BtnCardsTransform)
{
BtnCards = BtnCardsTransform.GetComponent<Button>();
}
Transform BtnMonstersTransform = transform.Find("UIAchievementBook/UIAchievementBook/BG/BtnMonsters/");
if (null != BtnMonstersTransform)
{
BtnMonsters = BtnMonstersTransform.GetComponent<Button>();
}
Transform BtnCloseTransform = transform.Find("UIAchievementBook/UIAchievementBook/CardBook(Clone)/BtnClose/");
if (null != BtnCloseTransform)
{
BtnClose = BtnCloseTransform.GetComponent<Button>();
}
TabGroup = transform.Find("UIAchievementBook/UIAchievementBook/CardBook(Clone)/TabGroup/");
// 添加事件
if (null != BtnAwards)
{
BtnAwards.onClick.AddListener(OnBtnAwards);
}
if (null != BtnCards)
{
BtnCards.onClick.AddListener(OnBtnCards);
}
if (null != BtnMonsters)
{
BtnMonsters.onClick.AddListener(OnBtnMonsters);
}
if (null != BtnClose)
{
BtnClose.onClick.AddListener(OnBtnClose);
}
// 声明函数
public void OnBtnAwards()
{
}
public void OnBtnCards()
{
}
public void OnBtnMonsters()
{
}
public void OnBtnClose()
{
}