您的位置:首页 > 财经 > 产业 > 找网站建设的企业_电子商务解决方案_企业网站seo平台_简述网站推广的方法

找网站建设的企业_电子商务解决方案_企业网站seo平台_简述网站推广的方法

2025/4/10 9:55:51 来源:https://blog.csdn.net/huoyixian/article/details/146889535  浏览:    关键词:找网站建设的企业_电子商务解决方案_企业网站seo平台_简述网站推广的方法
找网站建设的企业_电子商务解决方案_企业网站seo平台_简述网站推广的方法

        今天来介绍一下Framework-Client框架中的UIGenerate部分,UIGenerate是用来创建UI界面的自定义工具,可以快速创建出UI界面所需的Atlas、Prefab、Script、Texture等。

功能介绍

        首先我们通过菜单栏来打开UIGenerate窗口,如下图。

        第一个输入框用于输入面板的名称,Atlas、Prefab、Script、Texture会以面板名称创建对应的目录和资源。

       “是否为子面板”勾选框用于标记创建的面板是否为子面板,子面板创建的资源会放置在主面板的目录下。勾选时则会显示主面板名称的输入框,反之则不显示。

        第二个输入框用于输入主面板名称,只有在创建子面板时才需要输入主面板名称。

        接下来四个勾选框是分别对应生成Atlas、Prefab、Script、Texture不同的资源,只有勾选时才会生成对应的资源。根据需要还可以增加默认创建的UI资源,采用勾选框的目的也是为了选择更加的灵活。

        “全部勾选”“全部取消”两个按钮是为了方便勾选用的。

        点击“生成UI组件”按钮则会创建勾选的对应资源。

        这里我们使用UIGenerate创建了一个TestPanel面板。并生成了Atlas、Prefab、Script、Texture相关的资源和目录,如下图。

        下图是.spriteatlas资源,并且给Atlas默认指定了Texture目录。

        下图是.prefab资源,并且Prefab中默认创建了PanelMask对象。

        下图是TestPanel所需的.cs文件,并且实现了基础结构的编写。

        下图则是创建了放置TestPanel所需的Texture目录,由于会有子界面的存在,所以在Texture目录下又分别为主界面和子界面分别创建了对应的目录。

        最后在创建成功后,会在控制台输出创建成功的日志,显示资源名称和资源所在位置。点击日志则可以直接跳转到对应的资源。

功能实现

        由于UIGenerate涉及的功能比较多,所以分到了多个文件中进行实现。

        UIGenerate窗口实现

       UIGenerateEditor负责UIGenerate窗口的实现,在 OnGUI() 方法里绘制输入框、勾选框、按钮等。这里主要说一下的是Atlas、Prefab、Script、Texture通过创建各自的UIGenerate类对象处理各自的生成逻辑,部分代码如下。

private void OnGUI()
{GUILayout.Label("请输入要创建面板的名称");mPanelName = GUILayout.TextField(mPanelName);mIsSubPanel = GUILayout.Toggle(mIsSubPanel, "是否为子面板");if (mIsSubPanel){GUILayout.Label("输入主面板的名称");mMainPanelName = GUILayout.TextField(mMainPanelName);}else{mMainPanelName = mPanelName;}GUILayout.BeginHorizontal();mIsGenerateAtlas = GUILayout.Toggle(mIsGenerateAtlas, "生成 Atlas");mIsGeneratePrefab = GUILayout.Toggle(mIsGeneratePrefab, "生成 Prefab");GUILayout.EndHorizontal();GUILayout.BeginHorizontal();mIsGenerateScript = GUILayout.Toggle(mIsGenerateScript, "生成 Script");mIsGenerateTexture = GUILayout.Toggle(mIsGenerateTexture, "生成 Texture");GUILayout.EndHorizontal();GUILayout.BeginHorizontal();if (GUILayout.Button("全部勾选")){mIsGenerateAtlas = true;mIsGeneratePrefab = true;mIsGenerateScript = true;mIsGenerateTexture = true;}if (GUILayout.Button("全部取消")){mIsGenerateAtlas = false;mIsGeneratePrefab = false;mIsGenerateScript = false;mIsGenerateTexture = false;}GUILayout.EndHorizontal();if (GUILayout.Button("生成UI组件")){if (CheckName()){if (mIsGeneratePrefab)GeneratePrefab();if (mIsGenerateScript)GenerateScript();if (mIsGenerateTexture)GenerateTexture();if (mIsGenerateAtlas)GenerateAtlas();}}
}private void GeneratePrefab()
{UIGeneratePrefab uiGeneratePrefab = new UIGeneratePrefab(mPanelName, mIsSubPanel, mMainPanelName);uiGeneratePrefab.GeneratePrefab();AssetDatabase.Refresh();
}private void GenerateScript()
{UIGenerateScript uiGenerateScript = new UIGenerateScript(mPanelName, mIsSubPanel, mMainPanelName);uiGenerateScript.GenerateScript();AssetDatabase.Refresh();
}private void GenerateTexture()
{UIGenerateTexture uiGenerateTexture = new UIGenerateTexture(mPanelName, mIsSubPanel, mMainPanelName);uiGenerateTexture.GenerateTexture();AssetDatabase.Refresh();
}private void GenerateAtlas()
{UIGenerateAtlas uiGenerateAtlas = new UIGenerateAtlas(mPanelName, mIsSubPanel, mMainPanelName);uiGenerateAtlas.GenerateAtlas();AssetDatabase.Refresh();
}

        在这里值得一提的是,由于生成完成之后会调用 AssetDatabase.Refresh() 方法,因此Unity会将UIGenerate窗口进行刷新,此时 UIGenerateEditor 类会被重新创建,这也意味着记录Atlas勾选框状态的 mIsGenerateAtlas 变量会被初始化 。这也导致了每次创建UI完成后,勾选框会被重新勾选上。(Prefab、Script、Texture也有同样的问题)

        解决的办法是用 PlayerPrefs 在 OnDisable() 时记录下勾选框的状态,并在 OnEnable() 时重新读取状态。

