优秀个人网站案例/站长统计推荐
向量计算
Vector3.Slerp(起点坐标,终点坐标,t),可是从起点坐标以一个圆形轨迹到终点坐标,有那么多条轨迹,那怎么办
Vector3.Slerp
进行的是沿球面插值,因此并不是沿着严格的“圆形轨迹”移动,而是在两点所在的大圆弧(球体上的最短路径)上插值。
点乘叉乘判断方位,点乘得到的结果大于0和小于0,大于0的时候相距的角度大于90度,小于0则说明在前方
90度以内为正,到180为负,此为两向量点乘可得结果
所以两点之间可以判断前后的关系
叉乘,两向量相乘出垂直的向量,通过新向量的.y判断左右,大于0朝上,说明在目标向量的右侧,小于0,说明在目标向量的左侧
点乘(Dot Product)
A⋅B=∣A∣∣B∣cosθ
A⋅B=A1B1+A2B2+⋯+AnBn
-
2D 点乘: 若 A=(Ax,Ay)\mathbf{A} = (A_x, A_y)A=(Ax,Ay) 和 B=(Bx,By)\mathbf{B} = (B_x, B_y)B=(Bx,By),那么点乘为:
A⋅B=AxBx+AyBy\mathbf{A} \cdot \mathbf{B} = A_x B_x + A_y B_yA⋅B=AxBx+AyBy -
3D 点乘: 若 A=(Ax,Ay,Az)\mathbf{A} = (A_x, A_y, A_z)A=(Ax,Ay,Az) 和 B=(Bx,By,Bz)\mathbf{B} = (B_x, B_y, B_z)B=(Bx,By,Bz),那么点乘为:
A⋅B=AxBx+AyBy+AzBz\mathbf{A} \cdot \mathbf{B} = A_x B_x + A_y B_y + A_z B_zA⋅B=AxBx+AyBy+AzBz
debug的射线
Debug.DrawLine(点&点)
Debug.DrawLine(Vector3 start, Vector3 end, Color color, float duration);Vector3 startPoint = new Vector3(0, 0, 0);
Vector3 endPoint = new Vector3(5, 0, 0);
Debug.DrawLine(startPoint, endPoint, Color.red, 2.0f); // 画一条从 (0,0,0) 到 (5,0,0) 的红色线,持续2秒
Debug.DrawRay (点&向量)
Debug.DrawRay(Vector3 start, Vector3 direction, Color color, float duration);Vector3 rayOrigin = new Vector3(0, 0, 0);
Vector3 rayDirection = new Vector3(5, 0, 0); // 方向向量控制长度
Debug.DrawRay(rayOrigin, rayDirection, Color.blue, 2.0f);// 画出长度为 5 的蓝色射线,持续2秒
Camera的坐标系转换
-
WorldToScreenPoint: 将世界坐标转换为屏幕坐标。常用于把场景中物体的位置转换为 UI 屏幕上的坐标。
-
物体位置转为 UI 坐标:假设你有一个 3D 物体,你希望在 UI 上显示其位置,或者让一个 UI 元素跟随它。这时你就需要把物体的世界坐标转换为屏幕坐标,UI 系统才能正确定位该元素。
-
射线检测或点击交互:你可以使用
WorldToScreenPoint
来将 3D 世界中的物体位置转换为 2D 坐标,以便处理基于屏幕点击的交互,例如在物体上点击时触发某些事件。 -
// 获取物体的世界坐标 Vector3 worldPosition = objectTransform.position;// 将世界坐标转换为屏幕坐标 Vector3 screenPosition = Camera.main.WorldToScreenPoint(worldPosition);// 现在 screenPosition 包含物体在屏幕上的 X、Y 坐标(以像素为单位),和 Z 值(深度)。
关于Z值:是目标点,垂直到相机面的距离。
-
Z 值可以用来判断物体是在摄像机的前面(正值)还是后面(负值)
-
ScreenToWorldPoint: 将本地屏幕坐标转换为世界坐标。通常在基于屏幕点击(例如鼠标点击)来确定场景中的具体位置时使用。
-
// 获取鼠标点击位置(屏幕坐标) Vector3 screenPosition = Input.mousePosition;// 设置一个距离(深度值) screenPosition.z = 10.0f; // 假设距离摄像机10个单位// 将屏幕坐标转换为世界坐标 Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);// 使用 worldPosition 在3D世界中做某些操作,比如放置物体
-
Z 值的作用:
ScreenToWorldPoint
的 Z 值非常重要。它决定了转换的深度,即这个屏幕坐标在 3D 世界中距离摄像机有多远。如果 Z 值太小,结果会在摄像机附近;如果 Z 值太大,结果会在远处的世界位置。ScreenToWorldPoint 用来将屏幕上的 2D 坐标转换为 3D 世界中的点,核心是需要一个 Z 值来确定该点在世界中的深度位置。
-
WorldToViewportPoint: 将世界坐标转换为视口坐标。视口坐标通常指的是 (0,0) 到 (1,1) 范围内的相对坐标,常用于与 UI 元素的交互。
-
// 获取物体的世界坐标 Vector3 worldPosition = objectTransform.position;// 将世界坐标转换为视口坐标 Vector3 viewportPosition = Camera.main.WorldToViewportPoint(worldPosition);// 现在 viewportPosition 是 (X, Y, Z) 值 // X 和 Y 值的范围为 0 到 1,表示相对摄像机视野中的位置 // Z 值表示物体与摄像机之间的距离
视口坐标的 X 和 Y 值可以超出 0 到 1 的范围
-
这些坐标值是相对的,X 和 Y 超出范围并不意味着物体完全不可见,物体仍然可能部分显示在边缘(视角的原因)。
-
如果物体的视口坐标的 X 和 Y 值在 (0,0) 到 (1,1) 之间,并且 Z 值为正,则物体在摄像机的视野内;否则物体在视野外或被其他物体遮挡。
-
ViewportToWorldPoint: 将视口坐标转换为世界坐标。这在处理以视口为基础的坐标系转换时很有用,比如在分辨率变化时保持特定 UI 元素的比例。
-
ViewportToScreenPoint: 将视口坐标转换为屏幕坐标。可以帮助从相对的视口坐标系转换到具体像素的屏幕坐标系。
- 视口坐标系:这是相对的,(0,0) 代表左下角,(1,1) 代表右上角,与屏幕的分辨率无关。
- 屏幕坐标系:这是绝对的,单位是像素。例如,在 1920x1080 的屏幕上,(1920,1080) 代表屏幕的右上角。
-
视口超出 0 到 1 的范围:如果视口坐标的 X 和 Y 值超出了 (0,0) 到 (1,1),那么屏幕坐标也会相应地超出屏幕范围,代表物体在屏幕之外。
Transform的坐标系方法
Transform
有父物体时,transform.position
表示的是该物体在世界坐标系中的位置
(注:这里的本地,指的是每一个transform组件,都有自己的本地坐标系)
世界转本地
传入世界vector3,然后以本物体的坐标系重新修改,再返回改后 的vector3
InverseTransformDirection
:将一个方向向量从世界空间转换到本地空间(即局部空间)。这个向量表示的是一个方向,不会受到位移的影响。InverseTransformPoint
:将一个点的坐标从世界空间转换到本地空间。这个方法会受到父对象的位置影响。InverseTransformVector
:将一个向量从世界空间转换到本地空间。和InverseTransformDirection
类似,但它不仅仅表示方向,还可以包括缩放。- 为毛偏用inverse:"inverse" 通常给人一种“反转”的感觉,但在这里的语境中,它指的是 从世界坐标系 “逆转回”到局部坐标系 的操作。
- 这个“Inverse” 其实指的是矩阵的逆变换。在 3D 渲染或游戏开发中,
Transform
操作本质上是通过矩阵来进行坐标转换的。对象在世界坐标系中的变换(位置、旋转、缩放)会组成一个变换矩阵,这个矩阵可以把局部坐标转换到世界坐标系。而“逆矩阵”操作则是反过来,将世界坐标系的值转换回局部坐标系。
本地坐标转世界坐标:
Vector3 localDirection = new Vector3(1, 0, 0); // 本地坐标中的向右方向
Vector3 worldDirection = transform.TransformDirection(localDirection); // 转换为世界坐标系的方向
本transform下的坐标传入,转为世界的坐标
TransformDirection
:将一个本地坐标系下的方向转换到世界坐标系。TransformPoint
:将一个本地坐标系下的点的坐标转换到世界坐标系。TransformVector
:将一个本地坐标系下的向量转换到世界坐标系。
// 获取物体的 Transform 组件
Transform objTransform = gameObject.transform;// 使用 TransformPoint 方法将本地坐标转换为世界坐标
Vector3 worldPosition = objTransform.TransformPoint(localPosition);// 使用 InverseTransformPoint 方法将世界坐标转换为本地坐标
Vector3 localPosition = objTransform.InverseTransformPoint(worldPosition);
意思是一个Transform,的坐标值,会因为父对象改变而改变,并不完全取决于世界坐标
一个对象的 Transform
通常包括位置(position)、旋转(rotation)和缩放(scale)等属性。
这些属性的值可以分为局部坐标(local coordinates)和世界坐标(world coordinates)两种,五五开。
弧度数值与角度数值
rad弧度。degree角度
角度乘以一个0.几转换成弧度
弧度乘以五十多变成角度
Mathf.Lerp
public static float Lerp(float a, float b, float t);
a
:起始值。b
:结束值。t
:插值因子,取值范围通常为 [0, 1]。当t=0
时返回a
,当t=1
时返回b
,如果t
在 0 和 1 之间,返回 a 和 b 之间的线性插值值。
工作原理:
Lerp
函数的原理是:
result=a+(b−a)×t
当 t
为 0 时,结果是 a
;当 t
为 1 时,结果是 b
;而 t
为 0 和 1 之间的值时,结果是 a
和 b
之间的插值。
BaseEventData
-
统一处理不同事件类型的数据:
- 不同的事件(如鼠标点击、键盘按键、触摸、拖拽)可能需要传递不同的信息。
eventData
通过不同的子类(如PointerEventData
、AxisEventData
)来封装这些信息,简化了事件系统的处理流程。 - 这样,所有事件的数据结构就变得一致,方便事件的处理和扩展。
- 不同的事件(如鼠标点击、键盘按键、触摸、拖拽)可能需要传递不同的信息。
-
传递事件的详细信息:
- 当你处理用户交互时,除了知道事件发生了之外,通常你还需要了解事件发生的具体细节。例如:
- 用户点击了什么位置?
- 用户拖拽了哪个对象?
- 鼠标或触控设备按下的是哪个按钮?
eventData
中包含了这些信息,可以让你在事件回调中轻松获取并处理这些数据。
- 当你处理用户交互时,除了知道事件发生了之外,通常你还需要了解事件发生的具体细节。例如:
举例说明:
假设你在处理点击事件时,如果只提供一个简单的事件通知,可能只能知道“某个按钮被点击了”。但使用 PointerEventData
,你可以得到更多的信息:
- 点击的对象是什么。
- 点击的坐标是哪里。
- 按下的鼠标按钮是哪一个(左键、右键、中键等)。
- 是否发生了拖拽操作。
-
public void OnButtonClick(PointerEventData eventData) {Debug.Log("Clicked at position: " + eventData.position); }
ugui的RectTransform
unity中的小碎块功能
ugui不允许在同一个物体上挂相同的组件
lambda表达式的简写
()=>{ }
单个参数,且已知类型,可以省括号
仅一条返回语句,不用写return,直接在=>右边写要返回的东西
错误示例:
错误 Func<int> func = () => return 1;
正确 Func<int> func = () => 1; // 简写形式,无需 return 关键字
正确 Func<int> func = () =>{ return 1; };// 显式使用 return 关键字
只有一个参数的 Lambda 表达式
单行表达式: 如果 lambda 表达式仅包含一个表达式,可以省略花括号和 return
关键字
x => x * x
表示一个接受一个参数x
并返回x * x
Func<int, int> square = x => x * x;
多个参数的 Lambda 表达式
(x, y) => x + y
表示一个接受两个参数x
和y
并返回它们的和Func<int, int, int> add = (x, y) => x + y;
无参数的 Lambda 表达式
不接受参数并执行
Console.WriteLine("Hello, World!")
Action greet = () => Console.WriteLine("Hello, World!");
块状的 Lambda 表达式
单个参数配块状代码
Func<int, int> doubleValue = x => {int result = x * 2;return result; };
类型推断与显式类型
编译器可以自动推断 lambda 表达式的参数类型
Func<int, int> increment = x => x + 1; // 自动推断参数类型为 int
你也可以显式指定参数类型(通常在委托声明时指定)
Func<int, int> increment = (int x) => x + 1;
Resources.Load<T>()
Resources.LoadAsync<T>()
返回值的问题
这两种泛型资源加载都只有一种返回值,Load是返回T,Loadasync返回ResourceRequest,T在ResourceRequest.asset中体现
Resources.Load<T>()
:
- 这个方法会立即加载资源,并返回你指定类型
T
的对象。 - 你需要手动指定资源的类型,通过泛型参数
T
。返回值的类型就是你传入的T
。 Resources.Load()
还有非泛型的重载,返回值类型是UnityEngine.Object
Resources.LoadAsync<T>()
:
- 这个方法是异步加载资源。加载过程不会阻塞主线程,返回的对象是一个
ResourceRequest
,但是其中包含你指定的泛型类型T
。 - 加载完成后,你可以通过
ResourceRequest.asset
访问加载的资源,该资源类型是你指定的T
。
泛型的问题
总结:泛型是要自己输入的,用泛型T是为了减少手动类型转换的过程
如果不传入泛型 T
,Resources.Load()
会返回一个通用的 UnityEngine.Object
必须手动将它转换为你期望的类型
Object obj = Resources.Load("MyPrefab"); // 返回 UnityEngine.Object
GameObject myPrefab = (GameObject)obj; // 手动转换if (obj is GameObject)
{GameObject myPrefab = (GameObject)obj;
}GameObject myPrefab = Resources.Load<GameObject>("MyPrefab");
所以泛型T,要手动传入这个资源的类型,从而省去里面的类型转换
如果泛型填的不对,就执行不了
如果你在泛型中传入了错误的类型(比如试图加载一个
AudioClip
但是传入了GameObject
),不会执行成功,返回null
,而不会发生类型转换的错误(InvalidCastException
)。这样能在开发过程中帮助你迅速发现错误。AudioClip audioClip = Resources.Load<AudioClip>("MyPrefab"); // 错误:MyPrefab 不是 AudioClip if (audioClip == null) {// 资源加载失败,因为资源不是 AudioClip 类型Debug.Log("Failed to load AudioClip"); }
相关文章:

