Input输入
鼠标相关
cs
// 鼠标位置
Vector3 mousePosition = Input.mousePosition; // 0,0,0 原点在左下角,另外屏幕输出坐标是2D坐标
// 鼠标输入 : 0左键 1中键 2右键
// 按下瞬间检测
bool isButtonDown = Input.GetMouseButtonDown(0);
// 抬起瞬间检测
bool isButtonUp = Input.GetMouseButtonUp(0);
// 长按,按下,抬起都会检测
bool isButton = Input.GetMouseButton(0);
// 中键滚动 : Y = -1 下滚, Y = 0 未滚, Y = 1 上滚, X始终0
Vector2 mouseScrollDelta = Input.mouseScrollDelta;
隐藏鼠标相关
cs
public class Lesson2 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
#region 知识点一 隐藏鼠标
// Cursor.visible = true;
#endregion
#region 知识点二 锁定鼠标
// None 就是 不锁定
// Locked 锁定 鼠标会被限制在屏幕的中心点 不仅会被锁定 还会被隐藏 可以通过ESC键 摆脱编辑模式下的锁定
// Confined 限制在窗口范围内
Cursor.lockState = CursorLockMode.Locked;
Cursor.lockState = CursorLockMode.Confined;
#region 知识点三 设置鼠标图片
// 参数一:光标图片
// 参数二:偏移位置 相对图片左上角
// 参数三:平台支持的光标模式(硬件或软件)
Cursor.SetCursor(tex, Vector2.zero, CursorMode.Auto);
#endregion
}
}
设置鼠标为对应图片:
如果要图片大小对应鼠标------需要将光标图片设置一致,保险起见,还要给图片设置Cursor的材质类型
键盘相关
cs
// 键盘输入
bool isKeyDown = Input.GetKeyDown(KeyCode.W); // 按下
bool isKey = Input.GetKey(KeyCode.W); // 长按
bool isKeyUp = Input.GetKeyUp(KeyCode.W); // 抬起
默认轴输入
键盘和鼠标等设备控制玩家移动时,会根据默认轴返回值控制移动
cs
// 键盘AD按下时 返回 -1到1之间的变换
// 相当于 得到得这个值 就是我们的 左右方向 我们可以通过它来控制 对象左右移动 或者左右旋转
float h = Input.GetAxis("Horizontal");
print(h);
// 键盘SW按下时 返回 -1到1之间的变换
// 得到得这个值 就是我们的 上下方向 我们可以通过它来控制 对象上下移动 或者上下旋转
print(Input.GetAxis("Vertical"));
// 鼠标横向移动时 -1 到 1 左 右
print(Input.GetAxis("Mouse X"));
// 鼠标竖向移动时 -1 到 1 下 上
print(Input.GetAxis("Mouse Y"));
这些输入控制可以在ProjectSetting中进行控制