private void OnEnable()
{mIsGenerateAtlas = PlayerPrefs.GetString("IsGenerateAtlas", "true") == "true";mIsGeneratePrefab = PlayerPrefs.GetString("IsGeneratePrefab", "true") == "true";mIsGenerateScript = PlayerPrefs.GetString("IsGenerateScript", "true") == "true";mIsGenerateTexture = PlayerPrefs.GetString("IsGenerateTexture", "true") == "true";
}private void OnDisable()
{PlayerPrefs.SetString("IsGenerateAtlas", mIsGenerateAtlas ? "true" : "false");PlayerPrefs.SetString("IsGeneratePrefab", mIsGeneratePrefab ? "true" : "false");PlayerPrefs.SetString("IsGenerateScript", mIsGenerateScript ? "true" : "false");PlayerPrefs.SetString("IsGenerateTexture", mIsGenerateTexture ? "true" : "false");
}

        UIGeneratePrefab实现

       这里预先创建了UIPanel模版,通过加载模版,然后重新保存到指定目录,完成Panel面板的创建,部分代码如下。

public void GeneratePrefab()
{string fileName = $"{mPanelName}.prefab";string fileFullPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Prefabs/{fileName}";string fileRelativePath = $"Assets/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Prefabs/{fileName}";if (!File.Exists(fileFullPath)){string directoryPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Prefabs";CreateDirectory(directoryPath);GameObject uiPanel = GetUIPanel();GameObject panelPrefab = PrefabUtility.SaveAsPrefabAsset(uiPanel, fileRelativePath);DelayDebugLog($"<color=yellow>{fileName}</color> create succeed. Path is <color=yellow>{fileFullPath}</color>", panelPrefab);}else{GameObject panelPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(fileRelativePath);Debug.Log($"<color=yellow>{fileName}</color> already exist. Path is <color=yellow>{fileFullPath}</color>", panelPrefab);}
}private GameObject GetUIPanel()
{string uiPanelPath = $"Assets/{FrameworkDefine.UIComponentRootDirectoryPath}/UIPanel.prefab";GameObject uiPanelGameObject = AssetDatabase.LoadAssetAtPath<GameObject>(uiPanelPath);Transform panelMask = uiPanelGameObject.transform.Find("PanelMask");Image image = panelMask.GetComponent<Image>();image.sprite = AssetDatabase.LoadAssetAtPath<Sprite>($"Assets/{FrameworkDefine.UICommonPanelMaskPath}");return uiPanelGameObject;
}

        UIGenerateScript实现

        Script的创建主要是文件操作,将类文件模版替换类名,然后将编辑好的字符串模版保存为 .cs 文件,部分示例代码如下。

        将Panel类的基础代码单独写在 GetPanelContent() 方法内,调用时字符串会自动替换面板名称。在 CreateFile() 文件内,使用 File.Create() 创建 FileStream 对象,并将content内容写入其中,保存为 .cs 文件。Controller和View文件与之类似。

