赞
踩
在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。
需要完整版PDF学习资源私我
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
1当前的需求: 技术人员在每次资源更新的时候,需要重复操作软件来进行版本号的制作,安装包的制作,希望减少这种工作量。
2 用到的工具 pycharm + Unity
1我需要在Unity中 将更新的资源按照选定的项目 复制到 指定的文件夹中
2使用exe制作版本号及资源列表。
3使用SUFDesign 软件进行安装包制作。
复制这部分直接跳过,个人需要注意的点
GUIStyle st = GUI.skin.FindStyle ("flow node 2");
st.fontSize = 15;
st.alignment = TextAnchor.UpperCenter;
GUILayout.Space (10);
if (GUILayout.Button ("制作版本号\n(慎点!)",st, GUILayout.Height (50), GUILayout.Width (150)))
{
CallBuildTool ();
}
使用GUI内置的风格
Unity并不能执行python脚本,C#是编译型语言,需要先编译,python是解释型语言,直接就可以运行 但是需要解释器,我使用的就是python3.7,安装pycharm 还有Anaconda
Unity开启一个线程 调用解释器 然后解释器执行py 脚本,py脚本进行自动化操作,这就是整个流程。
#region 调用打包工具 private static string FilePath = @"F:\workspace\PythonTest\PythonCallHardware\venv\Scripts\python.exe"; // [MenuItem("PublishTools/制作版本号",false,2)] private static void CallBuildTool () { string file = @"F:/workspace/PythonTest/PythonCallHardware/Scripts/CallBuildTools.py"; ProcessStartInfo start = new ProcessStartInfo (); start.FileName = FilePath; start.Arguments = file + " " + currentItemType; start.UseShellExecute = false; //参数用空格分隔 //start.Arguments = path + " " + type + " " + mode; start.RedirectStandardOutput = true; start.RedirectStandardInput = true; start.RedirectStandardError = true; start.CreateNoWindow = false; Process process = Process.Start (start); } #endregion
和我们使用CMD一样 使用某一软件执行文件,
start.FileName = FilePath;参数是解释器的位置
start.Arguments = file + " " + currentItemType;第一个参数是文件位置 ,第二个是我选择的项目类型
注意参数之间是用空格隔开
调用方法同理参考上方
我在使用的时候 我一般使用conda 来下载模块包 但是这个模块使用conda 是不能下载的 我是用的pip下载的 当然最后我使用的不是conda安装时的编译器。
1我们如何在脚本中获取 传递过来的参数
我们使用 sys 模块 sys.argv[1]是第一个参数 一次类推
self.CurrentType = int(sys.argv[1]))
self.CurrentModel = int(sys.argv[2])
2 如果判断类型呢
我们使用enum枚举
class ProjectType(enum.Enum): ''' 项目类别 ''' CeLiang = 1 GongYi = 2 GCLX = 3 AnZhuangShiTu = 4 ZhuangPeiShi = 5 PingFa = 6 JingZhuangXiu = 7 GouZhao = 8 AnQuanWenMingGongDi = 9 JiLiangJiJia = 10 DaoLuGongCheng = 11 QiangLiangGongCheng = 12 ShouGongSuanLiang = 13 GangJieGou = 14, # 建筑电气施工 JianZhuDianQiShiGong = 15, DaqQiaoShiTu = 16, SuiDaoGongCheng = 17, # 不确定 GongChengShiTu = 18,
我们在使用的时候 可以 吧数字对应成 项目名 使用
self.modelType = ModelType(self.CurrentModel)
3 最重要的来了 pywinauto模块
我们需要判断当前软件窗口的类型 uia 还是win32
链接:https://pan.baidu.com/s/1VQv_SKGGCHwVZIqxa5iyMQ
提取码:x5nt
确定之后 使用模块调用软件创建联系
app = Application(backend='uia').start(r"F:\work\SetupFactory\SUFDesign.exe", timeout=10)
# 把进程和当前获得句柄联系起来
app = Application().connect(path=r"F:\work\SetupFactory\SUFDesign.exe", timeout=10)
都可以通过app.window()获取子空间和窗体
# 获取 当前的窗 通过标题
dlg_new = app.window(title="Start a New Project")
dlg_new.wait("ready", timeout=5) # 等待窗体响应 有很多状态 可以看方法内部的介绍
dlg_new.print_control_identifiers()# 打印出 窗体的结构 你可以查找对应的控件
# 标识一下
dlg_new.draw_outline() 在窗体的周边划线
找到按钮进行点击
btn_cancle = dlg_new[r'Cancle']
btn_cancle.click()
使用快捷键
dlg_Open = app.window(title=r"Untitled - Setup Factory")
dlg_Open.wait("exists enabled visible ready", timeout=5)
dlg_Open.draw_outline()
# dlg\_Open.print\_control\_identifiers()
# 使用快捷键 打开suf
dlg_Open.type_keys("^O")
对应快捷键的写法
我遇到的问题 就是选择combobox里面的选项
# 选择组合框中的
dlg_Mul.ComboBoxWrapper.select("Always overwrite existing file")
4 在使用pywinauto 的时候 报错 坑了很久 是程序是32的 而我使用的是64位python.exe
# 解决不能运行自己做的exe的问题
import os
os.environ.update({"\_\_COMPAT\_LAYER":"RUnAsInvoker"})
# 解决报错 是32位程序需要 使用32位python.exe
import warnings
warnings.simplefilter('ignore', category=UserWarning)
在使用过程中 需要不断的试错 适当的时候让程序sleep 因为没有程序没有完全打开 脚本就不能进行下去
我们可以获取当前焦点
dlg_Pro.get_active()
dlg_Pro.get_focus()
SUFDesign 就是这样
下附全部脚本
Unity C#
using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; using System.Text; using System.Diagnostics; /// <summary> /// 将I盘下的各个工程的资源和播放器移动到H盘下 方便制作安装包 /// </summary> enum itemType { 测量 = 1, 工艺 = 2, 工程力学 = 3, 安装识图 = 4, 装配式 = 5, 平法 = 6, 精装修 = 7, 构造 = 8, 安全文明工地 = 9, 计量计价 = 10, 道路工程 = 11, 桥梁工程 = 12, 手工算量 = 13, 钢结构 = 14, 建筑电气施工 = 15, 道桥识图 = 16, 隧道工程 = 17, 工程识图 = 18, 造价识图 = 20 } public class PublishEditorWindow : EditorWindow { #region 复制文件 private static itemType currentItemType = itemType.安装识图; private static float Window_height = 400; private static float Window_width = 1000; private static float LeftArea_width; private static float RightArea_height; private GUIStyle fontStyle; //private static string Source\_DirvePath = @"H:/PatchTool/RGZSoft/"; private static string Source_DirvePath = @"D:/工作安装包/PatchTool/RGZSoft"; //private static string Target\_DirvePath = @"I:/rgzsoft/RGZSoft/"; private static string Target_DirvePath = @"D:/工作安装包/网页版本打包项"; /// <summary> /// 目的资源路径 /// </summary> private static string Source_player_module = "module"; private static string Source_weike = @"WeiKe/WKPlayerResources/WKAssets"; /// <summary> /// 当前资源路径 /// </summary> private static string Target_player_module = "module"; private static string Target_weike = @"WeiKe/WKPlayerResources/WKAssets"; private static string sourceAssetsPath; private static string sourcePlayerPath; private static List<string> sourceWkPath; private static string TargetAssetsPath; private static string TargetPlayerPath; private static string TargetWkPath; private static bool IsAssetCopy = true; private static bool IsPlayerCopy = true; private static bool IsWkCopy = true; private static bool IsWkPlayer = true; private static string str; private string towkBg; private string fromwkBg; private string fromwkXml; private string towkXml; private string fromWkPlayerPath; private string toWkPlayerPath; [MenuItem ("PublishTools/移动各项目资源", false, 1)] private static void PublishWebglTool () { PublishEditorWindow publish = GetWindowWithRect<PublishEditorWindow> (new Rect (0, 0, Window_width, Window_height), false, "移动项目资源"); publish.ShowPopup (); LeftArea_width = Window_width / 3 \* 2; RightArea_height = Window_width - LeftArea_width; sourceWkPath = new List<string> (); } private void DrawLabel ( string content, GUIStyle style = null ) { EditorGUILayout.BeginHorizontal (); GUILayout.Label ("已选择的源播放器路径:", style); GUILayout.TextField (sourcePlayerPath); EditorGUILayout.EndHorizontal (); } private void OnGUI () { fontStyle = GUI.skin.FindStyle ("flow node 0"); //fontStyle.normal.textColor = Color.white; fontStyle.fontSize = 12; GUIStyle style = new GUIStyle (); style.fixedWidth = 130; style.normal.textColor = Color.red; GUILayout.BeginArea (new Rect (LeftArea_width, 0, RightArea_height, Window_height), "", "box"); EditorGUILayout.BeginVertical (); EditorGUILayout.LabelField ("请选择要移动的项目:"); EditorGUILayout.LabelField ("项目名称"); currentItemType = (itemType)EditorGUILayout.EnumPopup (currentItemType, GUILayout.Height (25)); if (GUILayout.Button ("确定")) { CompactStringPath (); } EditorGUILayout.LabelField ("如果你选择复制选择的项目,请按下方按钮:"); if (GUILayout.Button ("复制已选的项目")) { CopySelectItem (); } EditorGUILayout.LabelField ("如果你选择复制全部的项目,请按下方按钮:"); if (GUILayout.Button ("复制全部项目")) { CopyMultipleDirectory (); } EditorGUILayout.EndVertical (); GUILayout.Space (50); if (GUILayout.Button ("清理缓存")) { EditorUtility.UnloadUnusedAssets (); } GUILayout.EndArea (); //绘制左边 GUILayout.BeginArea (new Rect (0, 0, LeftArea_width, Window_height), "", "box"); EditorGUILayout.BeginVertical (); GUILayout.Space (5); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath); GUILayout.Label ("已选择的源文件路径:", style); GUILayout.TextField (sourceAssetsPath); EditorGUILayout.EndHorizontal (); GUILayout.Space (2); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath); GUILayout.Label ("已选择的源播放器路径:", style); GUILayout.TextField (sourcePlayerPath); EditorGUILayout.EndHorizontal (); GUILayout.Space (2); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath); GUILayout.Label ("已选择的源微课资源路径:", style); GUILayout.TextField (GetStrByList (sourceWkPath)); EditorGUILayout.EndHorizontal (); GUILayout.Space (2); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath); GUILayout.Label ("已选择的微课播放器路径:", style); GUILayout.TextField (fromWkPlayerPath); EditorGUILayout.EndHorizontal (); GUILayout.Space (5); EditorGUILayout.BeginHorizontal (); GUILayout.Label ("目标互动资源路径:", style); GUILayout.TextField (TargetAssetsPath); EditorGUILayout.EndHorizontal (); GUILayout.Space (2); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("要复制的目标路径:",TargetPath); GUILayout.Label ("目标播放器路径:", style); GUILayout.TextField (TargetPlayerPath); EditorGUILayout.EndHorizontal (); GUILayout.Space (2); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("要复制的目标路径:",TargetPath); GUILayout.Label ("目标微课资源路径:", style); GUILayout.TextField (TargetWkPath); EditorGUILayout.EndHorizontal (); EditorGUILayout.BeginHorizontal (); //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath); GUILayout.Label ("目标微课播放器路径:", style); GUILayout.TextField (toWkPlayerPath); EditorGUILayout.EndHorizontal (); GUILayout.Space (5); IsAssetCopy = EditorGUILayout.Toggle ("互动资源", IsAssetCopy); IsPlayerCopy = EditorGUILayout.Toggle ("播放器资源", IsPlayerCopy); IsWkCopy = EditorGUILayout.Toggle ("微课资源(全部)", IsWkCopy); IsWkPlayer = EditorGUILayout.Toggle ("微课播放器", IsWkPlayer); EditorGUILayout.EndVertical (); GUILayout.Space (20); GUIStyle button_style; button_style =/\* GUI.skin.FindStyle ("flow node 1");\*/new GUIStyle (); button_style.fontSize = 17; button_style.fontStyle = FontStyle.Bold; //button\_style.margin = new RectOffset (0,0,0,0); button_style.alignment = TextAnchor.MiddleLeft; button_style.normal.textColor = Color.red; EditorGUILayout.BeginHorizontal (); GUILayout.Label ("当前已选项目是: ", GUILayout.Width (100)); button_style.normal.textColor = Color.green; GUILayout.Label (currentItemType.ToString (), button_style, GUILayout.Width (200)); EditorGUILayout.EndHorizontal (); GUIStyle st = GUI.skin.FindStyle ("flow node 2"); st.fontSize = 15; st.alignment = TextAnchor.UpperCenter; GUILayout.Space (10); if (GUILayout.Button ("制作版本号\n(慎点!)",st, GUILayout.Height (50), GUILayout.Width (150))) { CallBuildTool (); } GUILayout.EndArea (); //绘制右边 } private void CompactStringPath () { Resources.UnloadUnusedAssets (); //源资源 sourceAssetsPath = PathTool.CombinePath (Source_DirvePath, GetDirNameByType (currentItemType)); sourcePlayerPath = PathTool.CombinePath (Source_DirvePath, Target_player_module, GetDirNameByType (currentItemType)); fromWkPlayerPath = PathTool.CombinePath (Source_DirvePath, Source_player_module, "WeiKe"); toWkPlayerPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType.ToString () + "微课", Target_player_module, "WeiKe"); str = GetWkNameByType (currentItemType); if (str.Contains ("+")) { string[] sourceWkPath_Arr = str.Split ('+'); sourceWkPath.Clear (); foreach (var i in sourceWkPath_Arr) { if (!sourceWkPath.Contains (i)) sourceWkPath.Add (PathTool.CombinePath (Source_DirvePath, Target_weike, i)); } } else { sourceWkPath.Clear (); sourceWkPath.Add (PathTool.CombinePath (Source_DirvePath, Target_weike, GetWkNameByType (currentItemType))); } TargetAssetsPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType.ToString () + "互动", GetDirNameByType (currentItemType)); TargetPlayerPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType.ToString () + "互动", Target_player_module, GetDirNameByType (currentItemType)); TargetWkPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType + "微课", Target_weike, GetWkNameByType (currentItemType)); towkBg = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType + "微课", Target_weike, "WKLoadBG"); fromwkBg = PathTool.CombinePath (Source_DirvePath, Source_weike, "WKLoadBG"); towkXml = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType + "微课", Target_weike, "WK\_ID对照表.xml"); fromwkXml = PathTool.CombinePath (Source_DirvePath, Source_weike, "WK\_ID对照表.xml"); UnityEngine.Debug.Log ("源文件互动路径sourceAssetsPath" + sourceAssetsPath); UnityEngine.Debug.Log ("源文件互动播放器路径sourcePlayerPath" + sourcePlayerPath); UnityEngine.Debug.Log ("源文件微课资源路径sourceWkPath" + string.Join (" ", sourceWkPath.ToArray ())); UnityEngine.Debug.Log ("源文件WK\_ID对照表 " + fromwkXml); UnityEngine.Debug.Log ("源文件微课背景图路径 " + fromwkBg); UnityEngine.Debug.Log ("源文件微课播放路径 " + fromWkPlayerPath); UnityEngine.Debug.Log ("目标互动路径TargetAssetsPath" + TargetAssetsPath); UnityEngine.Debug.Log ("目标互动播放器路径TargetPlayerPath" + TargetPlayerPath); UnityEngine.Debug.Log ("目标微课资源路径TargetWkPath" + TargetWkPath); UnityEngine.Debug.Log ("目标微课背景图路径 towkBg" + towkBg); UnityEngine.Debug.Log ("目标WK\_ID对照表 " + towkXml); UnityEngine.Debug.Log ("目标文件微课播放器 " + toWkPlayerPath); } private string GetStrByList ( List<string> str_list ) { StringBuilder sb = new StringBuilder (); foreach (string s in str_list) { sb.Append (s); if (s != str_list[str_list.Count - 1]) sb.Append ("\n"); } return sb.ToString (); } private void CopySelectItem () { //互动资源 if (IsAssetCopy) CopySelectDirectory (sourceAssetsPath, TargetAssetsPath); //互动播放器 if (IsPlayerCopy) CopySelectDirectory (sourcePlayerPath, TargetPlayerPath); //微课资源 if (IsWkCopy) { foreach (var i in sourceWkPath) { CopySelectDirectory (i, TargetWkPath); } //背景图 CopySelectDirectory (fromwkBg, towkBg); //wk对照表 File.Copy (fromwkXml, towkXml, true); } //微课播放器 if (IsWkPlayer) CopySelectDirectory (fromWkPlayerPath, toWkPlayerPath); UnityEngine.Debug.Log (string.Format ("<color=red>复制完成{0}</color>", currentItemType)); } /// <summary> /// 复制选择的文件夹 /// </summary> /// <param name="sourcePath">源文件路径</param> /// <param name="targetPath">目标文件路径</param> private static void CopySelectDirectory ( string sourcePath, string targetPath ) { if (!Directory.Exists (targetPath)) { Directory.CreateDirectory (targetPath); } DirectoryInfo dirInfo = new DirectoryInfo (sourcePath); List<FileInfo> fileList = new List<FileInfo> (dirInfo.GetFiles ()); fileList.ForEach (c => { EditorUtility.DisplayProgressBar ("正在复制", c.FullName, (int)(fileList.IndexOf (c) + 1 / fileList.Count)); string destPath = PathTool.CombinePath (targetPath, c.Name); File.Copy (c.FullName, destPath, true); UnityEngine.Debug.Log (c.FullName + "复制到to" + destPath + "成功"); }); List<DirectoryInfo> folders = new List<DirectoryInfo> (dirInfo.GetDirectories ()); folders.ForEach (c => { string targetpath = PathTool.CombinePath (targetPath, c.Name); UnityEngine.Debug.Log (string.Format ("文件夹中 源文件{0},目标文件{1}", c.FullName, targetpath)); CopySelectDirectory (c.FullName, targetpath); }); EditorUtility.ClearProgressBar (); } /// <summary> /// 复制全部的文件夹 /// </summary> /// <param name="sourcePath"></param> /// <param name="targetPaht"></param> private static void CopyMultipleDirectory () { } /// <summary> /// 获得互动名称 /// </summary> /// <param name="type"></param> /// <returns></returns> private static string GetDirNameByType ( itemType type ) { string dirname = string.Empty; switch (type) { case itemType.安装识图: dirname = "AnZhuangShiTu"; break; case itemType.测量: dirname = "CeLiang"; break; case itemType.钢结构: dirname = "GangJieGou"; break; case itemType.工程识图: dirname = "GongChengShiTu"; break; case itemType.工艺: dirname = "GongYi"; break; case itemType.构造: dirname = "Struct"; break; case itemType.计量计价: dirname = "JiLiangJiJia"; break; case itemType.精装修: dirname = "jingzhuangxiu"; break; case itemType.工程力学: dirname = "GCLX"; break; case itemType.平法: dirname = "PingFa"; break; case itemType.造价识图: dirname = "CostKnowledge"; break; case itemType.装配式: dirname = "ZhuangPeiShi"; break; case itemType.建筑电气施工: dirname = "InstallProject"; break; case itemType.桥梁工程: dirname = "BridgeProject"; break; case itemType.道桥识图: dirname = "BridgeFigure"; break; case itemType.隧道工程: dirname = "SuiDaoProject"; break; default: break; } return dirname; } /// <summary> /// 获得wk名称 /// </summary> /// <param name="type"></param> /// <returns></returns> private static string GetWkNameByType ( itemType type ) { string wkName = string.Empty; switch (type) { case itemType.安装识图: wkName = "AZST"; break; case itemType.测量: wkName = "CL"; break; case itemType.钢结构: wkName = "GJG"; break; case itemType.工程识图: wkName = "GZst"; break; case itemType.工艺: wkName = "GRgy"; break; case itemType.构造: wkName = "GRgz"; break; case itemType.计量计价: wkName = "GRjljj"; break; case itemType.精装修: wkName = "ZSzx"; break; case itemType.工程力学: wkName = "GCLX"; break; case itemType.平法: wkName = ""; break; case itemType.造价识图: wkName = "GZst"; break; case itemType.装配式: wkName = "ZPS"; break; case itemType.建筑电气施工: wkName = "GRaz"; break; case itemType.桥梁工程: wkName = "QLGC"; break; case itemType.道桥识图: wkName = ""; break; case itemType.隧道工程: wkName = "SGGY+GZRZ+WYFJ"; break; default: break; } return wkName; } #endregion #region 调用打包工具 private static string FilePath = @"F:\workspace\PythonTest\PythonCallHardware\venv\Scripts\python.exe"; // [MenuItem("PublishTools/制作版本号",false,2)] private static void CallBuildTool () { string file = @"F:/workspace/PythonTest/PythonCallHardware/Scripts/CallBuildTools.py"; ProcessStartInfo start = new ProcessStartInfo (); start.FileName = FilePath; start.Arguments = file + " " + currentItemType; start.UseShellExecute = false; //参数用空格分隔 //start.Arguments = path + " " + type + " " + mode; start.RedirectStandardOutput = true; start.RedirectStandardInput = true; start.RedirectStandardError = true; start.CreateNoWindow = false; Process process = Process.Start (start); } #endregion } public class PythonCallBuild : EditorWindow { #region 调用python自动化打包 static PythonCallBuild window; private static itemType CurrentType = itemType.测量; private static bool ISWEIKE = false; private static bool ISHUDONG = false; [MenuItem ("PublishTools/调用Python自动化打包", false, 3)] private static void CallBuild () { window = GetWindow<PythonCallBuild> (); window.autoRepaintOnSceneChange = false; window.maxSize = new Vector2 (430, 305); window.Show (); } //互动2 微课是1 static string CurrentModeType = "1"; private void OnGUI () { EditorGUILayout.BeginHorizontal (); CurrentType = (itemType)EditorGUILayout.EnumPopup ("选择项目:", CurrentType, GUILayout.Width (300)); EditorGUILayout.EndHorizontal (); GUILayout.Label ("------------------------------------------------------------------------------------------------------------------------------"); EditorGUILayout.BeginHorizontal (); using (var posGroup = new EditorGUILayout.ToggleGroupScope ("类别(只能选一个)", true)) { ISWEIKE = EditorGUILayout.ToggleLeft ("微课", ISWEIKE); ISHUDONG = EditorGUILayout.ToggleLeft ("互动", ISHUDONG); } EditorGUILayout.EndHorizontal (); GUILayout.Space (10); GUILayout.BeginHorizontal (); GUILayout.Label ("------------------------------------------------------------------------------------------------------------------------------"); GUILayout.Label ("当前选择项目:"); **网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。** **[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)** **一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。