键盘设定相关输入
这一帧的键盘输入是用来改键位的
cs
// 是否有任意键或鼠标长按
if(Input.anyKey)
{
print("有一个键长按");
}
// 是否有任意键或鼠标按下
if(Input.anyKeyDown)
{
print("有一个键 按下");
// 这一帧的键盘输入
print(Input.inputString);
}
手柄输入相关
cs
// 手柄输入相关
// 得到连接的手柄的所有按钮名字
string[] strs = Input.GetJoystickNames();
// 某一个手柄键按下
if (Input.GetButtonDown("Jump"))
{
// ...
}
// 某一个手柄键抬起
if (Input.GetButtonUp("Jump"))
{
// ...
}
// 某一个手柄键长按
if (Input.GetButton("Jump"))
{
// ...
}
移动端输入相关
cs
// 移动设备触摸相关
if (Input.touchCount > 0)
{
Touch t1 = Input.touches[0];
// 位置
print(t1.position);
// 相对上一次位置的变化
print(t1.deltaPosition);
}
// 是否启用多点触控
Input.multiTouchEnabled = false;
csif (Input.touchCount > 0)作用: 判断当前是否有至少一个触摸事件发生。
touchCount 是 Unity 提供的属性,表示屏幕上当前正在触摸的点数(即手指数量)。
条件成立时:进入代码块,开始处理第一个触摸点。
- 用一根手指点击屏幕 →
touchCount = 1- 同时用两根手指点击 →
touchCount = 2
csTouch t1 = Input.touches[0];
- 作用:获取第一个触摸点的信息。
Input.touches是一个Touch[]数组,包含所有当前触摸点的数据。[0]表示取第一个触摸点(通常是最早或最前面的手指)。
csprint(t1.position);
- 作用 :打印当前触摸点在屏幕上的绝对坐标。
position是Vector2类型,表示触摸点在屏幕上的像素位置(以左下角为原点)。- 用途:常用于检测用户点击了哪个 UI 元素,或作为角色移动的目标点。
csprint(t1.deltaPosition); 作用:打印当前触摸点相对于上一帧的位置变化量。 deltaPosition 也是 Vector2 类型,表示本次触摸点移动了多少距离。 用途:非常适合用来实现滑动控制,比如拖动角色、滚动视图、缩放地图等。 (15, -10) 表示手指向右移动了 15 像素,向上移动了 10 像素。
csInput.multiTouchEnabled = false;
- 作用 :禁用多点触控功能。
- 默认值 :
true,允许同时识别多个触摸点。- 设置为
false后 :
- 只能响应单个触摸点
- 即使用户用两只手指触摸屏幕,也只识别第一个触摸点
陀螺仪输入相关
只在 Android/iOS 移动设备上生效
cs
// 陀螺仪(重力感应)
// 是否开启陀螺仪 必须开启 才能正常使用
Input.gyro.enabled = true;
// 重力加速度向量
print(Input.gyro.gravity);
// 旋转速度
print(Input.gyro.rotationRate);
// 陀螺仪 当前的旋转四元数
// 比如 用这个角度信息 来控制 场景上的一个3d物体受到重力影响
// 手机怎么动 它怎么动
print(Input.gyro.attitude);
屏幕相关
较常用的功能:屏幕/分辨率/休眠模式
cs
#region 常用
// 当前屏幕分辨率
// 这里是当前屏幕的分辨率------如果是手机屏幕就是手机屏幕的分辨率,如果是PC屏幕就是PC屏幕的分辨率
Resolution r = Screen.currentResolution;
print("当前屏幕分辨率的宽" + r.width + "高" + r.height);
// 屏幕窗口当前宽高
// 这得到的是当前窗口的宽高 不是设备分辨率的宽高
// 一般写代码 要用窗口宽高 做计算时 就用他们
print(Screen.width);
print(Screen.height);
// 屏幕休眠模式
Screen.sleepTimeout = SleepTimeout.NeverSleep;
#endregion
不太常用的功能:窗口模式/屏幕旋转
cs
// 窗口模式
// 独占全屏 FullScreenMode.ExclusiveFullScreen
// 全屏窗口 FullScreenMode.FullScreenWindow
// 最大化窗口 FullScreenMode.MaximizedWindow
// 窗口模式 FullScreenMode.Windowed
Screen.fullScreenMode = FullScreenMode.Windowed;
// 移动设备屏幕转向相关
// 允许自动旋转到左横向 Home键在左
Screen.autorotateToLandscapeLeft = true;
// 允许自动旋转到右横向 Home键在右
Screen.autorotateToLandscapeRight = true;
// 允许自动旋转到纵向 Home键在下
Screen.autorotateToPortrait = true;
// 允许自动旋转到纵向倒着看 Home键在上
Screen.autorotateToPortraitUpsideDown = true;
屏幕转向具体示例

Camera相关
摄像机渲染相关

Culing Mask中取消勾选某个层级的对象,如果场景中的对象恰好是这个层级,那么在Game页面中不会显示该层级。
摄像机模式相关


其他常用摄像机功能分支