Unity中的功能解释(数学位置相关和事件)
向量计算 Vector3.Slerp(起点坐标,终点坐标,t),可是从起点坐标以一个圆形轨迹到终点坐标,有那么多条轨迹,那怎么办 Vector3.Slerp 进行的是沿球面插值,因此并不是沿着严格的“圆形…...

ElementPlus---Timeline 时间线组件使用示例
介绍 使用ElementPlus时间线组件在后台首页实现通知公告列表展示,使用Vue3开发。 实现代码 Vue3代码 <el-timeline><el-timeline-itemstyle"max-width: 600px"v-for"(activity, index) in activities":key"index":times…...

推荐4款2024年大家都在用的高质量翻译器。
翻译器在我们的生活中有着很重要的作用,不管是我们在学习还是工作,生活娱乐,出国旅游等场合都会派上用场,它是我们解决沟通的障碍,提高阅读效率的好帮手。我自己使用的翻译器有很多,可以给大家列举几款特别…...

Mybatis 返回 Map 对象
一、场景介绍 假设有如下一张学生表: CREATE TABLE student (id int NOT NULL AUTO_INCREMENT COMMENT 主键,name varchar(100) NOT NULL COMMENT 姓名,gender varchar(10) NOT NULL COMMENT 性别,grade int NOT NULL COMMENT 年级,PRIMARY KEY (id) ) ENGINEInnoD…...