public void GenerateScript()
{string directoryPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Scripts";CreateDirectory(directoryPath);string fileName = $"{mPanelName}.cs";string content = GetPanelContent();CreateFile(fileName, content);
}private void CreateFile(string pFileName, string pContentString)
{string fileFullPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Scripts/{pFileName}";string fileRelativePath = $"Assets/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Scripts/{pFileName}";if (!File.Exists(fileFullPath)){byte[] byteArray = UtilCollection.DataUtil.StringToByteArray(pContentString);FileStream fileStream = File.Create(fileFullPath);fileStream.Write(byteArray, 0, byteArray.Length);fileStream.Close();EditorApplication.delayCall += () =>{TextAsset textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(fileRelativePath);Debug.Log($"<color=yellow>{pFileName}</color> create succeed. Path is <color=yellow>{fileFullPath}</color>", textAsset);};}else{TextAsset textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(fileRelativePath);Debug.Log($"<color=yellow>{pFileName}</color> already exist. Path is <color=yellow>{fileFullPath}</color>", textAsset);}
}private string GetPanelContent()
{return $@"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Framework.UI;namespace Game.UI
{{public class {mPanelName} : PanelBase<{mPanelName}, {mPanelName}Controller, {mPanelName}View>{{protected override void OnInit(){{Debug.LogError(""{mPanelName} Init"");}}}}
}}";
}

        

        UIGenerateTexture实现

        UIGenerateTexture比较简单,只是创建Texture目录,示例代码如下。

        这里需要说明一下的是,为了输出日志可以点击跳转到目录,所以需要通过EditorApplication.delayCall延迟调用的方式,获取目录对象。因为在创建的目录的当前帧是无法获取到目录对象的。

public void GenerateTexture()
{string textureFullPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Textures/{mPanelName}";string textureRelativePath = $"Assets/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Textures/{mPanelName}";if (!Directory.Exists(textureFullPath)){Directory.CreateDirectory(textureFullPath);EditorApplication.delayCall += () =>{Object textureDirectory = AssetDatabase.LoadAssetAtPath<Object>(textureRelativePath);Debug.Log($"<color=yellow>{mPanelName}</color> Texture Directory create succeed. File path is:<color=yellow>{textureFullPath}</color>", textureDirectory);};}else{Object textureDirectory = AssetDatabase.LoadAssetAtPath<Object>(textureRelativePath);Debug.Log($"<color=yellow>{mPanelName}</color> Texture Directory already exist. File path is:<color=yellow>{textureFullPath}</color>", textureDirectory);}
}

        UIGenerateAtlas实现

        UIGenerateAtlas通过 SpriteAtlas 来创建 .spriteatlas 文件,并指定Texture目录,部分示例代码如下。

        这里获取Texture目录没有用延迟调用,是因为UIGenerateEditor中,先调用的UIGenerateTexture,再调用的UIGenerateAtlas。如果顺序相反的话,则需要通过延迟调用来获取Texture目录

public void GenerateAtlas()
{string directoryPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Atlas";CreateDirectory(directoryPath);string fileName = $"Atlas_{mPanelName}.spriteatlas";string atlasFullPath = $"{Application.dataPath}/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Atlas/{fileName}";string atlasFileRelativePath = $"Assets/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Atlas/{fileName}";if (!File.Exists(atlasFullPath)){SpriteAtlas spriteAtlas = new SpriteAtlas();SpriteAtlasPackingSettings packSetting = new SpriteAtlasPackingSettings(){blockOffset = 1,enableRotation = false,enableTightPacking = false,padding = 4,};spriteAtlas.SetPackingSettings(packSetting);string textureRelativePath = $"Assets/{FrameworkDefine.UIRootDirectoryPath}/{mMainPanelName}/Textures/{mPanelName}";Object textureDirectory = AssetDatabase.LoadAssetAtPath<Object>(textureRelativePath);spriteAtlas.Add(new[] { textureDirectory });AssetDatabase.CreateAsset(spriteAtlas, atlasFileRelativePath);Object atlasObject = AssetDatabase.LoadAssetAtPath<Object>(atlasFileRelativePath);Debug.Log($"<color=yellow>{fileName}</color> atlas create succeed. File path is:<color=yellow>{atlasFullPath}</color>", atlasObject);}else{Object atlasObject = AssetDatabase.LoadAssetAtPath<Object>(atlasFileRelativePath);Debug.Log($"<color=yellow>{fileName}</color> atlas already exist. File path is:<color=yellow>{atlasFullPath}</color>", atlasObject);}
}

相关文档链接

Editor编写常用方法汇总:https://blog.csdn.net/huoyixian/article/details/129587964

AssetDatabase官方文档:https://docs.unity3d.com/cn/2022.2/ScriptReference/AssetDatabase.html

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com