1、Cliping Planes是按照距离裁剪模型------有时候模型渲染残缺可能就是这个问题导致的
2、Depth是摄像机渲染深度
Depth越大越后渲染,然后越后渲染的覆盖在越先渲染的
而如果给摄像机设置Depth Only
另外,就算其他摄像机能渲染出物体,但是因为这个摄像机层级Depth最大,不渲染任何物体的效果会覆盖其他效果
3、TargetTexture
有点类似Su中的一个场景视角备份------一般用于制作地图?
先用一个摄像机摆放好角度
将该Textture拖拽进入该视角的摄像机------对该视角的场景已经备份了
4、剔除遮挡:就是摄像机渲染时,如果模型遮挡
5、viewport Rect
一般用于多个摄像机视图的游戏,比如双人成行!
摄像机代码相关参数
摄像机的获取
cs
// 1. 获取摄像机
// 如果用之前的知识 来获取摄像机
// 主摄像机的获取
// 如果想通过这种方式 快速获取摄像机 那么场景上必须有一个 tag为MainCamera的摄像机
print(Camera.main.name);
// 获取摄像机的数量
print(Camera.allCamerasCount);
// 得到所有摄像机
Camera[] allCamera = Camera.allCameras;
print(allCamera.Length);
cs
#region 知识点二 重要成员
// 1. 界面上的参数 都可以在Camera中获取到
// 比如 下面这句代码 就是得到主摄像机对象 上的深度 进行设置
Camera.main.depth = 10;
// 2. 世界坐标转屏幕坐标
// 转换过后 x和y对应的 就是屏幕坐标 z对应的 是 这个3d物体 里我们的摄像机有多远
Vector3 v = Camera.main.WorldToScreenPoint(this.transform.position);
print(v);
#endregion
void Update()
{
// 3. 屏幕坐标转世界坐标
print(Input.mousePosition);
print(Camera.main.ScreenToWorldPoint(Input.mousePosition));
}
世界坐标 转 屏幕坐标Vector3
屏幕坐标 转 世界坐标Vector3: z表示纵深距离,类似横切面
**需要注意的是:**屏幕坐标转换成世界坐标时,Z轴会自动设置为0------即摄像机的出发点,此时物体无法被渲染------所以需要在代码中手动设置!
光源
几大光源类型


面光源单独讲解
光源模式

实时光源(Realtime Light)
- 定义:在游戏运行时每帧实时计算光照效果的光源。
- 特点 :
- 光照会随着物体移动、光源变化而动态更新
- 支持阴影、反射等复杂效果
- 性能消耗大,适合需要动态交互的场景
烘焙光源(Baked Light)
- 定义:在编辑器中预先计算好光照信息,并保存为光照贴图(Lightmap),运行时直接读取。
- 特点 :
- 光照是静态的,无法动态改变
- 性能极佳,适合静态环境
- 适用于建筑、室内等不常变动的场景

阴影模式

投影遮罩Cookie

球形光晕效果Draw Halo

环境光的整体设置



碰撞检测
Rigidbody 刚体
两个物体相互碰撞必要条件:1.都有碰撞器 2.至少一个拥有刚体
刚体类似于模拟物理------有了刚体相当于有了可以施加力的对象


1、Drag是影响物体位移的空气阻力,Angular Drag是影响物体旋转的空气阻力
2、Is Kinematic 是禁用当前刚体,让Tranfrom接管物理运动
3、差值运算相关
物理帧更新直接影响着物体运动表现------当物理帧过大时,物体运动更新表现会些许卡顿


4、约束的作用
哪个物体的刚体约束了哪个轴的位移和旋转,该物体发生碰撞后就不会在此轴上发生运动

连续碰撞检测
位移是每帧更新的,如果两个物体间,一个物体的帧位移太大,到达第二个目标位置时就会穿过物体------所以我们引入了连续碰撞检测的概念
各种检测方式

使用场景推荐
| 模式 | 何时用 | 是否推荐 |
|---|---|---|
| Discrete | 普通移动、静态物体 | ✅ 推荐,默认 |
| Continuous | 高速物体 vs 静态环境 | ✅ 推荐,防穿墙 |
| Continuous Dynamic | 动态物体间高速碰撞 | ⚠️ 仅必要时用 |
| Continuous Speculative | 中高速 + 性能敏感 | ✅ 推荐,平衡方案 |
碰撞器相关
几个碰撞器种类
如下是比较常用的碰撞器以及控制它们的相关参数

一些复杂的物体,其碰撞器是多个碰撞器混合在一起组合
触发器

如果玩家被剑攻击,这两个物体不会被弹开,所以会设置成触发器检测玩家是否被剑命中即可。
物理材质
新建物理材质后,将该材质添加到Material中


