FishPlayer

一个喜欢摸鱼的废物

0%

上一期我们做完了基本的面板绘制,现在我们可以往里面添加简单的内容了。

定义显示单位

既然我们要显示Log,那就定义一些数据结构用于存储这些Log。因为这些东西在我们的console中只需要显示就行了,我们只需要定义只读的数据就可以,或许还能提高性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

public class LogItem
{
public bool IsSelected { get; set; }
public readonly string LogInfo = string.Empty; // Log简要信息
public readonly string LogMessage = string.Empty; // Log 调用栈!
public readonly LogType GetLogType = LogType.Log;

public LogItem(bool isSelected, string info, string message, LogType type)
{
IsSelected = isSelected;
// 记得加上时间!!!
LogInfo = string.Format("[{0}] {1}", System.DateTime.Now.ToLongTimeString(), info);
LogMessage = message;
GetLogType = type;
}
}

public class TempConsoleWindow : EditorWindow
{
private void LogMessageReceived(string condition, string stackTrace, LogType type)
{
LogItem log = new LogItem(false, condition, stackTrace, type);
m_logItems.Add(log);
switch (type)
{
case LogType.Error:
m_errorLogCount++;
break;
case LogType.Assert:
m_errorLogCount++;
break;
case LogType.Warning:
m_warningLogCount++;
break;
case LogType.Log:
m_normalLogCount++;
break;
case LogType.Exception:
m_errorLogCount++;
break;
default:
m_errorLogCount++;
break;
}

// 主动刷新,因为当此窗口没有焦点时似乎无法走 OnGUI() 刷新。
Repaint();
//GUI.changed = true;
}

private void OnEnable()
{
// ....
// 监听此事件,当Debug.Log("")被调用的时候就会响应
Application.logMessageReceived += LogMessageReceived;
}

private void OnDestroy()
{
// ....
Application.logMessageReceived -= LogMessageReceived;
}

}

在上部面板显示Log

像原本Unity Console一样,每一条Log以一个方条item的形式显示在上半部分面板。
我们先把这个item画出来。
m_selectedLogItem 是我们选中的 LogItem。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
private bool DrawLogBox(in string content, LogType logType, bool isOdd, bool isSelected)
{
if (isSelected)
{
m_boxItemStyle.normal.background = m_boxBgSelected;
}
else
{
if (isOdd)
{
m_boxItemStyle.normal.background = m_boxBgOdd;
}
else
{
m_boxItemStyle.normal.background = m_boxBgEven;
}
}

switch (logType)
{
case LogType.Error:
m_boxIcon = m_errorIcon;
break;
case LogType.Assert:
m_boxIcon = m_errorIcon;
break;
case LogType.Warning:
m_boxIcon = m_warningIcon;
break;
case LogType.Log:
m_boxIcon = m_infoIcon;
break;
case LogType.Exception:
m_boxIcon = m_errorIcon;
break;
default:
break;
}
// 这个按钮是因为这条box item是可以被点击选择的!!!
return GUILayout.Button(new GUIContent(content, m_boxIcon), m_boxItemStyle, GUILayout.ExpandWidth(true), GUILayout.Height(30.0f));
}

private void DrawUpperPanel()
{
m_upperPanel = new Rect(0, MENU_BAR_HEIGHT, this.position.width, (this.position.height - MENU_BAR_HEIGHT) * m_upperSizeRatio);
GUILayout.BeginArea(m_upperPanel, m_panelStyle);
GUILayout.Label("Log", m_panelLabelStyle);

// 在scrollview里填充log,unity
m_upperPanelScroll = GUILayout.BeginScrollView(m_upperPanelScroll);
for (int i = 0; i < m_logItems.Count; i++)
{
if (m_logTypeForUnshow.Contains(m_logItems[i].GetLogType))
{
continue;
}

// 画的时候,顺便接受item的点击的结果
if (DrawLogBox(m_logItems[i].LogInfo, m_logItems[i].GetLogType, i % 2 == 0, m_logItems[i].IsSelected))
{
if (null != m_selectedLogItem)
{
if (m_logItems[i] == m_selectedLogItem)
{
// click a some one, open code
// JumpToCurrentLogPos(); // 跳转到你点击的Log的顶部的代码文件(如果可以
}
else
{
m_selectedLogItem.IsSelected = false;
m_selectedLogItem = m_logItems[i];
m_selectedLogItem.IsSelected = true;
}
}
else
{
m_selectedLogItem = m_logItems[i];
m_selectedLogItem.IsSelected = true;
}
// 准备刷新
GUI.changed = true;
}
}

GUILayout.EndScrollView();
GUILayout.EndArea();
}


