EeveeUI框架4——如何获取选中物体的名字、设置赋值关系、创建对应脚本

为了让我们在运行时能够只使用名字即可加载界面,我们在创建了一个用于储存的.asset文件后,我们就需要考虑如何写入这个文件的值。

这里我们需要一个编辑器类,这个类实现了修改.asset文件内容、创建对应的脚本。
首先我们需要写一个UIEidtor继承Editor,脚本记得放在Editor文件夹下,然后写一个静态函数,用于一键调用我们自己写的功能。
如下代码即实现了编辑器中选中物体后右键处理逻辑

[MenuItem("Assets/Create/注册Panel", false, 1)]
    public static void RegisterPanel()
    {}

然后我们需要获取选中物体,并且取出其名字将其赋值到UIConfig.Instance.m_UIList中,即上述的.asset文件中

/// <summary>
    /// 在Resources/UIConfig中注册此Panel
    /// 如果后期需要删除可以到UIConfig中删除
    /// 后面需要调用UI的时候,从UIConfig中调用
    /// </summary>
    [MenuItem("Assets/Create/注册Panel", false, 1)]
    public static void RegisterPanel()
    {
        //获取全部选中物体GUID
        string[] GUIDs = Selection.assetGUIDs;
        //获取全部选中的物体
        GameObject[] selecteObjects = Selection.gameObjects;
        for (int i = 0; i < GUIDs.Length; i++)
        {
            //Debug.Log(AssetDatabase.GUIDToAssetPath(GUIDs[i]));
            string name = "";
            string path = "";
            //将文件路径拆成文件名和父文件夹
            //如:Asset/UI/test.png 会拆解为test.png和Asset/UI
            Help.GetFileNameAndPath(AssetDatabase.GUIDToAssetPath(GUIDs[i]), out name, out path);
            name = Help.GetFileName(name);
            //Debug.Log("name:" + name);
            //Debug.Log("path:" + path);
            if (!Help.IsContainPanel(UIConfig.Instance.m_UIList, name))
            {
                //创建一个UIPanelConfig
                UIPanelConfig item = new UIPanelConfig();
                item.Name = name;
                //在数组中搜索名字相同的object
                //主要是应用于Selection.gameObjects遍历选中物体时,通过路径获取选中的GameObject
                item.GameObject = Help.SearchObjectName(ref selecteObjects, name);
                //增加Panel 完成注册
                UIConfig.Instance.m_UIList.Add(item);
                //在指定路径下创建UI脚本,此处Scripts/UI即为父路径,可以自行定义
                CreateScript("Scripts/UI", item.Name);
                Debug.Log("Panel注册成功:" + name);
            }
            else
            {
                Debug.LogError("当前Panel已注册,请勿重复注册:" + name);
            }
        }
        //刷新编辑器
        AssetDatabase.Refresh();
    }

实现注册后UIConfig文件中会获取到绑定的Perfab和名字:

image.png

除了要创建还可以移除,也可以自行扩充一键清除等功能
全部代码如下:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using static UIConfig;