碰撞器函数相关
这是碰撞器相关函数
cs
// 碰撞开始时调用
private void OnCollisionEnter(Collision other) {
// 碰撞对象
GameObject gameObject = other.gameObject;
// 碰撞对象的碰撞器
Collider collider = other.collider;
// 碰撞对象的位置
Transform transform = other.transform;
}
// 重叠过程中调用,需要产生摩擦
private void OnCollisionStay(Collision other) {
}
// 碰撞结束时调用
private void OnCollisionExit(Collision other) {
}
1、OnCollisionEnter是两个物体刚接触
2、OnCollisionStay是两个物体一直在接触
3、OnCollisionExit是两个物体接触结束
触发器函数
cs
// 触发开始时调用
private void OnTriggerEnter(Collider other) {
}
// 触发重叠时调用
private void OnTriggerStay(Collider other) {
}
// 触发结束时调用
private void OnTriggerExit(Collider other) {
}
如上六种碰撞器函数------只要挂载的对象能和别的物体产生碰撞和触发,那么这六个函数都能被响应。
异形物体的碰撞器

父级物体上有刚体且挂载碰撞器脚本,子级物体也上有碰撞器才可以触发碰撞效果相关函数
给刚体添加力
方法
获取刚体组件
cs
Rigidbody rigidBody = this.gameObject.GetComponent<Rigidbody>();
添加水平力
cs
// 1.相对世界坐标
rigidBody.AddForce(Vector3.forward); // 朝世界坐标 0 0 1 方向施加力
// 2.相对本地坐标
rigidBody.AddRelativeForce(Vector3.forward); // 朝面朝向施加力
即物体水平移动的力------加了力后,是否停下是由阻力决定的
添加扭矩力
cs
// 1.相对世界坐标
rigidBody.AddTorque(Vector3.up);
// 2.相对本地坐标
rigidBody.AddRelativeTorque(Vector3.up);

直接改变速度
cs
rigidBody.velocity = Vector3.forward; // 相对世界坐标
给世界坐标添加爆炸力
cs
float forceValue = 100;
float radius = 10;
Vector3 point = Vector3.zero;
//三个参数按照顺序依次是(施加力的大小,坐标点,半径)
rigidBody.AddExplosionForce(forceValue,point,radius); // 只对rigibody调用的刚体起作用

- 爆炸力只影响调用该方法的刚体对象
- 不是全局效果,需要每个对象单独调用
力的模式
cs
//第二个参数是力的模式,主要方式是计算方式不同,最终移动速度不同
rigidBody.AddForce(Vector3.forward * 10, ForceMode.Acceleration);

|------------|----------------------------------------|
| 角色移动、玩家控制 | Acceleration 或 VelocityChange(更稳定) |
| 物理模拟(如推箱子) | Force(体现质量差异) |
| 瞬时冲击(如爆炸) | Impulse |
| 直接控制速度 | VelocityChange |
具体的速度
cs
Acceleration
给物体增加一个持续的加速度,忽略其质量
v = Ft/m
F: (0,0,10)
t: 0.02s
m: 默认为1
v = 10*0.02 / 1 = 0.2m/s
每物理帧移动 0.2m/s * 0.02 = 0.004m
Force
给物体添加一个持续的力,与物体的质量有关
v = Ft/m
F: (0,0,10)
t: 0.02s
m: 2kg
v = 10*0.02 / 2 = 0.1m/s
每物理帧移动 0.1m/s * 0.02 = 0.002m
Impulse
给物体添加一个瞬间的力,与物体的质量有关,忽略时间 默认为1
v = Ft/m
F: (0,0,10)
t: 默认为1
m: 2kg
v = 10*1 / 2 = 5m/s
每物理帧移动 5m/s * 0.02 = 0.1m
VelocityChange
给物体添加一个瞬时速度,忽略质量
v = Ft/m
F: (0,0,10)
t: 默认为1
m: 默认为1
v = 10*1 / 1 = 10m/s
每物理帧移动 10m/s * 0.02 = 0.2m
力场组件

