Input/屏幕/Camera/光源/碰撞检测/音频相关

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;
cs 复制代码
if (Input.touchCount > 0)

作用: 判断当前是否有至少一个触摸事件发生。

touchCount 是 Unity 提供的属性,表示屏幕上当前正在触摸的点数(即手指数量)。

条件成立时:进入代码块,开始处理第一个触摸点。

  • 用一根手指点击屏幕 → touchCount = 1
  • 同时用两根手指点击 → touchCount = 2
cs 复制代码
Touch t1 = Input.touches[0];
  • 作用:获取第一个触摸点的信息。
  • Input.touches 是一个 Touch[] 数组,包含所有当前触摸点的数据。
  • [0] 表示取第一个触摸点(通常是最早或最前面的手指)。
cs 复制代码
print(t1.position);
  • 作用 :打印当前触摸点在屏幕上的绝对坐标
  • positionVector2 类型,表示触摸点在屏幕上的像素位置(以左下角为原点)。
  • 用途:常用于检测用户点击了哪个 UI 元素,或作为角色移动的目标点。
cs 复制代码
print(t1.deltaPosition);
作用:打印当前触摸点相对于上一帧的位置变化量。
deltaPosition 也是 Vector2 类型,表示本次触摸点移动了多少距离。
用途:非常适合用来实现滑动控制,比如拖动角色、滚动视图、缩放地图等。

(15, -10)
表示手指向右移动了 15 像素,向上移动了 10 像素。
cs 复制代码
Input.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);

|------------|----------------------------------------|
| 角色移动、玩家控制 | AccelerationVelocityChange(更稳定) |
| 物理模拟(如推箱子) | 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
相关推荐
醉风塘2 小时前
完美升级!将ElTree生硬文本提示替换为优雅的ElEmpty组件
javascript·vue.js·elementui
云游云记2 小时前
php性能优化总结
开发语言·性能优化·php
独自破碎E2 小时前
【滑动窗口】最小覆盖子串
java·开发语言
fengfuyao9852 小时前
C#实现指纹识别
开发语言·c#
开发者小天2 小时前
python中的Dictionaries
android·开发语言·python
假女吖☌2 小时前
Lua 脚本
开发语言·lua
今天多喝热水2 小时前
Lua脚本实现滑动窗口
java·开发语言·lua
没有bug.的程序员2 小时前
Spring Cloud Gateway:API网关限流与熔断实战
java·开发语言·数据库·spring boot·gateway·api·springcloud
爱学习的阿磊2 小时前
C++代码动态分析
开发语言·c++·算法