Java注解
else if的省略问题(可能看花)
else if也是取最近的if连通,看上去加了{}就可以正常执行了,缩进要命,不提示真容易看错,
组合数公式和数组参数
在 C++ 中,数组作为函数参数时,实际上是以指针的形式传递的,因此它是引用的。修改数组的内容会影响原始数组。
c++里正常数组是引用,vector不同,是默认复制一个备份,然后再Java和c#里,只要是数组,就是引用类型
-
C++:
- 正常数组(如
int arr[]
)在函数参数中表现为指针,实际上是通过引用(指向数组的首元素)来传递的。因此,任何修改都会影响原始数组。 std::vector
默认是按值传递(复制一份),但可以通过引用传递(std::vector<int>& vec
)来避免复制,从而影响原始的vector
。
- 正常数组(如
-
Java:
- 数组是对象,所有数组(如
int[] arr
)都是引用类型。因此,传递数组时,是通过引用传递的,任何修改都会影响原始数组。 ArrayList
也是对象,行为类似。
- 数组是对象,所有数组(如
-
C#:
- 数组同样是引用类型(如
int[] arr
),通过引用传递,修改会影响原始数组。 List<T>
也是引用类型,传递方式相同。
- 数组同样是引用类型(如
SQL复杂查询
存在量词、全称量词、集合运算(如 IN
)和连接运算(如 JOIN
)
存在量词、全称量词、集合运算(如 IN
)和连接运算(如 JOIN
)是 SQL 中处理查询的重要概念。它们之间的关系及可替换性取决于具体的语义和上下文。以下是它们的关系及是否可以互相替换的分析。
1. 存在量词 (EXISTS)
EXISTS
用于判断是否存在至少一条记录满足某个条件。其语法通常是WHERE EXISTS (子查询)
。
2. 全称量词 (ALL)
ALL
用于检查某个条件是否对集合中的所有元素都成立。其语法通常是WHERE column_name OPERATOR ALL (子查询)
。SELECT ProductName FROM Products WHERE Price < ALL ( SELECT Price FROM Products WHERE Category = 'Electronics' );
这里查询的是所有电子产品中,价格低于其他所有电子产品的产品。
3. 集合运算 (IN)
IN
运算符用于检查某个值是否在一个特定的集合中。其语法通常是WHERE column_name IN (子查询或值列表)
。-
SELECT CustomerName FROM Customers WHERE CustomerID IN ( SELECT CustomerID FROM Orders );
这里查询的是有订单的所有客户。
4.连接运算 (JOIN)
JOIN
是一种将多个表的数据结合起来的方式。通过连接条件将相关表的记录组合。
-- 使用 EXISTS
SELECT CustomerName
FROM Customers c
WHERE EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustomerID = c.CustomerID
);
-- 使用 IN
SELECT CustomerName
FROM Customers
WHERE CustomerID IN (
SELECT CustomerID
FROM Orders
);
SELECT c.CustomerName
FROM Customers c
WHERE NOT EXISTS (
SELECT 1
FROM Orders o
WHERE o.CustomerID = c.CustomerID
);
select 1
为什么选择 SELECT 1
?
- 效率:
SELECT 1
通常被认为是更有效率的,因为数据库不需要返回任何实际数据行。只要存在至少一条记录,数据库就会返回真值。 - 语义清晰:使用
1
或NULL
等常数可以清楚地表明你关心的是记录的存在性,而不是具体的返回值。
3. 可以用 SELECT 2
或 SELECT 3
吗?
是的,你可以用 SELECT 2
、SELECT 3
,甚至 SELECT *
,但在这个上下文中,这些选择没有实际意义,因为你并不关心返回的具体值。例如:
SELECT 2
和SELECT 3
也能起到相同的作用,但返回值会有所不同。- 如果你用
SELECT *
,可能会导致性能下降,因为数据库会试图返回所有列的信息,而在这里并不需要。
NOT EXISTS
NOT EXISTS()
是一个用于检查子查询返回的结果集是否为空的运算符。它返回 TRUE
当子查询没有返回任何行时。这在检查某个条件是否不成立时非常有用。
语法分解
-
主查询:
SELECT c.CustomerName
:选择Customers
表中的客户名称。FROM Customers c
:指定从Customers
表中查询,给这个表一个别名c
。
-
子查询:
WHERE NOT EXISTS (...)
:这一部分用于检查条件,如果子查询中的条件不成立,则主查询的当前记录会被返回。SELECT 1 FROM Orders o
:从Orders
表中选择,给这个表一个别名o
。SELECT 1
是一个常用的写法,因为我们只关心是否存在记录,而不是具体的内容。WHERE o.CustomerID = c.CustomerID
:这是条件,检查Orders
表中的CustomerID
是否与主查询中的客户c.CustomerID
相匹配。
整体逻辑
- 这个查询的逻辑是:对于每一个客户,检查是否存在与该客户编号匹配的订单。如果没有匹配的订单(即
NOT EXISTS
为真),那么这个客户的名称会被返回。
SELECT c.CustomerID,
c.CustomerName,
p.ProductID,
p.ProductName,
od.Quantity,
od.Amount
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
WHERE c.CustomerID IN (
SELECT CustomerID
FROM Orders o
JOIN OrderDetails od ON o.OrderID = od.OrderID
GROUP BY o.CustomerID
HAVING COUNT(DISTINCT od.ProductID) >= 3
)
ORDER BY c.CustomerID, p.ProductID;
-
主查询部分:
- 选择
CustomerID
、CustomerName
等字段,以便获取满足条件客户的每条订单明细记录。
- 选择
-
子查询部分:
- 计算每位客户订购的商品种类数
COUNT(DISTINCT od.ProductID)
。 - 使用
HAVING
过滤出订购商品种类数不少于3的客户编号CustomerID
。
- 计算每位客户订购的商品种类数
-
条件筛选:
- 主查询根据子查询结果筛选出符合要求的客户的所有订单明细,并按
CustomerID
和ProductID
排序。
- 主查询根据子查询结果筛选出符合要求的客户的所有订单明细,并按
IK和换装功能
在 Unity 中,IK 指的是 Inverse Kinematics(反向运动学),子对象的移动可以让父对象受牵连,正常来说是父物体移动,子对象完全的follow。IK 是一种动画技术,主要用于让角色的身体部位(如手、脚)能够自动到达某个目标位置,并自动调整其他相关的骨骼和关节姿势,达到更加自然的动画效果。
IK 的原理
IK 是逆向计算的,给定目标位置(比如角色要触摸的物体),系统会自动计算出骨骼关节的角度和位置,让角色的手或脚自然地到达目标。而传统的 Forward Kinematics(正向运动学,FK) 则是逐个控制每个关节的角度来影响末端的姿势。
- IK(Inverse Kinematics):知道手或脚的目标位置,通过反向计算得出整个手臂或腿部的关节姿态。
- FK(Forward Kinematics):直接控制每个关节的旋转来实现末端的位置控制。
Unity 中的 IK 实现
Unity 提供了内置的 IK 功能,特别是在使用 Animator 控制的角色模型时,比如 Unity 的 Humanoid 角色模型。常见的 IK 控制包括手部和脚部,Unity 中的 Animator 组件可以轻松设置 IK 目标:
- Animator.SetIKPosition 和 Animator.SetIKRotation:用于设置手或脚的目标位置和旋转。
- Animator.SetIKPositionWeight 和 Animator.SetIKRotationWeight:用于设置目标权重值(0 到 1 之间),用于平滑调整到目标。
如何使用 IK
IK听着好像吓人,其实也就是做动画更偷懒的工具
正常来说做动画配状态机,把每个动作的关键帧都要做掉,谁做的下去
帮助把部分整体骨骼的移动控制转移到某个点上,就是IK点
Package找不到也是可能的
可能找不到2D IK,正常
target是帮你生成的对象,只不过立刻关联了,看上去像自己挂的
这个Fabrik Solver就可以反向
反转可以让骨骼正常
换装相关
2D骨骼
psb很方便,美术用ps的可以摆好让我们调整
如果没有看到白色的骨骼,记得点gizmos
上面的两个滑动条,左边的是骨骼的透明度,右边的是权重的颜色表现深度
用算法的算力换取内存,少存一些图片
如果没有橙色边缘线,就双击图片选中
Input.GetAxis
和 Input.GetAxisRaw
在 Unity 中,Input.GetAxis
和 Input.GetAxisRaw
都是用于获取输入轴的值(如水平轴 Horizontal
和垂直轴 Vertical
),但它们在响应方式上有一些不同:
1. 平滑插值(Smoothing)
Input.GetAxis
:返回的值是平滑插值的。换句话说,当你按下某个按键或移动控制杆时,值会逐渐从0
增加到1
或从1
减少到0
。Unity 会为这种输入做插值,使得输入响应更平滑。这对于角色移动、摄像机旋转等需要柔和过渡的操作非常有用。Input.GetAxisRaw
:直接返回输入的原始值(-1
、0
、1
),没有任何插值。适合需要即时反馈的操作,比如快速方向调整或控制射击等对响应时间要求高的场景。
2. 适用场景
Input.GetAxis
:用于平滑输入场景,比如角色缓慢移动、渐变的加速。Input.GetAxisRaw
:用于即时输入场景,比如菜单选择或方向快速切换,避免平滑延迟。
3. 示例代码
假设你的项目中有一个对象需要左右移动:
float speed = 5f;
void Update() { // 使用 GetAxis 实现平滑移动
float moveSmooth = Input.GetAxis("Horizontal") * speed * Time.deltaTime; transform.Translate(moveSmooth, 0, 0); // 使用 GetAxisRaw 实现即时移动
float moveInstant = Input.GetAxisRaw("Horizontal") * speed * Time.deltaTime; transform.Translate(moveInstant, 0, 0); }
- 使用
GetAxis
时,对象移动会有加速和减速的效果。 - 使用
GetAxisRaw
时,对象会立即开始或停止移动。
Input.GetAxisRaw
和 Input.GetAxis
的返回值都是 float
类型,而不是 int
。虽然 Input.GetAxisRaw
的返回值通常是 -1
、0
或 1
,但这些值仍然是 float
类型的,并非整数。
具体返回值
-
Input.GetAxisRaw
返回的值范围在-1
、0
和1
之间,用于表示输入的原始方向状态。例如:- 键盘:当按下 “A” 键时,
Input.GetAxisRaw("Horizontal")
会返回-1.0
(代表向左的方向),按下 “D” 键时返回1.0
(向右的方向)。 - 手柄:控制杆的左右或上下方向会直接返回
-1.0
或1.0
,没有插值。
- 键盘:当按下 “A” 键时,
-
Input.GetAxis
返回-1.0
到1.0
之间的平滑浮点数,用于处理插值输入,因此可能返回任意浮点值。
Animator和Animation
这里强转不存在丢失的问题,因为如果按了移动给的直接就是1和-1
float 类型强转成int,float在animator里不能像int一样可以equal
想要强行使用也是不可以的,除了能在animator窗口里面看上去在动,其他都是不能融合的
调试的跳出,逐过程和逐语句
逐语句调试会按代码的每一行执行,而不会进入被调用的函数内部。
逐过程调试会进入当前执行的函数内部,逐行查看函数内的代码执行。
进入一个函数后,通过“跳出”调试可以执行剩余代码,直接跳回到该函数被调用的地方。
Awake和Start到底什么时候调用
awake是场景上任意的游戏对象,在运行状态时首次被激活会调用的函数
Start则是在该游戏物体处于激活状态,脚本本身第一次被激活的时候调用
awake是对象的激活,start是脚本的第一次激活,也不管别的脚本有没有调自己里面的内容
怎么把电脑正在播放的音频录制下来
下载之后,真相大白,很明显的,
点录制就可以了,不要麦克风声音就在混音器那块把麦克风关了,
还有就是录的默认是视频,如果你只要声音,把录制得到的文件后缀改.mp3就OK了
1. 下载并安装 OBS Studio
确保你已经下载并安装了 OBS Studio。如果没有,可以从 OBS 官方网站 下载并安装。
2. 设置 OBS Studio
-
打开 OBS Studio: 启动 OBS Studio。
-
创建新场景:
- 在左下角的“场景”框中,点击“+”按钮创建一个新场景(例如,命名为“音频录制”)。
-
添加音频源:
- 在下方的“源”框中,点击“+”按钮。
- 选择“音频输出捕捉”(Audio Output Capture)。
- 给音频源命名,然后点击“确定”。
- 在弹出的窗口中,选择你的音频设备(如“立体声混音”或“系统声音”),然后点击“确定”。
-
检查音频设置:
- 在主界面右下角,确保“音量混音器”中的音频源音量调节到适当水平。
3. 开始录制
-
开始录制:
- 在右下角点击“开始录制”按钮。
- 播放你想要录制的音频(例如,音乐、视频等)。
-
停止录制:
- 完成录音后,返回 OBS Studio,点击“停止录制”按钮。
4. 查找录音文件
- 默认情况下,录音文件会保存到 OBS 的默认路径中(通常是在
视频
文件夹下),你可以通过点击“文件” > “显示录制的剪辑”来快速找到录音文件。
5. 检查录音效果
- 播放录制的音频文件,检查录音效果。如果需要,可以根据需要调整 OBS 中的音量和设置。
小贴士
- 使用监控:如果你希望在录制时监听音频,可以右键点击音频源,选择“属性”,然后在“高级”选项中启用音频监控。
- 设置输出格式:在“设置” > “输出”中,你可以调整录音的格式和质量。
blend文件怎么用到unity里
.blend
文件是 Blender 的原生文件格式,包含了3D模型、材质、纹理、动画等信息。要将 .blend
文件导入到 Unity 中,通常可以按照以下步骤操作:
导入到 Unity
Unity 会自动识别并导入放在 Assets
文件夹中的 .blend
文件。你可以在 Unity 编辑器的“项目”窗口中看到它。
使用 Blender 文件
- 拖放使用:将导入的模型从项目窗口拖到场景中。
- 材质与纹理:如果在 Blender 中设置了材质,Unity 会尝试导入这些设置。但可能需要手动调整材质属性,因为 Blender 和 Unity 使用的渲染引擎不同。
动画(可选)
如果你的模型包含动画,确保在 Blender 中正确设置了动画,并在 Unity 中检查动画是否正常工作。
更新模型
如果在 Blender 中对 .blend
文件进行了修改,Unity 会自动更新模型。如果未自动更新,可以尝试右键单击模型并选择“Reimport”。
小贴士
- 使用较新的 Blender 版本,因为 Unity 对
.blend
文件的支持在不同版本中有所不同。 - 如果遇到导入问题,可以考虑将模型导出为更通用的格式,如 FBX 或 OBJ,这些格式在 Unity 中的兼容性更好。
杂
vector的成员方法
push_back(value)
:在末尾添加元素value
。pop_back()
:移除末尾的元素。
不管Object被不被激活,Awake函数都会被执行。这时,我们手动勾选一下Start Awake Test前面的勾选框,结果就和第一幅图一样啦,Start和Update都开始被执行了。
我们知道Unity的Find函数可以根据名字查询到场景中的物体,但是这个物体必须是被激活的,如果我们把这个物体SetActive(false)了,那么这个函数是找不到对应物体的。
Unity中Awake和Start的区别_unity awake和start的区别-CSDN博客
lambda加
using UnityEngine;
using UnityEngine.UI;
public class ButtonHandler : MonoBehaviour
{
public Button myButton;
void Start()
{
myButton.onClick.AddListener(() =>
{
Debug.Log("Button clicked!");
});
}
}
正常加
using UnityEngine;
using UnityEngine.UI;
public class ButtonHandler : MonoBehaviour
{
public Button myButton;
void Start()
{
myButton.onClick.AddListener(OnButtonClick);
}
void OnButtonClick()
{
Debug.Log("Button clicked!");
}
}
雪白明月照在大地z