public class UIEidtor : Editor
{
    /// <summary>
    /// 在Resources/UIConfig中注册此Panel
    /// 如果后期需要删除可以到UIConfig中删除
    /// 后面需要调用UI的时候,从UIConfig中调用
    /// </summary>
    [MenuItem("Assets/Create/注册Panel", false, 1)]
    public static void RegisterPanel()
    {
        //获取全部选中物体GUID
        string[] GUIDs = Selection.assetGUIDs;
        //获取全部选中的物体
        GameObject[] selecteObjects = Selection.gameObjects;
        for (int i = 0; i < GUIDs.Length; i++)
        {
            //Debug.Log(AssetDatabase.GUIDToAssetPath(GUIDs[i]));
            string name = "";
            string path = "";
            //将文件路径拆成文件名和父文件夹
            //如:Asset/UI/test.png 会拆解为test.png和Asset/UI
            Help.GetFileNameAndPath(AssetDatabase.GUIDToAssetPath(GUIDs[i]), out name, out path);
            name = Help.GetFileName(name);
            //Debug.Log("name:" + name);
            //Debug.Log("path:" + path);
            if (!Help.IsContainPanel(UIConfig.Instance.m_UIList, name))
            {
                //创建一个UIPanelConfig
                UIPanelConfig item = new UIPanelConfig();
                item.Name = name;
                //在数组中搜索名字相同的object
                //主要是应用于Selection.gameObjects遍历选中物体时,通过路径获取选中的GameObject
                item.GameObject = Help.SearchObjectName(ref selecteObjects, name);
                //增加Panel 完成注册
                UIConfig.Instance.m_UIList.Add(item);
                //在指定路径下创建UI脚本,此处Scripts/UI即为父路径,可以自行定义
                CreateScript("Scripts/UI", item.Name);
                Debug.Log("Panel注册成功:" + name);
            }
            else
            {
                Debug.LogError("当前Panel已注册,请勿重复注册:" + name);
            }
        }
        //刷新编辑器
        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 清除选中的Panel注册状态
    /// </summary>
    [MenuItem("Assets/Create/清除Panel注册状态", false, 1)]
    public static void RemovePanel()
    {
        string[] GUIDs = Selection.assetGUIDs;
        GameObject[] selecteObjects = Selection.gameObjects;
        for (int i = 0; i < GUIDs.Length; i++)
        {
            //Debug.Log(AssetDatabase.GUIDToAssetPath(GUIDs[i]));
            string name = "";
            string path = "";
            Help.GetFileNameAndPath(AssetDatabase.GUIDToAssetPath(GUIDs[i]), out name, out path);
            name = Help.GetFileName(name);

            if (Help.IsContainPanel(UIConfig.Instance.m_UIList, name))
            {
                UIPanelConfig item = new UIPanelConfig();
                item.Name = name;
                item.GameObject = Help.SearchObjectName(ref selecteObjects, name);
                UIConfig.Instance.m_UIList.Remove(item);
                Debug.Log("Panel清除成功:" + name);
            }
            else
            {
                Debug.LogError("当前Panel未注册:" + name);
            }
        }

        AssetDatabase.Refresh();
    }

    //[MenuItem("Assets/Create/创建脚本", false, 1)]
    public static void CreateScript(string path, string uIName)
    {
        string folderPath = Application.dataPath + "/" + path;
        TextAsset uIItemTextFile = Resources.Load("UIControl", typeof(TextAsset)) as TextAsset;
        string contents = "";

        if (uIItemTextFile != null)
        {
            contents = uIItemTextFile.text;
            contents = contents.Replace("CHARACTERCLASS_NAME_HERE", uIName.Trim().Replace(" ", "") + "_UIControl");
        }
        Help.FolderPathExist(folderPath);
        AssetDatabase.Refresh();
        string filePath = string.Format(folderPath + "/{0}.cs", new object[] { uIName.Replace(" ", "") });
        if (!Help.FilePathExist(filePath))
        {
            //存在同名文件则不创建
            using (StreamWriter sw = new StreamWriter(filePath))
            {
                sw.Write(contents);
            }

            AssetDatabase.Refresh();
        }
        else
        {
            Debug.Log("当前脚本已存在:" + filePath);
        }
    }
}

这里用到了一些小功能,我全部整理到一个帮助工具类中:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using static UIConfig;

public static class Help
{
    /// <summary>
    /// 拆解url路径为文件名和路径,如Assets/Resources/x.asset
    /// 会通过out返回name:x.asset
    /// path:Assets/Resources
    /// </summary>
    /// <param name="url"></param>
    /// <param name="name"></param>
    /// <param name="path"></param>
    public static void GetFileNameAndPath(string url, out string name, out string path)
    {
        if (!url.Contains("/"))
        {
            name = url;
            path = url;
            return;
        }

        int indexOfLastFolder = url.LastIndexOf("/");
        name = url.Substring(indexOfLastFolder + 1, url.Length - indexOfLastFolder - 1);
        path = url.Substring(0, indexOfLastFolder);
    }

    /// <summary>
    /// 移除文件名后缀
    /// 如666.mp3转换后会获得666
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    public static string GetFileName(string file)
    {
        if (!file.Contains("."))
        {
            return file;
        }

        int indexOfPoint = file.LastIndexOf(".");
        return file.Substring(0, indexOfPoint);
    }

    /// <summary>
    /// 在数组中搜索名字相同的object
    /// 主要是应用于Selection.gameObjects遍历选中物体时,通过路径获取选中的GameObject
    /// </summary>
    /// <param name="objects"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static GameObject SearchObjectName(ref GameObject[] gameObjects, string name)
    {
        foreach (GameObject gameObject in gameObjects)
        {
            if (gameObject.name.Equals(name))
            {
                return gameObject;
            }
        }
        return null;
    }

    /// <summary>
    /// 测试总UI列表中是否包含此名字的Panel
    /// </summary>
    /// <param name="uIItems"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static bool IsContainPanel(List<UIPanelConfig> uIItems, string name)
    {
        foreach (var item in uIItems)
        {
            if (item.Name.Equals(name))
                return true;
        }

        return false;
    }

    /// <summary>
    /// 测试总UI列表中是否包含此名字的Panel
    /// </summary>
    /// <param name="uIItems"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static bool IsContainPanel(List<UIPanelConfig> uIItems, string name, out UIPanelConfig uIItem)
    {
        uIItem = default;
        foreach (var item in uIItems)
        {
            if (item.Name.Equals(name))
            {
                uIItem = item;
                return true;
            }
        }

        return false;
    }


    /// <summary>
    /// 判断文件夹路径是否存在,如果不存在则创建
    /// </summary>
    /// <param name="path"></param>
    public static void FolderPathExist(string path)
    {
        DirectoryInfo directoryInfo = new DirectoryInfo(path);
        if (!directoryInfo.Exists)
        {
            Directory.CreateDirectory(path);
        }
    }

    /// <summary>
    /// 判断文件路径是否存在
    /// </summary>
    /// <param name="path"></param>
    public static bool FilePathExist(string path)
    {
        FileInfo fileInfo = new FileInfo(path);

        return fileInfo.Exists;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值