Vue3(三)路由基本使用、工作模式(history,hash)、query传参和param传参、props配置、编程式路由导航
文章目录 一、路由的基本使用二、路由器的工作模式三、RouterLink中to的两种写法四、嵌套路由五、路由传参1. query传参2. params传参 六、路由的propos配置七、编程式路由导航 一、路由的基本使用 安装:npm i vue-router 在src/pages文件下,创建三个路…...

TypeScript概念讲解
简单来说,TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准; TypeScript 由微软开发的自由和开源的编程语言; TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 Jav…...

C++ | Leetcode C++题解之第437题路径总和III
题目: 题解: class Solution { public:unordered_map<long long, int> prefix;int dfs(TreeNode *root, long long curr, int targetSum) {if (!root) {return 0;}int ret 0;curr root->val;if (prefix.count(curr - targetSum)) {ret pref…...

回复《对话损友 2》
回复《对话损友 2》 承蒙贵人挂念,亦感激贵人给予这般交流的契机(对话损友 2 -- 回复-CSDN博客)。我自身也一直期望能留存些岁月的痕迹,然而却常困惑于不知哪些事物值得铭记,哪些又应被永远忘却。 随着时光流转&#x…...

MySQL - 运维篇
一、日志 1. 错误日志 2. 二进制日志 3. 查询日志 记录了所有的增删改查语句以及DDL语句 4. 慢查询日志 二、主从复制 1. 概述 2. 原理 3. 搭建 三、分库分表 1. 介绍 2. Mycat概述 3. Mycat入门 4. Mycat配置 5. Mycat分片 6. Mycat管理及监控 四、读写分离 1. 介绍 2. 一…...

WebGIS开发及市面上各种二三维GIS开发框架对比分析
GIS前端开发是现代WebGIS应用开发中非常重要的一环,通过前端开发框架,可以实现地图展示、交互、分析等功能。本文将介绍当前市面上常用的GIS前端开发框架,并进行对比分析。 Leaflet Leaflet是一款轻量级的开源地图库,它提供了丰…...

[论文精读]TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor
期刊名称:IEEE Transactions on Information Forensics and Security 发布链接:TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor | IEEE Journals & Magazine | IEEE Xplore 中文译名:TorWard:…...

pytest - 多线程提速
import timedef test1_test1():time.sleep(1)assert 1 1, "11"def test1_test2():time.sleep(1)assert 1 1, "11" 上面2个函数,执行情况: 正常执行时,花费 2.08s2个进程执行时,花费 1.18s2个线程执行时&a…...

python中logging的用法
logging.error 是 Python logging 模块中的一个方法,专门用于记录错误级别(ERROR)的日志信息。logging 模块是 Python 提供的标准日志工具,用于生成各种级别的日志消息,并支持日志的格式化和存储。 logging.error 的基…...

【YOLO目标检测车牌数据集】共10000张、已标注txt格式、有训练好的yolov5的模型
目录 说明图片示例 说明 数据集格式:YOLO格式 图片数量:10000(2000张绿牌、8000张蓝牌) 标注数量(txt文件个数):10000 标注类别数:1 标注类别名称:licence 数据集下载:车牌数据…...

gdb xterm 调试 openmpi 程序
1,编写编译一个openmpi程序 迭代计算 PI 的源程序: pi_reduce.c #include <stdio.h>#include <math.h> #include <mpi.h>double f(double); double f(double x) {return (4.0/(1.0x*x)); }int main(int argc, char* argv[]) {int d…...

【STM32】江科大STM32笔记汇总(已完结)
STM32江科大笔记汇总 STM32学习笔记课程简介(01)STM32简介(02)软件安装(03)新建工程(04)GPIO输出(05)LED闪烁& LED流水灯& 蜂鸣器(06)GPIO输入(07)按键控制LED 光敏传感器控制蜂鸣器(08)OLED调试工具(09)OLED显示屏(10)EXTI外部中断(11)对射式红外传感器计次 旋转编码器…...

Java基础扫盲(二)
想看Java基础扫盲(一)的可以观看我的上篇文章Java基础扫盲 目录 String为什么设计为不可变的 String有长度限制吗 为什么JDK9将String的char[]改为byte[] 泛型中K,T,V,E,Object,?等都代表什么含义 怎么修改一个类中使用了private修饰的String类型…...

兼容React的刮刮乐完整代码实现
需要兼容React的刮刮乐完整代码实现 在现代Web开发中,React作为一种流行的前端框架,为开发者提供了构建动态界面的强大工具。刮刮乐效果作为一种趣味性的用户交互,能够显著提升用户体验和参与度。本文将详细介绍如何在React项目中实现一个兼…...

PHP程序如何实现限制一台电脑登录?
PHP程序如何实现限制一台电脑登录? 可以使用以下几种方法: 1. IP地址限制:在PHP中,可以通过获取客户端的IP地址,然后与允许登录的IP地址列表进行比对。如果客户端的IP地址不在列表中,就禁止登录。 “php $…...

nodejs fs 模块的简介与相关案例
fs 文件系统模块 什么是 fs 文件系统模块? fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作要求。* 例如: fs.readFile() 方法用来读取文件内容。fs.writeFile() 方法用来写入文…...

计算机毕业设计 基于Flask+Vue的博客系统 Python毕业设计 前后端分离 附源码 讲解 文档
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...

基于SSH的酒店管理系统的设计与实现 (含源码+sql+视频导入教程)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSH的酒店管理系统拥有两种角色 管理员:房间管理、房型管理、客户管理、预定管理、入住管理(到店入住、预定入住、正在入住)、账单管理、会员管理…...

消息队列10:为RabbitMq添加连接池
环境: win11rabbitmq-3.8.17.net 6.0RabbitMQ.Client 6.8.1vs2022 安装RabbitMq环境参照: window下安装rabbitmqlinux下安装rabbitmq 问题:rabbitmq的c#客户端没有自带连接池,所以需要手动实现。 简易实现如下: usi…...

在使用 Docker 时,用户可能会遇到各种常见的错误和问题
在使用 Docker 时,用户可能会遇到各种常见的错误和问题。以下是一些需要注意的常见错误及其可能的解决方案: 1. 权限问题 在 Linux 系统上运行 Docker 命令时,可能会遇到权限不足的问题。解决这个问题通常有两种方法: 使用 sud…...

MinIO使用客户端进行桶和对象的管理
MinIO使用客户端进行桶和对象的管理 minio安装完成后,除了自带的webui管理界面,还可以使用官方配套的客户端mc进行管理。除此之外,还可以使用第三方客户端s3browser也可以完成对象和桶的生命周期管理。 1. 官方客户端mc MinIO客户端 mc 命…...

数据库管理-第244期 一次无法switchover的故障处理(20240928)
数据库管理244期 2024-09-28 数据库管理-第244期 一次无法switchover的故障处理(20240928)1 问题展现2 问题排查与处理2.1 问题12.2 问题2 3 问题分析4 总结 数据库管理-第244期 一次无法switchover的故障处理(20240928) 作者&…...

太绝了死磕这本大模型神书!
今天给大家推荐一本大模型神书,就是这本:《大语言模型:基础与前沿》 书籍介绍: 本书深入阐述了大语言模型的基本概念和算法、研究前沿以及应用,涵盖大语言模型的广泛主题,从基础到前沿,从方法…...

Kevin‘s notes about Qt---Episode 6 不同类中创建同一对象
问题描述 使用场景 现在在我的Qt界面中需要同时使用采集卡的AI(Analog Input)和AO(Analog Output)功能,均已分别调通,但是像之前一样通过创建两个类,然后分别在两个线程中进行操作的方式并不能实现。 原本写法 头文件 art_ao.h 核心代码如下: #ifndef ART_AO_H #defi…...

YOLOv9改进策略【Conv和Transformer】| AssemFormer 结合卷积与 Transformer 优势,弥补传统方法不足
一、本文介绍 本文记录的是利用AssemFormer优化YOLOv9的目标检测网络模型。传统卷积和池化操作会导致信息丢失和压缩缺陷,且传统的注意力机制通常产生固定维度的注意力图,忽略了背景中的丰富上下文信息。本文的利用AssemFormer改进YOLOv9,以在特征传递和融合过程中增加多尺…...

Git 的安装和配置
Git 是跨平台的,可以在 Windows,Linux、Unix 和 Mac 各几大平台上使用 由于笔者主要是使用 Windows,其他平台下安装 Git 的方法暂且不表(可参考廖雪峰老师的博客:安装 Git) Windows 安装 Git 从 Git…...