| 参数 | 类型 | 坐标系 | 是否随物体旋转 | 典型用途 |
|---|---|---|---|---|
| Force | 线性力 | 世界坐标 | ❌ 否 | 推进、重力、牵引 |
| Relative Force | 线性力 | 局部坐标 | ✅ 是 | 飞船引擎、车辆动力 |
| Torque | 旋转力 | 世界坐标 | ❌ 否 | 固定轴旋转、陀螺 |
| Relative Torque | 旋转力 | 局部坐标 | ✅ 是 | 姿态控制、轮子转动 |
刚体休眠
- 性能优化机制: Unity为了节约性能,会给刚体添加休眠机制,在特定情况下会停止计算
- 休眠表现: 刚体停止运动后,即使碰撞体位置发生变化,刚体也不会响应
- 触发条件: 当刚体静止一段时间后,Unity会自动将其设为休眠状态
立方体会自然下落停在平面上
- 异常现象:
- 当旋转平面改变角度时,立方体不会重新下落
- 但移动平面位置时,立方体会响应下落
- 原因分析: 刚体进入休眠状态后,仅对某些变化(如位置移动)有反应
cs
// 获取刚体是否休眠
if (rigidBody.IsSleeping())
{
rigidBody.WakeUp(); // 唤醒
}
刚体被唤醒的代码
音频相关
Unity音频常用文件格式



音频源相关脚本

音频源相关参数如下:

Play On Awake
- 功能:对象创建时自动播放音频。
- 应用场景 :
- 背景音乐建议开启。
- 音效(如跳跃、爆炸)通常应通过代码控制,不建议勾选。
- 示例:取消勾选后运行游戏,音效将不会自动播放。
Loop
- 功能:启用后音频会循环播放。
- 典型应用:背景音乐必须开启此选项以实现无缝循环。
- 注意:非循环音效在播放完毕后会自动停止。
Priority(优先级)
- 取值范围:0(最高优先级)~ 256(最低优先级)
- 作用 :当系统资源不足、多个音频同时播放时,优先级高的音频更不容易被强制停止。
- 默认值:128(中等优先级)
Volume(音量)
- 取值范围:0.0(静音)~ 1.0(最大音量)
- 调整效果:实时控制音频播放的响度。
- 示例 :设为
0.3时,音量明显降低,适合远距离或背景音效。
Pitch(音高)
- 功能:改变音频的播放速度与音调。
- 数值影响 :
- > 1.0:播放加快,声音变尖(如"加速"效果)
- < 1.0:播放变慢,声音低沉(如"慢动作"氛围)
- 典型应用 :
- 游戏时间加速/减速时动态调整。
- 制作卡通化音效(如角色变大/变小)。
音效设置

1、一般用2D音效,3D音效是将音效作为物体放在游戏场景中------当玩家离这个音频源物体的距离变化而导致物体音效大小。

这是音频接收器的对象------主要是看这个挂载对象和接受对象的距离,然后播放音效效果。
2、多普勒效果和扩散角度都是默认设置的
音效源相关脚本
1、代码控制音效的播放停止
cs
void start()
{
audioSource=this.getCompoent<AudioSource>();
}
void Update()
{
#region 知识点一 代码控制播放停止
if (Input.GetKeyDown(KeyCode.P))
{
//播放音效
audioSource.Play();
//延迟播放
audioSource.PlayDelayed(5)
}
if (Input.GetKeyDown(KeyCode.S))
{
//停止音效
audioSource.Stop();
}
if (Input.GetKeyDown(KeyCode.Space))
{
//暂停音效
audioSource.Pause();
}
#endregion
}
2、检测音效是否播放完毕
cs
void Update()
{
#region 知识点二 如何检测音效播放完毕
// 如果你希望某一个音效播放完毕后,想要做什么事情
// 那就可以在 Update 生命周期函数中,不停的去检测它的 isPlaying 属性
// 如果是 false 就代表播放完毕了
if (audioSource.isPlaying)
{
print("播放中");
}
else
{
print("播放结束");
}
#endregion
}
动态播放音效的方法
cs
#region 知识点三 如何动态控制音效播放
1. 直接在要播放音效的对象上挂载脚本 控制播放
2. 实例化挂载了音效源脚本的对象
这种方法 其实用的比较少
Instantiate(obj);
3. 用一个AudioSource来控制播放不同的音效
AudioSource aus = this.gameObject.AddComponent<AudioSource>();
aus.clip = clip;
aus.Play();
// 潜在知识点
// 一个GameObject可以挂载多个音效源脚本AudioSource
// 使用时要注意 如果要挂载多个 那一定要自己管理他们 控制他们的播放 停止 不然 我们没有办法准确的获取 谁是谁
#endregion