private void OnGUI()
{
// .....
if (GUI.changed)
{
Repaint();
}
}

显示Log详情以及调用栈

由于我脑子不好使,我不知道如何完美复刻Unity Console的详情,Unity自带Console中显示的代码链接既可以复制也可以点击跳转,我只做了简单的跳转。如果有比较熟悉编辑器开发的朋友,可以提供修改的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
private void DrawLowerPanel()
{
float yPos = PanelGroupHeight * m_upperSizeRatio + MENU_BAR_HEIGHT + RESIZER_HEIGHT;
m_lowerPanel = new Rect(0, yPos, this.position.width, PanelGroupHeight * (1.0f - m_upperSizeRatio));
GUILayout.BeginArea(m_lowerPanel, m_panelStyle);
GUILayout.Label("Log Detail", m_panelLabelStyle);

m_lowerPanelScroll = GUILayout.BeginScrollView(m_lowerPanelScroll);

string logDetail = null;
string[] logDetailMutiLine = null;

// TODO : code clean here
string pathline = "";
string tempCase = ".cs:";
string path = string.Empty;
int line = 0;
int splitwa = 0;

if (null != m_selectedLogItem)
{
logDetail = m_selectedLogItem.LogMessage;
GUILayout.TextArea(string.Format("{0}\n", m_selectedLogItem.LogInfo), m_textAreaStyle);

logDetailMutiLine = logDetail.Split('\n');
for (int i = 0; i < logDetailMutiLine.Length; i++)
{
// Regex match 'at xxx'
Match matches = Regex.Match(logDetailMutiLine[i], @"\(at (.+)\)", RegexOptions.Multiline);

if (matches.Success)
{
while (matches.Success)
{
pathline = matches.Groups[1].Value;
if (pathline.Contains(tempCase))
{
int splitIndex = pathline.LastIndexOf(":");
path = pathline.Substring(0, splitIndex);
line = Convert.ToInt32(pathline.Substring(splitIndex + 1));
string fullpath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets"));
fullpath = fullpath + path;
splitwa = logDetailMutiLine[i].LastIndexOf("(");
logDetailMutiLine[i] = logDetailMutiLine[i].Substring(0, splitwa);

GUILayout.BeginHorizontal();
GUILayout.TextArea(string.Format(" (at : {0})\n", logDetailMutiLine[i]), m_textAreaStyle);
if (GUILayout.Button(string.Format(" ( {0} )\n", pathline), m_labelButtonStyle))
{
// 打开文件的魔法
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(fullpath.Replace('/', '\\'), line);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
break;
}
}
}
else
{
GUILayout.TextArea(logDetailMutiLine[i], m_textAreaStyle);
}

}
}

GUILayout.EndScrollView();
GUILayout.EndArea();
}

这边用了正则表达式去匹配去寻找代码文件,是从网上查到的,我用着还不太熟练。所以写得很乱,后续会在工程中更新干净些的版本。

完善菜单栏功能

既然我们能显示Log了,那就别忘了补上清除Log的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public void ClearLogs()
{
if (null != m_selectedLogItem)
{
m_selectedLogItem.IsSelected = false;
}
m_selectedLogItem = null;

m_normalLogCount = 0;
m_warningLogCount = 0;
m_errorLogCount = 0;
m_logItems.Clear();
GUI.changed = true;
}


private void DrawMenuUpperBar()
{
// .....
if (GUILayout.Button(new GUIContent("Clear"), EditorStyles.toolbarButton, GUILayout.Width(40.0f)))
{
// 用于清空所有的 log
ClearLogs();
}
// .....
}

总结

这一期就到这里。感觉工具开发也有点搬砖,但是会用到各种各样的搬砖工具去搬运契合不同的砖,能接触到很多东西,还蛮有趣的。
下一期我会尝试把当前这个乞丐Log Console的功能都补齐。
代码有缺漏可以先参考工程。


完整工程链接

https://github.com/2C2C2C/TempUnityLogConsoleClone

本菜狗在上周领了一个做LogManager的任务。很高兴也很慌,毕竟从来没做过编辑器开发,于是面向搜索引擎编程开始辣,找了一些教程学着做,顺便分享一下。

需求分析(?

组里对这个LogManager的要求是在Unity原来的Log功能上再加上根据标签和危险度(?)来筛选。
仔细想想还挺麻烦。需要筛选的话,那自然需要一个Console面板,似乎Unity原本的Console不方便扩展,索性跟着网上的教程重新做一个。

弹出窗口

首先我们先把窗口弹出来。代码很简单。

我们可以从Unity头顶的菜单栏中的Window中找到这个面板并打开。打开了是空白的,当然啦,因为还什么都没画上去。

1
2
3
4
5
6
7
8
9
10
11
public class TempConsoleWindow : EditorWindow
{
[MenuItem("Window/Temp Console")]
private static void OpenWindow()
{
TempConsoleWindow window = GetWindow<TempConsoleWindow>();
GUIContent titleContent = new GUIContent("TempConsole", EditorGUIUtility.Load("icons/UnityEditor.ConsoleWindow.png") as Texture2D, "a clone sonsole");
window.titleContent = titleContent;
}

}

分割区块

我们把原本的面板分成4块:1.菜单栏;2. Log区;3. 调整棒(上下移动调整区域大小);4. 详情区。于是乎我们给这个4个区创建响应的变量为了方便绘制。

1
2
3
4
5
6
7
8
9
10
private Rect m_menuUpperBar = default;
private Rect m_upperPanel = default;
private Rect m_lowerPanel = default;
private Rect m_resizer = default;

private readonly float MENU_BAR_HEIGHT = 20.0f;
private float m_upperSizeRatio = 0.5f;
private readonly float RESIZER_HEIGHT = 4.0f;
private float PanelGroupHeight => position.height - MENU_BAR_HEIGHT;
private bool m_isResizing = false;

偷皮

Unity的绘制GUI方法中可以填写风格参数,我们绘制四个区块的时候自然也需要为区块准备皮和文字颜色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// log区风格以及log区的标题风格
private GUIStyle m_panelLabelStyle = default;
private GUIStyle m_panelStyle = default;
// 调整棒儿的风格
private GUIStyle m_resizerStyle = default;
// box item 其实是在log区显示的每一个log item
private GUIStyle m_boxItemStyle = default;
// 这是 log详情的文字风格
private GUIStyle m_textAreaStyle = default;
// 这是一个无边框的按钮风格,为代码跳转准备
private GUIStyle m_labelButtonStyle = default;

// 各种图标
private Texture2D m_infoIcon = null;
private Texture2D m_infoIconSmall = null;
private Texture2D m_warningIcon = null;
private Texture2D m_warningIconSmall = null;
private Texture2D m_errorIcon = null;
private Texture2D m_errorIconSmall = null;

private Texture2D m_boxBgOdd = null;
private Texture2D m_boxBgEven = null;
private Texture2D m_boxBgSelected = null;
private Texture2D m_boxIcon = null;

// 获取各种皮
private void GetAssets()
{
m_panelLabelStyle = new GUIStyle();
m_panelLabelStyle.fixedHeight = 30.0f;
m_panelLabelStyle.richText = true;
m_panelLabelStyle.normal.textColor = Color.white;
m_panelLabelStyle.fontSize = 20;

m_infoIcon = EditorGUIUtility.Load("icons/console.infoicon.png") as Texture2D;
m_infoIconSmall = EditorGUIUtility.Load("icons/console.infoicon.sml.png") as Texture2D;
m_warningIcon = EditorGUIUtility.Load("icons/console.warnicon.png") as Texture2D;
m_warningIconSmall = EditorGUIUtility.Load("icons/console.warnicon.sml.png") as Texture2D;
m_errorIcon = EditorGUIUtility.Load("icons/console.erroricon.png") as Texture2D;
m_errorIconSmall = EditorGUIUtility.Load("icons/console.erroricon.sml.png") as Texture2D;

m_resizerStyle = new GUIStyle();

m_panelStyle = new GUIStyle();
m_panelStyle.normal.background = EditorGUIUtility.Load("builtin skins/darkskin/images/projectbrowsericonareabg.png") as Texture2D;
// 这行是同事告诉我的,但是不知道为什么不管用,直接用会有空引用报错,要在GUI里用
// m_panelStyle.normal.background = GUI.skin.window.normal.background;

m_boxItemStyle = new GUIStyle();
m_boxItemStyle.normal.textColor = new Color(0.7f, 0.7f, 0.7f);

m_boxBgOdd = EditorGUIUtility.Load("builtin skins/darkskin/images/cn entrybackodd.png") as Texture2D;
m_boxBgEven = EditorGUIUtility.Load("builtin skins/darkskin/images/cnentrybackeven.png") as Texture2D;
m_boxBgSelected = EditorGUIUtility.Load("builtin skins/darkskin/images/menuitemhover.png") as Texture2D;

m_textAreaStyle = new GUIStyle();
m_textAreaStyle.normal.textColor = new Color(0.9f, 0.9f, 0.9f);
m_textAreaStyle.normal.background = EditorGUIUtility.Load("builtin skins/darkskin/images/projectbrowsericonareabg.png") as Texture2D;

m_labelButtonStyle = new GUIStyle();
m_labelButtonStyle.normal.textColor = Color.green;
m_labelButtonStyle.normal.background = m_textAreaStyle.normal.background;
m_labelButtonStyle.alignment = TextAnchor.MiddleLeft;
m_labelButtonStyle.stretchWidth = false;
var b = m_labelButtonStyle.border;
b.left = 0;
b.right = 0;
b.top = 0;
b.bottom = 0;
m_labelButtonStyle.border = b;

}


private void OnEnable()
{
GetAssets();
}

获取图像的参数都是magic number,这里不多提。图标浏览和获取参数可以参考下面两个页面。当然你也可以准备自己的素材。

https://unitylist.com/p/5c3/Unity-editor-icons
https://gist.github.com/rus89/375e107ed8c6db79d0c41b8612e5dbf3

绘制菜单栏

菜单栏上有几个按钮,我们把最常用的如清理,Play开始清除以及右边三个Filter选项。除了’Clear’是Button,其它的都是Toggle。所以得准备一些布尔变量。

1
2
3
4
5
6
7
8
9
10
11
12
private bool m_isClearOnPlay = false;
private bool m_isClearOnBuild = false;
public bool IsClearOnBuild => m_isClearOnBuild;
private bool m_isErrorPause = false;
private bool m_isShowLog = true;
private bool m_isShowWarning = true;
private bool m_isShowError = true;

private int m_normalLogCount = 0;
private int m_warningLogCount = 0;
private int m_errorLogCount = 0;
private HashSet<LogType> m_logTypeForUnshow = null;

准备好了,那么就可以开始绘制菜单栏了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
private void DrawMenuUpperBar()
{
m_menuUpperBar = new Rect(0.0f, 0.0f, this.position.width, MENU_BAR_HEIGHT);

// 开始绘制
GUILayout.BeginArea(m_menuUpperBar, EditorStyles.toolbar);
// 横向绘制!!!
GUILayout.BeginHorizontal();

if (GUILayout.Button(new GUIContent("Clear"), EditorStyles.toolbarButton, GUILayout.Width(40.0f)))
{
// 用于清空所有的 log
ClearLogs();
}
GUILayout.Space(5.0f);

// m_isCollapse = GUILayout.Toggle(m_isCollapse, new GUIContent("Collapse"), EditorStyles.toolbarButton, GUILayout.Width(55.0f));
m_isClearOnPlay = GUILayout.Toggle(m_isClearOnPlay, new GUIContent("Clear On Play"), EditorStyles.toolbarButton, GUILayout.Width(80.0f));
m_isClearOnBuild = GUILayout.Toggle(m_isClearOnBuild, new GUIContent("Clear On Build"), EditorStyles.toolbarButton, GUILayout.Width(85.0f));
m_isErrorPause = GUILayout.Toggle(m_isErrorPause, new GUIContent("Error Pause"), EditorStyles.toolbarButton, GUILayout.Width(70.0f));

// 弹性空白,我不太清楚应该怎么描述,但是它可以把后面的几个Toggle都尽可能往后面推
GUILayout.FlexibleSpace();

m_normalLogCount = Mathf.Clamp(m_normalLogCount, 0, 100);
m_warningLogCount = Mathf.Clamp(m_warningLogCount, 0, 100);
m_errorLogCount = Mathf.Clamp(m_errorLogCount, 0, 100);
m_isShowLog = GUILayout.Toggle(m_isShowLog, new GUIContent(m_numStrs[m_normalLogCount], m_infoIconSmall), EditorStyles.toolbarButton, GUILayout.Width(30.0f));
m_isShowWarning = GUILayout.Toggle(m_isShowWarning, new GUIContent(m_numStrs[m_warningLogCount], m_warningIconSmall), EditorStyles.toolbarButton, GUILayout.Width(30.0f));
m_isShowError = GUILayout.Toggle(m_isShowError, new GUIContent(m_numStrs[m_errorLogCount], m_errorIconSmall), EditorStyles.toolbarButton, GUILayout.Width(30.0f));

m_logTypeForUnshow.Clear();
if (!m_isShowLog)
{
m_logTypeForUnshow.Add(LogType.Log);
}

if (!m_isShowWarning)
{
m_logTypeForUnshow.Add(LogType.Warning);
}

if (!m_isShowError)
{
m_logTypeForUnshow.Add(LogType.Error);
m_logTypeForUnshow.Add(LogType.Assert);
m_logTypeForUnshow.Add(LogType.Exception);
}

// 横向绘制结束
GUILayout.EndHorizontal();
// 区域绘制结束
GUILayout.EndArea();
}

// 实际调用绘制
private void OnGUI()
{
DrawMenuUpperBar();
//DrawUpperPanel();
//DrawLowerPanel();
//DrawResizer();
}

这样就把菜单栏绘制好了。

简单绘制上下区栏

接下来再绘制调整棒之前先简单绘制上下区,待会儿做好调整棒之后就能直接测试效果。要注意给菜单栏以及调整版预留的高度,不然会得到错误的区域大小,添加调整棒后会更会出现奇怪现象。
现在只需要给上下区绘制空白就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private void DrawUpperPanel()
{
m_upperPanel = new Rect(0, MENU_BAR_HEIGHT, this.position.width, (this.position.height - MENU_BAR_HEIGHT) * m_upperSizeRatio);
GUILayout.BeginArea(m_upperPanel, m_panelStyle);
GUILayout.Label("Log", m_panelLabelStyle);

// 为了画log item而准备的 ScrollView
m_upperPanelScroll = GUILayout.BeginScrollView(m_upperPanelScroll);
GUILayout.EndScrollView();

GUILayout.EndArea();
}


private void DrawLowerPanel()
{
float yPos = PanelGroupHeight * m_upperSizeRatio + MENU_BAR_HEIGHT + RESIZER_HEIGHT;
m_lowerPanel = new Rect(0, yPos, this.position.width, PanelGroupHeight * (1.0f - m_upperSizeRatio));
GUILayout.BeginArea(m_lowerPanel, m_panelStyle);
GUILayout.Label("Log Detail", m_panelLabelStyle);

// 为 log详情准备的 ScrollView
m_lowerPanelScroll = GUILayout.BeginScrollView(m_lowerPanelScroll);
GUILayout.EndScrollView();

GUILayout.EndArea();
}

// 实际调用绘制
private void OnGUI()
{
DrawMenuUpperBar();
DrawUpperPanel();
DrawLowerPanel();
//DrawResizer();
}

绘制调整棒 添加区域调整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

private void DrawResizer()
{
float yPos = (this.position.height - MENU_BAR_HEIGHT) * m_upperSizeRatio + MENU_BAR_HEIGHT;
m_resizer = new Rect(0, yPos, this.position.width, RESIZER_HEIGHT);

GUILayout.BeginArea(new Rect(m_resizer.position + (Vector2.up * RESIZER_HEIGHT), new Vector2(this.position.width, 2.0f)), m_resizerStyle);
GUILayout.EndArea();

// 把 m_resizer 区域内的光标换成拉伸指示光标
EditorGUIUtility.AddCursorRect(m_resizer, MouseCursor.ResizeVertical);
}


private void Resize(Event currentEvent)
{
if (m_isResizing)
{
// 通过鼠标位置改变调整棒位置
float pos = currentEvent.mousePosition.y - MENU_BAR_HEIGHT;

m_upperSizeRatio = pos / PanelGroupHeight;
m_upperSizeRatio = Mathf.Clamp(m_upperSizeRatio, 0.5f, 0.8f);
//Debug.Log($"next upper ratio {m_upperSizeRatio}");
Repaint();
}
}

private void ProcessEvents(Event currentEvent)
{
if (EventType.MouseDown == currentEvent.type)
{
// if press mouse left in resizer
m_isResizing = (0 == currentEvent.button && m_resizer.Contains(currentEvent.mousePosition));
}
else if (EventType.MouseUp == currentEvent.type)
{
m_isResizing = false;
}

Resize(currentEvent);
}

总结

其实感觉编辑器开发挺麻烦的,除了区域绘制要注意,还有一堆API不好查不会用。下一期将会将Log信息捕获并显示在我们自己的这个Console上。


完整工程链接(持续更新中) :
https://github.com/2C2C2C/TempUnityLogConsoleClone

P.S : 我在做的时候是参考了某个游戏工作室发布的教程,我也顺便把这个教程分享出来。
https://gram.gs/gramlog/creating-editor-windows-in-unity/

给Unity用上代理

前言

之前有段时间公司的网络不是很稳定,从UnityHub上拖东西99%失败。自己又太菜不想安装Android Studio手动设置安卓打包的东西,于是乎只能想办法给下载加速。

准备

首先你要有那个,就是那个你为了看PH才弄的小工具:)

命令

首先默认我们的小✈代理端口是1080。
似乎V2可以同时有SOCK5和HTTP代理的样子,那也把HTTP代理的端口设置成1080.

1
2
3
4
5
6
7

# 设置代理
set HTTP_PROXY=http://127.0.0.1:1080
set HTTPS_PROXY=http://127.0.0.1:1080

start "" "your unity hub path"
# like path is like -> D:\Unity\Unity Hub\Unity Hub.exe

爆炸

非常简单就是这样。

其实东西都是从有木桑博客看来的
https://www.yomunchan.moe/archives/320

这边有蛮多游戏开发相关的文章,帮了我不少,十分感谢了。

给GIT用上代理

前言

在看着教程搭建这个博客的时候,我在GIT上也拖了不少的包。直连有时候真的速度慢到吐血,原因很复杂也莫得办法。
不过还好,我们其实可以给GIT上个代理,这样能给速度一些改善。

准备

我是在本机器安装有代理客户端,小🛩和V2都彳亍。
我这边的情况是这样的,小飞机走SOCK5代理,V2走的HTTP代理。
因为平时我只可能开着一个,所以端口都是1080。

命令

废话不多说了,直接上命令。

首先我们看看已有的设置.

1
2
3
4
5
6
7

# 查看全局配置中的代理
git config --global --get http.proxy


# 查看当前生效配置中的代理
git config --get http.proxy

然后我们加上自己的代理。
当前我们假设的状态是本机开着小✈或者V2,且代理端口为1080的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 括号中的都是可选项

# 若用的小飞机, --global 意味着应用到全局设置
git config (--global) http.proxy sock5://127.0.0.1:1080
git config (--global) https.proxy sock5://127.0.0.1:1080

# 这样应用后,没开代理GIT就会抽风了,所以如果平时速度还不错的话记得用完取消代理
git config (--global) --unset http.proxy (sock5://127.0.0.1:1080)
git config (--global) --unset https.proxy (sock5://127.0.0.1:1080)

# 若用的V2, --global 意味着应用到全局设置
git config (--global) http.proxy http://127.0.0.1:1080
git config (--global) https.proxy https://127.0.0.1:1080

# 取消
git config (--global) --unset http.proxy (http://127.0.0.1:1080)
git config (--global) --unset https.proxy (https://127.0.0.1:1080)

挂了代理真的飞速,爽到。