Unity知识点入门、基础、核心、进阶

知识点来源:总结人间自有韬哥在唐老狮,豆包

目录

一、Unity入门

1 生命周期函数和打印信息

1.1. 生命周期函数详解

函数名调用时机用途
Awake对象(脚本类对象)被创建时调用类似构造函数,可进行对象创建时的初始化操作
OnEnable对象被激活时调用可在此处编写对象激活时的逻辑处理代码,运行游戏时,因脚本挂载对象默认激活,会自动调用一次
Start对象进行第一次帧更新之前执行用于编写初始化信息的逻辑,执行时间比 Awake
FixedUpdate每一物理帧执行主要用于进行物理更新,物理帧和游戏帧不同
Update每一游戏帧执行用于处理游戏核心逻辑更新
LateUpdateUpdate 晚执行一般用于处理摄像机位置更新相关内容
OnDisable对象失活时调用可在此处编写对象失活时的处理逻辑
OnDestroy对象被销毁时调用销毁对象时调用,调用前对象失活,也会调用一次 OnDisable

1.2. 在 Unity 中打印信息

方法用途
DebugLog 方法打印普通信息,如 Debug.Log("Awake Debug.Log");
DebugLogWarning 方法打印警告信息,如 Debug.LogWarning("Awake Debug.LogWarning");
DebugLogError 方法打印报错信息,如 Debug.LogError("Awake Debug.LogError");
MonoBehaviourprint 方法继承 MonoBehaviour 类时,可使用该方法打印普通信息,如 print("Awake print");

2 Unity 特性

2.1变量可见性控制

特性作用适用变量语法关键说明
[SerializeField]强制私有/保护变量显示在 Inspectorprivate/protected 变量[SerializeField] private int value;- 序列化字段,支持基本类型、数组、GameObject
- 运行时修改会影响成员变量
[HideInInspector]隐藏公共变量(避免误操作)public 变量[HideInInspector] public int value;- 代码中可访问,但 Inspector 不显示
默认公共变量直接显示(无需特性)public 变量public int value;- 简单直接,但暴露所有公共字段

2.2.自定义类型序列化

类型显示条件示例关键说明
枚举直接显示(无需额外特性)public E_TestEnum enumValue;- 下拉菜单选择枚举值
结构体[System.Serializable] 特性[Serializable] public struct MyStruct{...}- 序列化后可展开编辑字段
[System.Serializable] 特性 + 继承 UnityEngine.Object 或标记为 [CreateAssetMenu][Serializable] public class MyClass{...}- 非 MonoBehaviour 需手动序列化
- ScriptableObject[CreateAssetMenu]
集合直接显示(数组、List<T>public int[] array;
public List<int> list;
- 支持动态添加/删除元素(List需初始化)

2.3辅助特性(提升可读性)

特性作用参数示例
[Header("标题")]分组标题(字段上方显示)字符串(如 "基础属性"[Header("战斗属性")] public int atk;
[Tooltip("提示")]悬停提示(鼠标悬停显示说明)字符串(如 "最大生命值"[Tooltip("闪避率")] public float miss;
[Space(像素)]字段间隔(垂直空白)可选像素值(默认 10)[Space(20)] public int crit;
[Range(Min, Max)]数值滑条(限制输入范围)最小值,最大值(如 0, 100[Range(0, 10)] public float luck;
[Multiline(行数)]多行文本框(固定行数)可选行数(默认 3)[Multiline(5)] public string tips;
[TextArea(Min, Max)]滚动文本框(超过最大行数显示滚动条)最小行数,最大行数(如 3, 5[TextArea(3, 4)] public string desc;

2.4交互增强特性

特性作用参数示例
[ContextMenuItem("按钮名", "方法")]为变量添加右键快捷方法(无参无返回)按钮文本,方法名[ContextMenuItem("重置", "ResetMoney")] public int money;
[ContextMenu("按钮名")]为方法添加 Inspector 执行按钮(非静态无参)按钮文本[ContextMenu("测试逻辑")] private void Test();

3.基础属性和组件的获取

3.1. 重要成员

成员说明示例
gameObject获取脚本依附的 GameObjectprint(gameObject.name);
transform获取 GameObject 的位置信息print(transform.position);
enabled获取或设置脚本激活状态this.enabled = false;

3.2. 重要方法

方法作用参数示例
GetComponent获取单个挂载脚本可按脚本名、Type、泛型获取var script = GetComponent<MyScript>();
GetComponents获取多个挂载脚本泛型var scripts = GetComponents<MyScript>();
GetComponentInChildren获取子对象(含自身)挂载的单个脚本bool:是否查找失活子对象,默认 falsevar childScript = GetComponentInChildren<MyScript>(true);
GetComponentsInChildren获取子对象(含自身)挂载的多个脚本bool:是否查找失活子对象,默认 false
可传入 List 接收结果
GetComponentsInChildren<MyScript>(true, list);
GetComponentInParent获取父对象(含自身)挂载的单个脚本var parentScript = GetComponentInParent<MyScript>();
GetComponentsInParent获取父对象(含自身)挂载的多个脚本var parentScripts = GetComponentsInParent<MyScript>();
TryGetComponent安全获取单个脚本泛型,使用 out 输出结果if (TryGetComponent<MyScript>(out var script)) { ... }

4.GameObject游戏对象

4.1. GameObject 成员变量

变量说明示例
name对象名称print(gameObject.name); gameObject.name = "新名称";
activeSelf对象是否激活print(gameObject.activeSelf);
isStatic对象是否为静态对象print(gameObject.isStatic);
layer对象的层级print(gameObject.layer);
tag对象的标签print(gameObject.tag);
transform对象的位置、旋转和缩放信息print(gameObject.transform.position);

4.2. GameObject 静态方法

方法作用注意事项示例
CreatePrimitive创建带原始网格渲染器和碰撞体的游戏对象GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
Find通过对象名查找单个激活对象效率低,找不到返回 null,无法找失活对象,多匹配时不确定找到哪个GameObject obj = GameObject.Find("对象名");
FindWithTag/FindGameObjectWithTag通过标签查找单个激活对象找不到返回 null,无法找失活对象GameObject obj = GameObject.FindWithTag("标签名");
FindGameObjectsWithTag通过标签查找多个激活对象找不到返回空数组,无法找失活对象GameObject[] objs = GameObject.FindGameObjectsWithTag("标签名");
FindObjectOfType找到场景中挂载某脚本的对象效率低,不仅遍历对象还遍历脚本,找不到返回 nullvar scriptObj = GameObject.FindObjectOfType<MyScript>();
Instantiate实例化(克隆)对象GameObject clone = GameObject.Instantiate(original);
Destroy删除对象异步,下一帧移除对象,建议优先使用GameObject.Destroy(obj, 5); // 5 秒后删除
DestroyImmediate立即删除对象可能造成卡顿GameObject.DestroyImmediate(obj);
DontDestroyOnLoad过场景不移除对象GameObject.DontDestroyOnLoad(obj);

4.3. GameObject 成员方法

方法作用示例
构造函数创建空物体GameObject obj = new GameObject("物体名", typeof(脚本1), typeof(脚本2));
AddComponent为对象添加脚本var script = obj.AddComponent<MyScript>();
GetComponent得到对象的脚本var script = obj.GetComponent<MyScript>();
CompareTag标签比较if (gameObject.CompareTag("标签名")) { ... }
SetActive设置对象激活失活obj.SetActive(false);

4.4. 次要成员方法(不建议使用,效率低)

方法作用示例
SendMessage广播自己执行方法gameObject.SendMessage("方法名", 参数);
BroadcastMessage广播自己和所有子对象执行方法gameObject.BroadcastMessage("方法名");
SendMessageUpwards广播自己和所有父对象执行方法gameObject.SendMessageUpwards("方法名");

5.Time时间

分类变量说明受 timeScale 影响使用场景示例代码
时间缩放比例timeScale控制时间流逝的标度,可用于慢动作、暂停等效果。默认值为 1-实现游戏的暂停、倍速等功能Time.timeScale = 0; // 时间停止
Time.timeScale = 2; // 2 倍速
普通帧间隔时间
(Update 内使用)
deltaTime完成上一帧所用的时间(秒)希望游戏暂停时物体停止移动的位移计算print("帧间隔时间: " + Time.deltaTime);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
unscaledDeltaTime从上一帧到当前帧独立于 timeScale 的时间间隔(秒)希望不受暂停影响的位移计算print("不受 scale 影响的帧间隔时间: " + Time.unscaledDeltaTime);
transform.Translate(Vector3.forward * speed * Time.unscaledDeltaTime);
游戏开始到现在的时间time该帧开始的时间,自游戏启动以来受 timeScale 影响的时间(秒)受时间缩放影响的计时功能print("受 scale 影响的游戏开始到现在的时间: " + Time.time);
unscaledTime该帧独立于 timeScale 的时间,自游戏启动以来的时间(秒)不受时间缩放影响的计时功能print("不受 scale 影响的游戏开始到现在的时间: " + Time.unscaledTime);
物理帧间隔时间
(FixedUpdate 内使用)
fixedDeltaTime执行物理和其他固定帧率更新的时间间隔(秒)物理模拟相关的计算print("受 scale 影响的物理帧间隔时间: " + Time.fixedDeltaTime);
fixedUnscaledDeltaTime从上一个固定帧到当前固定帧独立于 timeScale 的时间间隔(秒)不受时间缩放影响的物理模拟计算print("不受 scale 影响的物理帧间隔时间: " + Time.fixedUnscaledDeltaTime);
帧数frameCount从游戏开始到现在运行的总帧数帧同步、帧率统计等print("从开始到现在游戏跑了 " + Time.frameCount + " 帧");

6.Transform

6.1. Transform 概述

Transform 主要用于游戏对象(GameObject)的位移、旋转、缩放、父子关系、坐标转换等相关操作。

6.2. Vector3 三维向量

分类说明示例
申明方式无参构造后赋值;传 xy 坐标参数的构造(默认 z 是 0);传 xyz 坐标参数的参数构造;结构体直接声明后赋值Vector3 v1 = new Vector3(); v1.x = 10; v1.y = 10; v1.z = 10;
Vector3 v2 = new Vector3(10, 10);
Vector3 v3 = new Vector3(10, 10, 10);
Vector3 v4; v4.x = 10; v4.y = 10; v4.z = 10;
基本计算支持 +、 -、 *、 / 运算Vector3 v11 = new Vector3(1, 1, 1); Vector3 v12 = new Vector3(2, 2, 2);
print(v11 + v12); // (3.0, 3.0, 3.0)
常用向量提供如 Vector3.zeroVector3.right 等常用向量print(Vector3.zero); // (0, 0, 0)
距离计算Distance 方法返回向量之间的距离print(Vector3.Distance(v11, v12)); // 1.732051

6.3. 位置

变量说明注意事项示例
position相对世界坐标系的坐标不能单独修改 xyz,只能整体赋值;若父对象不在原点,与面板显示可能不同print(this.transform.position);
this.transform.position = new Vector3(10, 10, 10);
localPosition相对父对象的坐标若想以面板坐标为准设置位置,使用此变量print(this.transform.localPosition);
this.transform.localPosition = Vector3.up * 10;

6.4. 朝向

可通过 transform.forwardtransform.uptransform.right 得到对象当前的面朝向、头顶朝向、右手边朝向。

6.5. 位移

方式说明示例
手动计算路程 = 方向 * 速度 * 时间,一般放在 Updatethis.transform.position += this.transform.forward * 1 * Time.deltaTime;
Translate 方法根据 translation 的方向和距离移动变换,可指定相对坐标系this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.World);

6.6. 角度和旋转

分类变量/方法说明注意事项示例
角度rotation返回旋转的四元数-print(this.transform.rotation);
eulerAngles相对世界坐标角度不能单独设置 xyz,要用 Vector3 赋值print(this.transform.eulerAngles);
this.transform.eulerAngles = new Vector3(10, 10, 10);
localEulerAngles相对父对象角度若想改变面板显示角度,使用此变量print(this.transform.localEulerAngles);
this.transform.localEulerAngles = new Vector3(10, 10, 10);
旋转Rotate 方法自转,有多种重载方式一般放在 Updatethis.transform.Rotate(new Vector3(0, 100, 0) * Time.deltaTime);
this.transform.Rotate(Vector3.right, 10 * Time.deltaTime, Space.World);
RotateAround 方法相对于某一个点转-this.transform.RotateAround(Vector3.zero, Vector3.right, 10 * Time.deltaTime);

6.7. 缩放

变量说明注意事项示例
lossyScale相对世界坐标系的缩放大小(只读)只能获取,不能改变print(this.transform.lossyScale);
localScale相对本地坐标系(父对象)的缩放大小一般修改此变量,不能只改 xyz,用 Vector3 向量一起改print(this.transform.localScale);
this.transform.localScale += Vector3.one * Time.deltaTime;

6.8. 看向

LookAt 方法可让一个对象的面朝向某一个点或者某一个对象,一般写在 Update 内以持续更新。

示例说明
this.transform.LookAt(Vector3.zero);看向一个点,相对于世界坐标系
this.transform.LookAt(lookAtObj);看向一个对象,传入对象的 Transform 信息

6.9. 父子关系

操作变量/方法说明示例
获取父对象parent 变量获取父对象,返回父对象的 transformprint(this.transform.parent);
print(this.transform.parent.name);
设置父对象parent 变量可用于断绝父子关系或设置新的父对象this.transform.parent = null;
this.transform.parent = GameObject.Find("Father2").transform;
SetParent 方法可指定是否保留世界坐标的位置、角度、缩放信息this.transform.SetParent(null);
this.transform.SetParent(GameObject.Find("Father2").transform);
this.transform.SetParent(GameObject.Find("Father3").transform, false);
断绝子对象关系DetachChildren 方法断绝与所有子对象的关系,不影响子对象间关系this.transform.DetachChildren();
获取子对象Find 方法按名字查找儿子,能找到失活对象,只能找儿子print(this.transform.Find("Cube (1)").name);
childCount 变量得到有多少个儿子,失活儿子也算print(this.transform.childCount);
GetChild 方法遍历所有儿子for (int i = 0; i < this.transform.childCount; i++) { print("儿子的名字:" + this.transform.GetChild(i).name); }
儿子操作IsChildOf 方法判断自己是否为某对象的子项if (son.IsChildOf(this.transform)) { print("是我的儿子"); }
GetSiblingIndex 方法得到自己作为儿子的编号print(son.GetSiblingIndex());
SetAsFirstSibling 方法把自己设置为第一个儿子son.SetAsFirstSibling();
SetAsLastSibling 方法把自己设置为最后一个儿子son.SetAsLastSibling();
SetSiblingIndex 方法把自己设置为指定个儿子,超出范围会设置为最后一个编号son.SetSiblingIndex(1);

6.10. 坐标转换

转换类型方法说明示例
世界坐标转本地坐标InverseTransformPoint 方法世界坐标系的点转换为相对本地坐标系的点print("转换后的点 " + this.transform.InverseTransformPoint(Vector3.forward));
InverseTransformDirection 方法世界坐标系的方向转换为相对本地坐标系的方向(不受缩放影响)print("转换后的方向(不受缩放影响)" + this.transform.InverseTransformDirection(Vector3.forward));
InverseTransformVector 方法世界坐标系的方向转换为相对本地坐标系的方向(受缩放影响)print("转换后的方向(受缩放影响)" + this.transform.InverseTransformVector(Vector3.forward));
本地坐标转世界坐标TransformPoint 方法本地坐标系的点转换为相对世界坐标系的点(受缩放影响)print("本地 转 世界 点" + this.transform.TransformPoint(Vector3.forward));
TransformDirection 方法本地坐标系的方向转换为相对世界坐标系的方向(不受缩放影响)print("本地 转 世界 方向" + this.transform.TransformDirection(Vector3.forward));
TransformVector 方法本地坐标系的方向转换为相对世界坐标系的方向(受缩放影响)print("本地 转 世界 方向" + this.transform.TransformVector(Vector3.forward));

7.Input 组件

7.1.鼠标输入(Update 中使用)

方法/属性说明参数/返回值示例注意事项
mousePosition鼠标屏幕坐标(左下角为原点,z=0)Vector3(x,y 像素坐标)print(Input.mousePosition);屏幕坐标系:x 右,y 上,z=0
GetMouseButtonDown(0/1/2)鼠标按键按下瞬间(0=左,1=右,2=中)int 键索引,返回 boolif (Input.GetMouseButtonDown(0)) 射击();仅按下帧触发一次
GetMouseButtonUp(0/1/2)鼠标按键抬起瞬间int 键索引,返回 boolif (Input.GetMouseButtonUp(1)) 取消();仅抬起帧触发一次
GetMouseButton(0/1/2)鼠标按键长按(持续触发)int 键索引,返回 boolif (Input.GetMouseButton(2)) 旋转();按住期间每帧触发
mouseScrollDelta鼠标滚轮滚动量(y 轴为主)Vector2(y=-1 下滚,y=1 上滚)float scroll = Input.mouseScrollDelta.y;滚轮滚动时触发,非持续

7.2.键盘输入(Update 中使用)

方法/属性说明参数/返回值示例注意事项
GetKeyDown(KeyCode.W)键盘按下瞬间(枚举或小写字符串)KeyCode 枚举或 "w" 字符串,返回 boolif (Input.GetKeyDown(KeyCode.Space)) 跳跃();枚举大写(如 KeyCode.W),字符串小写(如 "w"
GetKeyUp(KeyCode.W)键盘抬起瞬间KeyCode,返回 boolif (Input.GetKeyUp("q")) 换弹();仅抬起帧触发一次
GetKey(KeyCode.W)键盘长按(持续触发)KeyCode,返回 boolif (Input.GetKey(KeyCode.LeftShift)) 加速();按住期间每帧触发
inputString按下的键盘字符(如字母、数字)string(只读)if (Input.anyKeyDown) print(Input.inputString);仅在 anyKeyDown 帧有效
anyKeyDown任意键/鼠标按下瞬间bool(只读)if (Input.anyKeyDown) 开始游戏();包括鼠标和键盘

7.3虚拟轴输入(控制移动/旋转)

方法说明返回值范围默认轴示例适用场景
GetAxis("Horizontal")平滑轴(渐变值,-1~1)float(如 -0.5, 0.8)Horizontal(A/D 或 左摇杆)transform.Translate(Vector3.right * Input.GetAxis("Horizontal"));角色移动、镜头旋转
GetAxisRaw("Vertical")离散轴(仅 -1/0/1)float(-1/0/1)Vertical(W/S 或 上摇杆)if (Input.GetAxisRaw("Fire1") > 0) 开火();技能触发、跳跃(避免渐变延迟)
GetAxis("Mouse X/Y")鼠标移动增量(屏幕像素速度)float(-1~1)Mouse X(鼠标左右)camera.Rotate(0, Input.GetAxis("Mouse X"), 0);镜头旋转

7.4触摸输入(移动设备)

方法/属性说明示例注意事项
touchCount当前触摸点数(只读)if (Input.touchCount >= 2) 缩放();需开启 Edit > Project Settings > Input Manager > Multi Touch
touches[0].position第 0 个触摸点屏幕坐标Vector2 pos = Input.touches[0].position;触摸点索引从 0 开始
touches[0].deltaPosition触摸点相对上次位置的偏移量Vector2 delta = Input.touches[0].deltaPosition;用于滑动控制(如移动角色)
multiTouchEnabled是否启用多点触控Input.multiTouchEnabled = true;默认为 true,禁用后仅识别第一个触摸点

7.5.手柄/虚拟按钮

方法说明参数示例配置
GetButtonDown("Jump")手柄按钮按下瞬间(对应 Input Manager 中虚拟按钮)string 按钮名(如 “Jump”)if (Input.GetButtonDown("Jump")) 跳跃();Edit > Project Settings > Input Manager 中配置
GetButton("Fire")手柄按钮长按string 按钮名if (Input.GetButton("Fire")) 持续射击();支持键盘/手柄映射

7.6.重力感应(陀螺仪)

属性说明示例注意事项
gyro.enabled启用陀螺仪(需先开启)Input.gyro.enabled = true;移动设备专属,PC 需模拟
gyro.gravity重力加速度向量(世界坐标系)Vector3 gravity = Input.gyro.gravity;手机倾斜时返回重力方向(如平放时 (0, -1, 0))
gyro.rotationRate旋转角速度(弧度/秒)float rotation = Input.gyro.rotationRate.z;手机旋转时的角速度

8.Screen屏幕

分类变量/方法说明示例注意事项
静态属性(常用)currentResolution当前屏幕分辨率,返回 Resolution 类对象Resolution resolution = Screen.currentResolution;得到的是当前显示器的分辨率,不是 Game 窗口的
widthheightGame 窗口当前宽高print("Game窗口的当前宽度" + Screen.width);
print("Game窗口的当前高度" + Screen.height);
用于代码中用 Game 窗口宽高做计算
sleepTimeout屏幕休眠模式Screen.sleepTimeout = SleepTimeout.NeverSleep;
Screen.sleepTimeout = SleepTimeout.SystemSetting;
-
静态属性(不常用)fullScreen运行时是否全屏模式Screen.fullScreen = true;-
fullScreenMode窗口模式,可设置为 FullScreenMode 中的某个值Screen.fullScreenMode = FullScreenMode.Windowed;可选择独占全屏、全屏窗口、最大化窗口、窗口模式
移动设备旋转屏幕相关autorotateToLandscapeLeft允许自动旋转为左横向,Home 键在左Screen.autorotateToLandscapeLeft = true;-
autorotateToLandscapeRight允许自动旋转为右横向,Home 键在右Screen.autorotateToLandscapeRight = true;-
autorotateToPortrait允许自动旋转到纵向,Home 键在下Screen.autorotateToPortrait = true;-
autorotateToPortraitUpsideDown允许自动旋转到纵向倒着看,Home 键在上Screen.autorotateToPortraitUpsideDown = true;-
orientation指定屏幕显示方向Screen.orientation = ScreenOrientation.Landscape;-
静态方法SetResolution设置分辨率(一般移动设备不使用)Screen.SetResolution(1920, 1080, false);-

9.Camera摄像机

9.1Camera组件参数

分类参数说明用途示例或注意事项
Clear Flags(清除标志)Skybox(天空盒)确定将清除屏幕的哪些部分,此模式主要用于3D游戏,会渲染天空盒3D游戏开发-
`Solid Color(纯色)2D游戏适用,无需渲染天空盒,可在Background(背景)中修改颜色2D游戏开发在Background中选择合适颜色
Depth only(仅深度)只画该层,背景透明,通常配合深度使用,用于多个摄像机叠加渲染的情况多摄像机渲染高深度摄像机常选此模式,配合选择要渲染的层级
Don’t Clear(不清除)不移除原有内容,进行覆盖渲染,配合右键Game窗口tab选择编辑模式下不清除每一帧使用,一般较少使用特殊渲染需求-
Background(背景)-在绘制视图中的所有元素之后且没有天空盒的情况下,应用于剩余屏幕部分的颜色设置背景颜色选择合适的背景颜色
Culling Mask(剔除遮罩)-可包含或忽略要由摄像机渲染的对象层,能选择性渲染部分层级,未选定的层级不会被当前摄像机渲染控制渲染对象层级在检视面板中将层分配到对象,指定只渲染对应层级的对象
Projection(投影)Perspective(透视模式)切换摄像机模拟透视的功能,此模式有近大远小效果,常用于3D游戏制作3D游戏开发
- FOV Axis(Fov轴):决定光学仪器的视野范围,有Vertical(垂直)和Horizontal(水平)可选
- Field of view(视野):摄像机视角,范围在0 - 180度之间,一般默认60度
- Physical Camera(物理相机):勾选后可模拟真实世界中的摄像机
Orthographic(正交模式)没有近大远小效果,一般用于2D游戏制作2D游戏开发Size(大小):视野轴,决定摄制范围
Clipping Planes(裁剪平面)-确定开始和停止渲染位置到摄像机的距离,对象位置需在近和远的区间内才能被渲染到控制对象渲染范围对象渲染异常或模型显示不全可能与此参数有关
Viewport Rect(Viewport矩形)-通过四个值指示将在屏幕上绘制此摄像机视图的位置,在视口坐标中测量(值为0 - 1)多摄像机游戏XY设置渲染画面在Game窗口的起始位置,宽高设置渲染画面的比例,用于双摄像机或多摄像机游戏
Depth(深度)-摄像机在绘制顺序中的位置,值越大的摄像机将绘制在值越小的摄像机之上控制摄像机渲染顺序低深度摄像机先渲染,高深度摄像机后渲染并可叠加覆盖
Rendering path(渲染路径)-定义摄像机将使用的渲染方法的选项选择渲染方式-
Target Texture(目标纹理)-引用将包含摄像机视图输出的渲染纹理,设置此引用将禁用此摄像机的渲染到屏幕功能制作小地图等在Project右键创建Render Texture渲染器纹理,拖拽到Target Texture上,可将摄像机画面渲染到纹理上
Occlusion Culling(遮挡剔除)-为此摄像机启用遮挡剔除功能,即隐藏在其他对象后面的对象不会被渲染优化渲染性能默认勾选,可减少不必要的渲染
HDR-为此摄像机启用高动态范围渲染提升画面质量-
MSAA-为此摄像机启用多重采样抗锯齿提升画面平滑度-
Allow Dynamic Resolution(允许动态分辨率)-为此摄像机启用动态分辨率渲染优化性能-
Target Display-定义要渲染到的外部设备,值为1到8之间多屏幕平台游戏开发-
Target Eye-用于VR游戏,选择渲染的眼睛(左或右)VR游戏开发-

9.2Camera参数和方法

9.2.1. 获取摄像机相关
静态成员说明示例代码注意事项
main获取主摄像机,即第一个启用且 tag 为 “MainCamera” 的摄像机(只读)print(Camera.main);
print(Camera.main.name);
场景必须有 tag 为 “MainCamera” 的摄像机,否则报错;若有多个,获取的摄像机不确定
allCamerasCount获取当前场景中的摄像机数量print(Camera.allCamerasCount);-
allCameras得到场景中所有已启用的摄像机Camera[] allCameras = Camera.allCameras;
print(allCameras.Length);
-
9.2.2. 渲染相关委托
静态变量说明示例代码
onPreCull任意摄像机开始剔除前触发的事件,可在剔除前做委托处理Camera.onPreCull += (c) => { /* 处理逻辑 */ };
onPreRender任意摄像机开始渲染前触发的事件Camera.onPreRender += (c) => { /* 处理逻辑 */ };
onPostRender任意摄像机完成渲染后触发的事件Camera.onPostRender += (c) => { /* 处理逻辑 */ };
9.2.3. 重要成员
成员说明示例代码注意事项
depth设置摄像机在渲染顺序中的深度Camera.main.depth = 10;-
WorldToScreenPoint将世界坐标转换为屏幕坐标,常用于头顶血条功能Vector3 v = Camera.main.WorldToScreenPoint(this.transform.position);
print(v);
-
ScreenToWorldPoint将屏幕坐标转换为世界坐标,需设置 Z 值Vector3 v = Input.mousePosition;
v.z = 5;
sphere.position = Camera.main.ScreenToWorldPoint(v);
若不设置 Z 值,默认为 0,转换的世界坐标点是视口相交焦点;设置 Z 值后,是摄像机前方对应单位横截面上的世界坐标点

10.Light光面板

10.1光源组件
分类参数说明示例或注意事项
光源类型Directional(方向光)模拟远距离的光源,如太阳,光照方向一致-
Spot(聚光灯)类似手电筒,有特定的发光范围和光锥角度需设置 Range(范围)和 Spot Angle(光锥角度)
Point(点光源)类似小灯泡,向四周发光-
Area(面光源)--
光源颜色和模式Color(光源颜色)设置光源的颜色-
Mode(光源模式)Realtime(实时光源):每帧实时计算,效果好但性能消耗大;Baked(烘焙光源):事先计算好,无法动态变化;Mixed(混合光源):预先计算 + 实时运算根据性能和效果需求选择模式
光源强度和间接系数Intensity(光源强度)控制光源的亮度-
Indirect Multiplier(间接系数)改变间接光的强度,低于 1 每次反弹光更暗,大于 1 每次反弹光更亮-
阴影类型Shadow TypeNoShadows(关闭阴影);HardShadows(生硬阴影);SoftShadows(柔和阴影);Realtime Shadows(实时阴影)选择合适的阴影类型提升视觉效果
Strength(强度)阴影暗度,范围 0 - 1,越大越黑-
Resolution(分辨率)阴影贴图渲染分辨率,越高越逼真,消耗越高-
Bias(偏离)阴影推离光源的距离-
Normal Bias(法线偏离)阴影投射面沿法线收缩距离-
Near Panel(近平面)渲染阴影的近裁剪面-
剪影和效果Cookie(剪影)投影遮罩,一般用于聚光灯显示图案-
Cookie Size(剪影大小)控制剪影的大小-
Draw Halo(绘制光晕)球形光环开关,可用于蜡烛等效果要在 Game 窗口看到光晕需在摄像机上加 FlareLayer 脚本
Flare(眩光)耀斑效果,类似太阳耀斑要在 Game 窗口看到耀斑需在摄像机上加 FlareLayer 脚本
渲染模式和剔除遮罩Render ModeAuto(自动):运行时确定;Important(重要):以像素质量为单位进行渲染,效果逼真,消耗大;Not Important(非重要):以快速模式进行渲染根据性能和效果需求选择渲染模式
Culling Mask(剔除遮罩)剔除遮罩层,决定哪些层的对象受到该光源影响-
代码控制intensity(光照强度)控制光的强度乘以光颜色light.intensity = 0.5f;
10.2光面板(照明设置)
分类参数说明示例或注意事项
环境相关设置Skybox Material(天空盒材质)可以改变天空盒,可在 Project 窗口右键创建材质,材质选择成天空盒着色器-
Sun Source(太阳来源)不设置会默认使用场景中最亮的方向光代表太阳-
环境光设置Source(环境光光源颜色)Skybox(天空盒):天空和材质作为环境光颜色;Gradient(渐变):可以为天空、地平线、地面单独选择颜色和它们之间混合-
Intensity Multiplier(环境光亮度)控制环境光的亮度-
Ambient Mode(环境模式)全局光照模式,只有启用了实时全局和全局烘焙时才有用,Realtime(实时,已弃用)、Baked(烘焙)-
其它设置Fog(雾开关)控制雾的显示-
Color(雾颜色)设置雾的颜色-
Mode(雾计算模式)Linear(线性模式):随距离线性增加;Exponential(指数模式):随距离指数增加;Exponential Qquare(指数平方模式):随距离比指数更快的增加不同模式下需设置不同的参数,如 Linear 模式需设置 Start 和 End 距离,指数模式需设置 Density 密度
Halo Texture(光晕材质)光源周围挥着光环的纹理-
Halo Strength(光晕强度)光环可见性-
Flare Fade Speed(炫光交叉淡化速度)耀斑淡出时间,最初出现之后淡出的时间-
Flare Strength(炫光强度)耀斑可见性-
Spot Cookie(聚光灯剪影)聚光灯剪影纹理-

11 物理系统 - 刚体

11.1.刚体组件参数

英文参数说明示例或注意事项
Mass(质量)默认为千克,质量越大惯性越大-
Drag(空气阻力)根据力移动对象时影响对象的空气阻力大小,0 表示没有空气阻力-
Angular Drag(角阻力,扭矩阻力)通俗理解就是阻碍对象旋转的阻力,角阻力越大越不容易旋转。根据扭矩旋转对象时影响对象的空气阻力大小,0 表示没有空气阻力-
Use Gravity(重力开关)是否受重力影响-
Is Kinematic控制物理是否影响刚体。可以理解为开启后不受力的影响,只能通过 Transform 移动。如果启用此选项,则对象将不会被物理引擎驱动,只能通过 (Transform) 对其进行操作。对于移动平台,或者如果要动画化附加了 HingeJoint 的刚体,此属性将非常有用-
Interpolate(插值运算)让刚体物体移动更平滑可以更改 FixTime,改成一秒,这样对象会很突兀的一秒移动一次,这时开启插值运算就可以让刚体对象平滑移动
- None(无插值运算模式)不应用插值运算-
- Interpolate(插值模式)插值将始终滞后一点,但比外推更流畅。根据前一帧的变换来平滑变换-
- Extrapolate(外推模式)外推将根据当前速度预测刚体的位置。根据下一帧的估计变换来平滑变换-
Collision Detection(碰撞检测模式)用于防止快速移动的对象穿过其它对象而不检测碰撞-
- Discrete(离散检测)默认的碰撞检测模式。在每一帧中进行一次碰撞检测,适用于大多数普通物体。最省性能,但可能会错过高速物体的碰撞。适合一般速度移动的物体,不适合高速移动的小物体。对场景中的所有其他碰撞体使用离散碰撞检测。其他碰撞体在测试碰撞时会使用离散碰撞检测。用于正常碰撞(这是默认值)-
- Continuous(连续检测)提高了碰撞检测的精度,特别适合高速移动的物体。在每一帧中进行多次碰撞检测,避免高速物体穿过其他物体。比 Discrete 消耗更多的性能,但减少了穿透问题。适用于高速移动的物体,如子弹或快速飞行的物体。对动态碰撞体(具有刚体)使用离散碰撞检测,并对静态碰撞体(没有刚体)使用连续碰撞检测。设置为连续动态 (Continuous Dynamic) 的刚体将在测试与该刚体的碰撞时使用连续碰撞检测。(此属性对物理性能有很大影响,如果没有快速对象的碰撞问题,请将其保留为 Discrete 设置)其他刚体将使用离散碰撞检测-
- Continuous Dynamic(连续动态检测)针对快速移动的物体和其他静止或缓慢移动的物体之间的碰撞检测。结合 ContinuousDiscrete 的优点,对高速物体进行多次检测,对慢速或静止物体进行一次检测。在保证精度的同时比 Continuous 更省性能。适用于快速移动的物体与静止或缓慢移动的物体之间的碰撞检测,如快速移动的角色或车辆。性能消耗高。对设置为连续 (Continuous) 和连续动态 (Continuous Dynamic) 碰撞的游戏对象使用连续碰撞检测。还将对静态碰撞体(没有刚体)使用连续碰撞检测。对于所有其他碰撞体,使用离散碰撞检测。用于快速移动的对象-
- Continuous Speculative(连续推测检测)使用预测的方式进行碰撞检测。预测物体的未来位置,并在物体穿过其他物体前进行检测和处理。性能较高,精度也不错,但有时可能会出现误判。适合大多数需要高精度且有较高速度的物体。对刚体和碰撞体使用推测性连续碰撞检测。该方法通常比连续碰撞检测的成本更低-
Constraints(刚体约束)对刚体运动的限制-
- Freeze Position(冻结位置)有选择地停止刚体沿世界 X、Y 和 Z 轴的移动-
- Freeze Rotation(冻结旋转)有选择地停止刚体围绕局部 X、Y 和 Z 轴旋转-
Info(当前刚体的信息)--

11.2.刚体参数和方法

方法详情
获取刚体组件使用this.GetComponent<Rigidbody>()获取刚体组件,示例:rigidBody = this.GetComponent<Rigidbody>();
AddForce方法相对世界坐标添加力,例如rigidBody.AddForce(Vector3.forward * 10);。若要让对象相对于自身面朝向移动,可使用rigidBody.AddForce(this.transform.forward * 10);。若想即使有阻力也让对象一直移动,可在Update内持续调用此方法。
AddRelativeForce方法相对本地坐标添加力,示例:rigidBody.AddRelativeForce(Vector3.forward * 10);
AddTorque方法相对世界坐标添加扭矩力,使刚体旋转,示例:rigidBody.AddTorque(Vector3.up * 10);
AddRelativeTorque方法相对本地坐标添加扭矩力,使刚体旋转,示例:rigidBody.AddRelativeTorque(Vector3.up * 10);
velocity变量设置刚体速度,速度方向相对于世界坐标系,示例:rigidBody.velocity = Vector3.forward * 5;
AddExplosionForce方法模拟爆炸效果,参数为(力的大小,中心,半径),示例:rigidBody.AddExplosionForce(100, Vector3.zero, 10);
力的模式(ForceMode)- Acceleration(加速度模式):给物体增加持续加速度,忽略质量,如rigidBody.AddForce(Vector3.forward * 10, ForceMode.Acceleration);
- Force(力模式):给物体添加持续力,与物体质量有关。
- Impulse(冲击力模式):给物体添加瞬间力,与物体质量有关,忽略时间。
- VelocityChange(瞬时速度模式):给物体添加瞬时速度,忽略质量和时间。
恒力场组件搜索组件constant force添加到物体上,修改其参数可实现不用代码添加力的效果,适用于保持某种力的场景。
刚体的休眠Unity为节约性能可能让刚体休眠。可使用IsSleeping方法判断刚体是否休眠,如if (rigidBody.IsSleeping());使用WakeUp方法唤醒刚体,如rigidBody.WakeUp();

12. 物理系统 - 碰撞体

12.1.3D 碰撞器种类

  • 盒状碰撞器 (BoxCollider)
  • 球状碰撞器 (Sphere Collider)
  • 胶囊碰撞器 (Capsule Collider)
  • 网格碰撞器 (Mesh Collider)
  • 轮胎碰撞器 (Wheel Collider)
  • 地形碰撞器 (Terrain Collider)

12.2.3D 碰撞器共同参数

英文参数说明示例或注意事项
Edit Collider(编辑碰撞体)改变碰撞体大小-
Is Trigger(是否是触发器)如果启用此属性,则该碰撞体将用于触发事件,并被物理引擎忽略。主要用于进行没有物理效果的碰撞检测-
Material(物理材质)可以确定碰撞体和其它对象碰撞时的交互(表现)方式-
Center(碰撞器中心)碰撞体在对象局部空间中的中心点位置-

12.3.常用碰撞器

碰撞器类型英文参数说明
BoxCollider(盒状碰撞器)Size(大小)碰撞体在 X、Y、Z 方向上的大小
Sphere Collider(球状碰撞器)Radius(半径)球形碰撞体的半径大小
Capsule Collider(胶囊碰撞器)Radius(半径)胶囊体的半径
-Height(高度)胶囊体的高度
-Direction(轴向)胶囊体在对象局部空间中的轴向

异形物体使用多种碰撞器组合。刚体对象的子对象碰撞器信息参与碰撞检测。比如金字塔预设体,只在金字塔最高层级对象添加刚体,子对象的所有 Cube 都会参与碰撞检测。再比如一个 Cube 添加刚体,再给他添加两个空物体,两个空物体分别添加斜着的盒型碰撞器当做支架,这样这个 Cube 下落时就会被支架撑起来,即便两个空物体连模型都没有只有碰撞器。

12.4不常用碰撞器

碰撞器类型英文参数说明示例或注意事项
Mesh Collider(网格碰撞器)不常用的原因是性能消耗较高默认不会显示绿色的碰撞器边框,开启 Convex 才会显示绿色的碰撞器边框-
-Convex(凸面)加了刚体的网格碰撞器必须把这个选项开启才能和别的对象碰撞,否则报错-
-Cooking Options(烹制选项)启用或禁用影响物理引擎对网格处理方式的网格烹制选项-
-Mesh(网格模型选项)引用需要用于碰撞的网格-
Wheel Collider(轮胎碰撞器)不常用的原因是国内赛车游戏公司较少可以通过给车的父对象加刚体,子对象加车轮碰撞器模拟汽车-
-Mass(车轮的质量)--
-Radius(车轮的半径)--
-Wheel Damping Rate(应用于车轮的阻尼值)--
-Suspension Distance(车轮悬架的最大延伸距离)--
-Force App Point Distance(定义车轮上的受力点)--
-Suspension Spring(悬架尝试通过增加弹簧力和阻尼力来到达目标位置)--
Terrain Collider(地形碰撞器)不常用的原因是性能消耗较高--
-Terrain Data(地形数据)--
-Enable Tree Colliders(选中此属性时,将启用树碰撞体)--

13. 物理系统 - 物理材质

英文参数说明
Dynamic Friction(动摩擦力)已在移动时使用的摩擦力。通常为 0 到 1 之间的值。值为零就像冰一样,值为 1 将使对象迅速静止(除非用很大的力或重力推动对象)
Static Friction(静摩擦力)当对象静止在表面上时使用的摩擦力。通常为 0 到 1 之间的值。值为零就像冰一样,值为 1 将导致很难让对象移动
Bounciness(弹性)表面的弹性如何?值为 0 将不会反弹。值为 1 将在反弹时不产生任何能量损失,预计会有一些近似值,但可能只会给模拟增加少量能量
Friction Combine(摩擦力组合)两个碰撞对象的摩擦力的组合方式
- Average(平均值)对两个摩擦值求平均值
- Minimum(最小值)使用两个值中的最小值
- Maximum(最大值)使用两个值中的最大值
- Multiply(相乘)两个摩擦值相乘
Bounce Combine(反弹组合)两个碰撞对象的弹性的组合方式。其模式与 Friction Combine 模式相同
- Average(平均值)对两个摩擦值求平均值
- Minimum(最小值)使用两个值中的最小值
- Maximum(最大值)使用两个值中的最大值
- Multiply(相乘)两个摩擦值相乘

14. 碰撞检测函数

14.1碰撞器与触发器的核心条件对比

14.1.1.碰撞发生的必要条件
条件说明示例
至少1个刚体(Rigidbody)提供物理模拟的动力源,负责受力与运动下落的立方体(带刚体)碰撞地面(无刚体但有碰撞器)
双方均有碰撞器(Collider)定义碰撞体积,缺一无法检测碰撞子弹(刚体+碰撞器) vs 敌人(碰撞器)
碰撞器未开启 Is Trigger必须为物理碰撞模式(默认关闭)关闭触发器的胶囊体碰撞
14.1.2.触发器触发的必要条件
条件说明示例
至少1个碰撞器开启 Is Trigger标记为触发器,禁用物理碰撞效果门的触发区域(碰撞器+Is Trigger)
至少1个刚体(可选但推荐)非必须,但刚体存在时事件更稳定(静止物体需刚体才能触发)玩家(刚体)进入触发器区域(无刚体的碰撞器)
双方碰撞器重叠空间上产生交集(无需接触)球形触发器包裹玩家

14.2.物理碰撞检测响应函数

// OnCollisionEnter方法 碰撞触发接触时会自动执行这个函数
private void OnCollisionEnter(Collision collision)
{
    // 获取碰撞到的对象的相关信息
    Collider collider = collision.collider; // 碰撞到的对象的碰撞器信息
    GameObject gameObject = collision.gameObject; // 碰撞到的对象
    Transform transform = collision.transform; // 碰撞到的对象的位置信息

    // 获取接触点数
    int contactCount = collision.contactCount;
    ContactPoint[] pos = collision.contacts; // 返回接触点类数组,可以查看每个接触点的具体的坐标

    print(this.name + "被" + collision.gameObject.name + "撞到了");
}

// OnCollisionExit方法 碰撞结束分离时会自动执行的函数
private void OnCollisionExit(Collision collision)
{
    print(this.name + "被" + collision.gameObject.name + "结束碰撞了");
}

// OnCollisionStay方法 两个物体相互接触摩擦时会不停的调用该函数 接触但静止时不会调用
private void OnCollisionStay(Collision collision)
{
    print(this.name + "一直在和" + collision.gameObject.name + "接触");
}

14.3触发器检测响应函数

// OnTriggerEnter方法 触发开始的函数 当第一次接触时会自动调用
protected virtual void OnTriggerEnter(Collider other)
{
    print(this.name + "被" + other.gameObject.name + "触发了");
}

// OnTriggerExit方法 触发结束的函数 当水乳相融的状态结束时会调用一次
private void OnTriggerExit(Collider other)
{
    print(this.name + "被" + other.gameObject.name + "结束水乳相融的状态了");
}

// OnTriggerStay方法 当两个对象水乳相融的时候会不停调用
private void OnTriggerStay(Collider other)
{
    print(this.name + "和" + other.gameObject.name + "正在水乳相融");
}

15.Unity 音效系统

15.1.音频文件导入

分类知识点说明/示例
支持格式WAV、MP3、OGG、AIFF推荐 WAV(无损)用于短音效,MP3/OGG(压缩)用于长音频
导入操作直接拖拽音频到 Project 窗口-
属性设置Force To Mono(强制单声道)多声道转单声道,适合语音类音频
LoadType(加载类型)- Decompress On Load:小音效(内存高,加载快)
- Compress in Memory:大音效(内存低,加载慢)
- Streaming:极长音频(内存最小,CPU 高)
Preload Audio Data(预加载)勾选:进入场景预加载;不勾选:首次播放时加载
预览与控制底部工具栏播放/暂停/循环按钮支持拖拽进度条预览音频

15.2.音频源(AudioSource)

15.2.1.音频源组件参数
分类参数说明适用场景注意事项
基础设置AudioClip拖拽音频文件,指定播放内容背景音乐、UI 音效、技能特效未赋值时播放为空,需检查引用
Play On Awake启用时对象创建即播放(默认√)背景音乐(√)、UI 点击音效(×)动态生成的对象(如子弹)需关闭此选项
Loop循环播放(默认×)背景音乐、环境音(如风声、水流)短音效(如按钮点击)禁用循环
音量控制Volume音量(0-1,支持负数反向)主音量调节、角色音量衰减结合 PlayerPrefs 存储用户设置
Priority优先级(0-255,0 最高,默认 128)多音效冲突时,高优先级优先播放(如警报音 > 脚步声)超过 32 个同时播放的音效可能爆音,需用 AudioMixer 管理
2D 音效Stereo Pan左右声道平衡(-1左 ~ 1右)UI 按钮立体声、2D 游戏音效Spatial Blend=0 配合使用
3D 音效Spatial Blend空间混合(0=2D,1=3D)3D 游戏中脚步声、NPC 语音设为 1 时需配置 Min/Max Distance 和衰减曲线
Doppler Level多普勒效果(0-1,模拟运动时音调变化)车辆引擎声、飞行物音效角色移动时生效,静态对象建议设为 0
Volume Rolloff衰减模式:
- Logarithmic(真实衰减)
- Linear(线性衰减)
- Custom(自定义曲线)
脚步声(Logarithmic)、环境音(Custom)Custom 需手动绘制曲线,匹配场景距离
Min/Max Distance最小/最大距离(3D 音效生效范围)脚步声(Min=1,Max=5)、BOSS 语音(Min=2,Max=10)Min 过小导致声音突变,Max 过大增加计算量
性能控制Bypass Effects跳过音效滤镜(如混响、延迟)性能优化,禁用非必要特效仅在低端设备或复杂场景使用
Output输出到混音器(高级功能)多声道混音、分组控制(如 BGM/音效分离)需配合 AudioMixer 组件使用
15.2.2.音频源参数和方法
方法/属性说明示例代码
Play()播放音频(从开头)audioSource.Play();
PlayDelayed(5f)延迟播放(秒为单位)audioSource.PlayDelayed(2f); // 2 秒后播放
Pause()/UnPause()暂停/恢复(保留播放位置)audioSource.Pause();
Stop()停止并重置位置audioSource.Stop(); // 下次从开头播放
isPlaying检测是否播放(只读)if (!audioSource.isPlaying) 播放完毕逻辑;
多 AudioSource一个物体挂多个音频源,独立控制AudioSource[] audios = GetComponents<AudioSource>(); audios[1].Play();
15.3.麦克风录制
功能方法/属性示例代码
获取设备Microphone.devicesstring[] mics = Microphone.devices; // 打印所有麦克风名称
开始录制Microphone.Start(设备名, 循环, 时长, 采样率)audioClip = Microphone.Start(null, false, 10, 44100); // 默认设备录 10 秒
停止录制Microphone.End(设备名)Microphone.End(null); // 停止并保存录音
获取音频数据AudioClip.GetData(数组, 起始样本)float[] data = new float[clip.channels * clip.samples];<br>clip.GetData(data, 0);
播放录音绑定 AudioSource 播放audioSource.clip = 录音Clip; audioSource.Play();

二、Unity基础

1.Mathf

1.1.常用基础方法(一般计算一次)

方法说明参数/返回值示例代码游戏场景
Mathf.PI圆周率(3.14159265358979)float(只读)print(Mathf.PI); // 3.141593圆周长、弧度计算
Mathf.Abs(float f)取绝对值f:数值
返回:绝对值
Mathf.Abs(-5f); // 5距离计算、伤害绝对值处理
Mathf.Clamp(float val, float min, float max)钳制数值(超出范围则取边界值)val:原始值
min/max:边界
Mathf.Clamp(HP, 0, 100); // HP 不低于 0 不高于 100血量、进度条限制
Mathf.Lerp(float a, float b, float t)线性插值(t 0→1 时从 a 平滑过渡到 ba:起始值
b:目标值
t:插值系数
pos = Mathf.Lerp(startPos, endPos, 0.5f); // 中间位置平滑移动、渐变动画
Mathf.RoundToInt(float f)四舍五入取整f:浮点数
返回:整数
Mathf.RoundToInt(3.6f); // 4分数显示、帧数统计
Mathf.Sqrt(float f)平方根f:数值
返回:平方根
Mathf.Sqrt(25f); // 5距离计算(替代 Vector3.Distance
Mathf.CeilToInt(float f)向上取整,返回大于或等于 f 的最小整数f:浮点数
返回:整数
Mathf.CeilToInt(1.3f); // 2资源计数,比如购买物品数量向上取整
Mathf.FloorToInt(float f)向下取整,返回小于或等于 f 的最大整数f:浮点数
返回:整数
Mathf.FloorToInt(9.6f); // 9资源计数,如计算可用资源的整数量
Mathf.Max(params float[] values)返回两个或更多值中的最大值values:可变长参数列表
返回:最大值
Mathf.Max(1, 2, 3, 4, 5); // 5比较多个角色的属性值,如攻击力最大值
Mathf.Min(params float[] values)返回两个或更多值中的最小值values:可变长参数列表
返回:最小值
Mathf.Min(1, 2, 3, 4, 5); // 1比较多个敌人的防御值,找出最小防御值的敌人
Mathf.Pow(float f, float p)返回 fp 次幂f:底数
p:指数
返回:幂值
Mathf.Pow(2, 3); // 8伤害计算,如技能伤害随等级的幂次增长
Mathf.IsPowerOfTwo(int value)判断一个数是否是 2 的 n 次方value:整数
返回:布尔值
Mathf.IsPowerOfTwo(4); // true纹理尺寸判断,在图形处理中确保纹理尺寸为 2 的幂次方
Mathf.Sign(float f)返回 f 的符号,正数和 0 返回 1,负数返回 -1f:数值
返回:1 或 -1
Mathf.Sign(-10); // -1方向判断,如角色移动方向的正负判断

1.2.插值运算(Lerp)深度解析

用法代码示例效果适用场景
用法一:先快后慢pos = Mathf.Lerp(pos, target, Time.deltaTime * speed);初始速度快,逐渐趋近目标(类似阻尼效果)镜头跟随、物体平滑停止
用法二:匀速接近t += Time.deltaTime; pos = Mathf.Lerp(start, end, t);t 累加,匀速到达目标(t≥1 时固定为 end倒计时、线性动画
扩展:颜色插值color = Color.Lerp(Color.red, Color.blue, t);平滑过渡颜色(t 0→1 时红→蓝)UI 渐变、技能特效

1.3.三角函数与角度转换

方法/常量说明参数/返回值示例代码游戏场景
Mathf.Rad2Deg弧度转角度常量(1 弧度 ≈ 57.29578°)float(只读)float deg = rad * Mathf.Rad2Deg; // 弧度转角度欧拉角显示、UI 角度标注
Mathf.Deg2Rad角度转弧度常量(1° ≈ 0.01745329 弧度)float(只读)float rad = deg * Mathf.Deg2Rad; // 角度转弧度三角函数计算、旋转方向
Mathf.Sin(float rad)正弦函数(输入弧度)rad:弧度
返回:正弦值
Mathf.Sin(90 * Mathf.Deg2Rad); // 1正弦波运动(如摆锤、波浪效果)
Mathf.Cos(float rad)余弦函数(输入弧度)rad:弧度
返回:余弦值
Mathf.Cos(0 * Mathf.Deg2Rad); // 1方向向量计算(如敌人巡逻路径)
Mathf.Atan2(float y, float x)反正切函数(返回弧度,计算 y/x 的角度)y/x:坐标差值
返回:弧度
float angle = Mathf.Atan2(y, x) * Mathf.Rad2Deg; // 目标角度角色朝向、子弹追踪

2.坐标系

2.1.四大坐标系对比

坐标系定义原点轴方向典型场景
世界坐标系全局唯一,所有物体的绝对位置基准场景中心(0,0,0)X→右,Y→上,Z→前(默认)物体位置存储、碰撞检测
本地坐标系相对于父对象的局部坐标系父对象的位置随父对象旋转/缩放而变化子对象相对父对象的位置调整
屏幕坐标系基于屏幕像素的2D坐标系左下角(0,0)X→右,Y→上,Z→深度(摄像机距离)鼠标位置获取、UI元素定位
视口坐标系归一化的屏幕坐标系(0-1范围)左下角(0,0)X→右,Y→上,Z→深度(0-1)分屏显示、全屏适配

2.2坐标转换核心方法

2.2.1. 世界 ↔ 本地(Transform 方法)
方向方法说明参数/返回值游戏场景
世界→本地(点)InverseTransformPoint(Vector3 worldPos)将世界点转为本地坐标(含位置+缩放+旋转)worldPos:世界点
返回:本地点
子对象相对于父对象的位置计算
世界→本地(方向)InverseTransformDirection(Vector3 worldDir)仅转换方向(忽略缩放,保留旋转)worldDir:世界方向
返回:本地方向
子弹方向相对于坦克的朝向调整
本地→世界(点)TransformPoint(Vector3 localPos)将本地点转为世界坐标(含父对象变换)localPos:本地点
返回:世界点
炮塔位置转世界坐标生成子弹
本地→世界(方向)TransformDirection(Vector3 localDir)仅转换方向(忽略缩放,保留旋转)localDir:本地方向
返回:世界方向
角色朝向转世界方向(如技能释放方向)
2.2.2. 世界 ↔ 屏幕(Camera 方法)
方向方法说明关键参数游戏场景
世界→屏幕WorldToScreenPoint(Vector3 worldPos)世界点转屏幕坐标(Z为到摄像机的距离)worldPos:世界点
返回:屏幕点(x,y,depth)
头顶血条位置计算(UI锚点)
屏幕→世界ScreenToWorldPoint(Vector3 screenPos)屏幕点转世界坐标(需设置Z轴,默认Z=0为近裁剪平面)screenPos:屏幕点(需设Z)
返回:世界点
鼠标点击生成物体(需Z=10)
2.2.3. 世界 ↔ 视口(Camera 方法)
方向方法说明坐标范围游戏场景
世界→视口WorldToViewportPoint(Vector3 worldPos)世界点转视口坐标(X/Y∈[0,1],Z为深度)worldPos:世界点
返回:视口点(0-1)
检测物体是否在屏幕内(视口坐标>0且<1)
视口→世界ViewportToWorldPoint(Vector3 viewportPos)视口点转世界坐标(X/Y∈[0,1],Z为深度)viewportPos:视口点(需设Z,返回:世界点分屏游戏中,左半屏生成物体(X=0.5)

3.Vector3

3.1基础属性(实例成员)

方法/属性说明参数/返回值示例代码游戏场景注意事项
magnitude向量的模长(只读)float(返回长度)Vector3 dir = target - transform.position;<br>float distance = dir.magnitude;敌人距离检测、射程判断等价于 Mathf.Sqrt(x²+y²+z²),性能略低于Distance方法
normalized单位向量(只读,方向不变,长度1)Vector3(返回单位向量)Vector3 normDir = dir.normalized;方向移动(如角色朝向)若原向量为零向量,返回零向量(避免除以零)
sqrMagnitude模长平方(只读,性能更高)float(返回长度²)if (dir.sqrMagnitude < 25) 触发攻击;快速距离比较(避免开平方)用于判断“是否在半径5内”时,比magnitude快约50%

3.2静态方法(基础运算)

方法说明参数/返回值示例代码游戏场景几何意义
Distance(a, b)两点间距离(等价于(b-a).magnitudea,b:Vector3
返回:float
float dist = Vector3.Distance(A, B);子弹射程、寻路范围欧几里得距离公式
Angle(from, to)两向量夹角(0°~180°,度数)from,to:Vector3
返回:float
float angle = Vector3.Angle(forward, dir);扇形攻击范围、视野检测基于点乘计算,忽略方向(仅角度)
Cross(a, b)叉乘(左手坐标系,返回垂直于a、b的向量)a,b:Vector3
返回:Vector3
Vector3 up = Vector3.Cross(right, forward);判断左右方位(如敌人侧击)右手法则(数学)→ 左手法则(Unity)
Dot(a, b)点乘(返回标量,a·b =abcosθ)
Lerp(a, b, t)线性插值(t∈[0,1],a到b的直线过渡)a,b:Vector3
t:float
返回:Vector3
pos = Vector3.Lerp(start, end, Time.deltaTime*3);平滑移动、镜头跟随t>1时固定为b,t<0时固定为a
Slerp(a, b, t)球形插值(保持向量长度,球面过渡)a,b:Vector3
t:float
返回:Vector3
dir = Vector3.Slerp(forward, targetDir, 0.1f);平滑旋转、物体轨迹常用于方向向量插值,避免“翻折”
MoveTowards(current, target, maxDistanceDelta)向目标移动(自动限制步长)current,target:Vector3
maxDistanceDelta:float
返回:Vector3
transform.position = Vector3.MoveTowards(pos, target, speed*dt);角色寻路、敌人追击等价于Lerp+Clamp,更安全

4.Quaternion

4.1.构造与属性

方法/属性类型说明参数/返回值示例代码游戏场景注意事项
Quaternion()构造函数初始化四元数(默认单位四元数)-Quaternion q = new Quaternion();空旋转初始化等价于Quaternion.identity
AngleAxis(angle, axis)静态绕轴旋转(角度→四元数)angle:float(度数)
axis:Vector3
返回:Quaternion
Quaternion q = Quaternion.AngleAxis(90, Vector3.up);绕Y轴旋转90°(如门开合)轴向量无需归一化,内部自动处理
Euler(x, y, z)静态欧拉角转四元数(按Z→X→Y顺序旋转)x,y,z:float(度数)
返回:Quaternion
Quaternion q = Quaternion.Euler(30, 0, 0);欧拉角转四元数(如角色转头)可能引发万向节死锁,避免直接修改欧拉角
eulerAngles实例属性四元数转欧拉角(只读,自动处理-180~180°)Vector3(返回欧拉角)Vector3 angles = q.eulerAngles;调试旋转角度非连续旋转时可能跳跃(如从179°→-179°)
identity静态属性单位四元数(无旋转)Quaternion(只读)transform.rotation = Quaternion.identity;重置旋转(如复位操作)等价于new Quaternion(0,0,0,1)

4.2.核心方法(旋转控制)

方法类型说明参数/返回值示例代码游戏场景对比/优化
Lerp(a, b, t)静态线性插值(非球面,可能翻转)a,b:Quaternion
t:float
返回:Quaternion
q = Quaternion.Lerp(rotA, rotB, 0.5f);快速插值(如UI旋转)Slerp快20%,但可能“翻折”(适合非方向敏感场景)
Slerp(a, b, t)静态球形插值(保持旋转方向,球面过渡)a,b:Quaternion
t:float
返回:Quaternion
transform.rotation = Quaternion.Slerp(rot, targetRot, dt*5);平滑转向(如角色转头)计算开销略高,适合方向敏感场景(如镜头旋转)
LookRotation(dir, up)静态看向目标方向(自动处理Up轴)dir:Vector3(目标方向)
up:Vector3(默认Vector3.up)
返回:Quaternion
Quaternion look = Quaternion.LookRotation(target - pos);角色/镜头看向目标(如敌人)等价于Transform.LookAt,但更灵活(可自定义Up轴)
operator * (q1, q2)运算符四元数乘法(q1先旋转,q2后旋转)q1,q2:Quaternion
返回:Quaternion
transform.rotation *= Quaternion.AngleAxis(10, Vector3.up);绕自身轴连续旋转(如飞机翻滚)左乘:世界坐标系;右乘:本地坐标系(默认右乘)
operator * (q, vec)运算符向量绕四元数旋转q:Quaternion
vec:Vector3
返回:Vector3
Vector3 newDir = q * Vector3.forward;子弹方向计算(如扇形发射)等价于Transform.TransformDirection(vec)

5.延迟函数

5.1.核心方法

方法作用参数返回值执行时机典型场景
Invoke(method, time)延时执行一次方法method: 函数名(字符串)
time: 延迟时间(秒)
第1次在time秒后执行倒计时提示、技能冷却结束触发
InvokeRepeating(method, time, repeat)延时重复执行方法method: 函数名
time: 首次延迟
repeat: 重复间隔(秒)
第1次time秒后,之后每repeat秒执行定时刷新(如敌人巡逻、自动射击)
CancelInvoke([method])取消延迟函数method: 可选(取消指定函数,不填则取消所有)立即生效对象销毁前清理任务(如停止重复播放)
IsInvoking([method])判断是否存在待执行的延迟函数method: 可选(检查指定函数,不填则检查所有)bool实时判断避免重复开启延迟(如防止多次点击)

5.2.对象状态对延迟函数的影响

对象状态Invoke/InvokeRepeatingCancelInvoke恢复执行
激活(Active)正常执行正常取消-
失活(Inactive)继续执行(不受影响)正常取消激活后继续(仅InvokeRepeating
销毁(Destroy)立即终止无效无法恢复
脚本禁用(Disable)继续执行(脚本生命周期未结束)正常取消启用后继续(仅InvokeRepeating

5.3延迟函数 vs 协程(Coroutine)

对比项延迟函数(Invoke)协程(Coroutine)
执行控制简单(字符串函数名)灵活(可传参、中途中断)
性能较高(底层优化)中等(迭代器开销)
参数支持不支持(需代理)支持(通过IEnumerator传参)
生命周期依赖独立于对象激活状态依赖MonoBehaviour生命周期
适用场景简单定时任务(如冷却、提示)复杂流程控制(如动画插值、异步加载)

6.协同程序

6.1.协程方法

分类方法作用执行机制适用场景核心特性
启动StartCoroutine(ie)开启协程(迭代器函数)主线程分时执行,依赖yield控制异步加载、批量操作(如创建1000个物体)可传参,通过迭代器分步执行
关闭StopCoroutine(ie/c)停止指定协程(推荐用返回的Coroutine对象)立即终止中途取消(如加载失败)StopAllCoroutines()清空所有
暂停标记yield return X- null/数字:下一帧
- WaitForSeconds(t):等待t
- WaitForFixedUpdate():物理帧
- WaitForEndOfFrame():渲染后
调度器根据X决定恢复时机分步逻辑(如动画插值、截图)迭代器本质,代码块被拆分为多段执行
生命周期-组件失活继续执行,物体/组件销毁终止--依赖MonoBehaviour生命周期,适合Unity对象操作
本质迭代器(C#语法糖)将函数逻辑拆分为可中断的“片段”,通过调度器恢复执行--非多线程,无并行,纯主线程分支

6.2.多线程与协程对比表

对比项多线程(Thread)协程(Coroutine)
本质操作系统层面的并行执行,独立于主线程基于C#迭代器的分时执行,在主线程分支运行
访问Unity对象不能直接访问Unity相关对象(如transform可正常访问Unity对象
性能开销开销大,创建和销毁线程有资源消耗开销小,基于迭代器实现
执行顺序并行执行,执行顺序不确定分时执行,可控制执行时机
适用场景复杂逻辑计算(如A星寻路)、网络消息接收异步加载(文件、场景)、批量创建对象
生命周期管理需手动关闭,否则会持续运行组件或物体销毁、物体失活时停止(组件失活除外)

7.特殊文件夹

路径/文件夹获取方式创建要求读写权限打包后状态典型用途注意事项
Application.dataPathprint(Application.dataPath)自动生成(无需创建)编辑模式:可读可写
发布后:只读
包含所有资源(只读)编辑模式调试路径(如加载外部配置)发布后不可写,避免运行时修改
Resources无(通过Resources.Load访问)手动创建(Assets下)编辑/发布:只读压缩加密(仅Resources.Load可用)动态加载资源(如UI预制体、音效)打包后无法直接访问路径,避免存放过大资源
StreamingAssetsprint(Application.streamingAssetsPath)手动创建(Assets下)编辑/PC:可读可写
移动:只读
不压缩(保留原始格式)存放需自定义加载的初始资源(如AB包、配置文件)移动平台(Android/iOS)仅可读,PC可读写
persistentDataPathprint(Application.persistentDataPath)自动生成(无需创建)全平台:可读可写不打包(运行时生成)存储动态数据(如用户存档、下载资源)路径唯一,适合热更新和持久化存储(推荐使用)
Plugins无(自动识别)手动创建(Assets下)编辑/发布:只读包含插件(按需编译)存放平台专属插件(如iOS/Android SDK)不同平台文件需分目录(如Plugins/iOS/Android
Editor无(仅编辑器可见)手动创建(Assets下)仅编辑器:可读可写不打包(编辑器脚本专用)存放编辑器扩展脚本(如自定义面板)内容不会打入游戏包,编辑器模式下生效
Editor无(仅编辑器可见)手动创建(Assets下)仅编辑器:可读可写不打包(编辑器脚本专用)存放编辑器扩展脚本(如自定义面板)内容不会打入游戏包,编辑器模式下生效
Standard Assets无(自动识别)手动创建(Assets下)编辑/发布:只读包含资源(正常打包)存放Unity官方标准资源或项目基础资源,如角色控制器、物理组件等避免滥用,按需提取资源;处理好编译顺序冲突;编辑器脚本放子级Editor文件夹

8.Resources

8.1.同步加载

方法说明参数/返回值示例代码适用场景注意事项
Resources.Load(path)同步加载资源(最常用)path: 资源路径(无扩展名)
返回: Object
GameObject cube = Resources.Load<GameObject>("Prefabs/Cube");小资源(UI、音效)阻塞主线程,大资源慎用
LoadAll(path)加载文件夹下所有资源(按类型过滤)path: 文件夹路径
返回: Object[]
Object[] textures = Resources.LoadAll("Textures");批量加载同目录资源同名资源按类型区分,需强制转换
Load<T>(path)泛型加载(自动类型转换)T: 目标类型
返回: T
AudioClip bgm = Resources.Load<AudioClip>("Music/BGM");明确类型的资源(推荐)无需手动as,代码更简洁
GameObject 加载需配合Instantiate实例化-Instantiate(Resources.Load<GameObject>("Player"));预制体动态生成直接加载GameObject不实例化会占用内存,但无法卸载

8.2.异步加载

方法说明执行机制示例代码适用场景核心优势
LoadAsync<T>(path)异步加载(返回ResourceRequest新开线程加载,主线程检测完成ResourceRequest req = Resources.LoadAsync<Texture>("BigTex");大资源(模型、高清纹理)避免主线程卡顿
回调监听req.completed += OnLoadEnd;加载完成触发回调void OnLoadEnd(AsyncOperation op) { tex = op.asset as Texture; }简单加载后逻辑代码简洁,不支持多资源并行加载
协程加载yield return req;while (!req.isDone)协程分时检测加载状态IEnumerator LoadCoroutine() { yield return req; 渲染纹理(); }复杂逻辑(如进度条、多资源)支持并行加载,灵活控制加载流程
进度跟踪req.progress(0~1,非精确)实时获取加载进度progressBar.value = req.progress;显示加载进度条移动端可能因压缩导致进度跳跃

8.3.资源卸载

方法说明适用资源示例代码最佳实践禁忌
UnloadAsset(asset)卸载指定资源(非GameObject)纹理、音效、文本等非实例化资源Resources.UnloadAsset(tex);释放不再使用的单次加载资源禁止卸载GameObject预制体(会报错)
UnloadUnusedAssets()卸载未使用的缓存资源(配合GC.Collect所有未引用的Resources资源Resources.UnloadUnusedAssets(); GC.Collect();场景切换时清理内存需在主线程调用,避免频繁调用
GameObject 卸载实例化对象需Destroy()释放实例化的预制体Destroy(instance.gameObject);动态生成的对象(如子弹、UI)仅销毁实例,预制体缓存仍存在

9.SceneManager

9.1.场景同步加载

  • 实现方式:使用 SceneManager.LoadScene 进行场景同步加载,需引用 UnityEngine.SceneManagement 命名空间。
using UnityEngine.SceneManagement;

// 场景同步切换
SceneManager.LoadScene("Lesson21_场景异步加载Test");
  • 缺点:切换场景时,Unity 会删除当前场景的所有对象,并加载下一个场景的相关信息。若当前场景或下一个场景的对象过多,该过程会非常耗时,导致玩家感受到卡顿。

9.2.场景异步加载

9.2.1 事件回调异步加载场景
  • 原理:利用 SceneManager.LoadSceneAsync 方法在后台异步加载场景,通过 AsyncOperation 类的 completed 事件回调来处理加载完成后的逻辑。
   // 封装的场景异步加载方法
    private void LoadSceneAsyncWithCallback(string sceneName)
    {
        // 异步加载场景
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName);
        // 加载完成回调
        asyncOperation.completed += (aO) =>
        {
            print("加载结束");
        };
        asyncOperation.completed += AsynLoadOver;
    }

    // 异步加载场景回调
    private void AsynLoadOver(AsyncOperation ao)
    {
        print("AsynLoadOver");
    }
  • 注意事项:即使过场景时脚本或脚本依附的对象被销毁,异步加载的回调依然能够执行,因为回调被存储在事件中。
9.2.2 协程异步加载场景
  • 原理:通过协程调用 SceneManager.LoadSceneAsync 进行异步加载,在加载过程中可以执行其他逻辑,如更新进度条。
    // 异步加载场景协程函数
    IEnumerator CoroutineAsynLoadScene(string name)
    {
        // 异步加载场景
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(name);

        print("异步加载过程中打印的信息");

        // 利用场景异步加载的进度更新进度条(不太准确)
        while (!asyncOperation.isDone)
        {
            print(asyncOperation.progress);
            yield return null;
        }

        // 等待异步加载结束
        yield return asyncOperation;
        print("异步加载结束后打印的信息");

        // 也可根据游戏规则自定义进度条变化条件
    }
}

9.3常用方法和属性

分类属性/方法描述
属性activeScene获取或设置当前的活动场景,活动场景是当前正在运行的场景,一些操作会基于活动场景
属性sceneCount获取当前加载的场景数量,在管理多个同时加载的场景时有用
属性sceneCountInBuildSettings获取Build Settings中场景的总数,可了解项目中总共包含的场景数量
方法GetSceneAt(int index)根据索引获取已加载的场景,索引从0开始,范围是0到sceneCount - 1
方法GetSceneByName(string name)根据场景名称获取已加载的场景,若未找到则返回空的Scene对象
方法GetSceneByPath(string path)根据场景的路径获取已加载的场景,路径是相对于项目的Assets文件夹的路径
方法UnloadSceneAsync(int sceneBuildIndex)异步卸载指定索引的场景,卸载场景会释放该场景占用的内存资源
方法UnloadSceneAsync(string sceneName)异步卸载指定名称的场景,卸载场景会释放该场景占用的内存资源

10.LineRenderer

10.1.LineRenderer组件参数

分类参数说明常用值/操作
场景点编辑Simplify Preview开启后线段预览更明显(简化密集点显示)勾选(调试用)/ 取消(正式)
Tolerance点简化宽容度(值越大,线段越粗略,忽略密集点)1(默认,密集点时调大)
编辑点操作Subdivide Selected框选相邻点后插入新点(用于细化拐角)鼠标框选+点击(需启用编辑模式)
添加点模式Input Mode点创建方式:
- Mouse Position:摄像机位置创建(少用)
- Physics Raycast:射线碰撞点创建(常用)
Physics Raycast(勾选)
LayerMask射线检测层(仅响应指定层的点击,如地面、UI)勾选目标层(如“Ground”“UI”)
Min VertexDistance拖动创建点的最小间隔(避免过密)0.1~0.5米(根据手感调整)
通用属性Loop首尾点连接(闭合图形/开放线段)true(攻击范围)/ false(轨迹线)
PositionCount线段总点数(需先设置,再赋值)2(直线)~ 100(复杂曲线)
Use World Space坐标系模式:
- true:世界坐标(固定)
- false:本地坐标(随物体移动)
false(角色激光线)
渲染属性Start/End Width线段首尾宽度(支持曲线插值)0.01f(纤细)~ 0.5f(粗壮)
Start/End Color线段渐变颜色(需材质支持)Color.red → Color.blue(渐变)
Corner/End Vertices拐角/末端圆角精度(值越大越圆滑)2(默认)~ 5(高精度圆角)
Material线段材质(支持纹理/着色器,如火焰、激光)自定义材质(需关联主纹理)
光照相关Generate Lighting Data启用光照计算(材质需光源,如标准着色器)true(有光照场景)/ false(无光照)
Cast/Receive Shadows投射/接收阴影(增加场景真实感)按需勾选(默认关闭以优化性能)
高级设置Alignment线段对齐方式:
- View:始终朝向相机
- Transform Z:沿物体Z轴方向
View(UI指引线)/ Transform Z(模型轮廓)
Texture Mode纹理映射模式:
- Stretch:单次拉伸
- Tile:平铺重复
Stretch(激光纹理)/ Tile(铁链纹理)
性能优化Dynamic Occludee动态遮挡剔除(减少不可见线段渲染)勾选(复杂场景)
排序控制Sorting Layer渲染层级(避免被UI遮挡)自定义层级(如“Foreground”)

10.2.LineRenderer参数和方法

功能API说明注意事项
动态创建线段AddComponent<LineRenderer>()GameObject 添加 LineRenderer 组件需先创建空物体
设置闭合状态lineRenderer.loop = true;闭合线段(首尾相连)需配合 PositionCount ≥ 2
设定宽度lineRenderer.startWidth = 0.02f;
lineRenderer.endWidth = 0.02f;
设置线起点和终点处的宽度,支持动态修改实时刷新需在 Update 中调用
设定颜色lineRenderer.startColor = Color.white;
lineRenderer.endColor = Color.red;
设置线起点和终点处的颜色,支持动态修改实时刷新需在 Update 中调用
设置材质material = Resources.Load<Material>("火焰材质");
lineRenderer.material = material;
赋值自定义材质,支持纹理动画材质需包含主纹理(Main Tex)
设置点个数lineRenderer.positionCount = 4;设置或获取顶点数设置点时,要先设置点的个数
批量设置点lineRenderer.SetPositions(new Vector3[] { new Vector3(0,0,0),new Vector3(0,0,5), new Vector3(5,0,5)});一次性设置所有点需先定义 PositionCount,数组长度需 ≤ PositionCount
单点修改lineRenderer.SetPosition(3, new Vector3(5, 0, 0));单独修改某点坐标index 从 0 开始,坐标基于 useWorldSpace 的设置
坐标系切换lineRenderer.useWorldSpace = false;切换为本地坐标系(线段随物体移动)动态切换需谨慎,可能导致坐标混乱
设置光照影响lineRenderer.generateLightingData = true;配置线以生成法线和切线,让场景光照影响线若材质需要光照效果,需开启此选项

11.物理系统-范围检测

11.1.范围检测基础

分类要点关键细节
定义瞬时检测指定范围内的对象(无实体碰撞器,仅计算)用于攻击范围、触发判定等瞬时逻辑
必备条件- 对象需含碰撞器(Collider)
- 检测代码执行时触发(非持续检测)
无刚体也可检测(区别于碰撞事件)
层级过滤LayerMask 位运算(左移+或运算)1 << LayerMask.NameToLayer("Enemy") 表示仅检测Enemy层
触发器处理QueryTriggerInteraction 枚举:
- UseGlobal(全局设置)
- Collide(检测触发器)
- Ignore(忽略触发器)
全局设置路径:Edit > Project Settings > Physics > Queries Hit Triggers

11.2.核心方法

API形状参数返回值典型场景优化建议
OverlapBox盒状中心坐标, 半尺寸, 旋转, 层掩码, 触发器模式Collider[](动态数组)矩形攻击范围(如地刺、AOE)避免高频调用(每次生成新数组)
OverlapBoxNonAlloc盒状中心坐标, 半尺寸, 预分配数组, 层掩码, 触发器模式int(碰撞数)高频检测(如每帧扫描)预分配数组(colliders = new Collider[10])减少GCAlloc
OverlapSphere球形中心坐标, 半径, 层掩码, 触发器模式Collider[](动态数组)圆形范围(如角色拾取、技能半径)配合LayerMask过滤非目标层
OverlapSphereNonAlloc球形中心坐标, 半径, 预分配数组, 层掩码, 触发器模式int(碰撞数)性能敏感场景(如子弹爆炸检测)提前计算半径(避免重复计算)
OverlapCapsule胶囊状端点1, 端点2, 半径, 层掩码, 触发器模式Collider[](动态数组)柱状范围(如角色近战攻击、NPC视野)Vector3.ProjectOnPlane计算地面投影
OverlapCapsuleNonAlloc胶囊状端点1, 端点2, 半径, 预分配数组, 层掩码, 触发器模式int(碰撞数)复杂地形检测(如爬墙判定)缓存端点坐标(减少重复赋值)

12.射线检测

分类核心内容关键细节
基础概念瞬时发射射线,检测与碰撞器的交点(无实体,仅计算)适用:鼠标选择、射线攻击、视线阻挡判定
条件:目标需有碰撞器(无需刚体)
Ray 类- 构造:new Ray(origin, direction)
- 摄像机射线:Camera.ScreenPointToRay(鼠标位置)
origin:射线起点
direction:方向向量(非终点)
屏幕点转射线用于UI/场景交互
核心APIPhysics.Raycast(单碰撞)
参数:(射线/起点, 方向, out 碰撞信息, 距离, 层掩码, 触发器模式)
返回:bool
用途:检测首个碰撞目标(如射击命中)
层掩码:1 << 层号(如1 << 8
Physics.RaycastAll(多碰撞)
参数:(射线/起点, 方向, 距离, 层掩码, 触发器模式)
返回:RaycastHit[](无序数组)
用途:获取所有碰撞目标(如区域内敌人)
Physics.RaycastNonAlloc(预分配)
参数:(射线/起点, 方向, 预分配数组, 距离, 层掩码, 触发器模式)
返回:int(碰撞数)
优化:避免GCAlloc,适合高频检测(如每帧扫描)
RaycastHit- collider:碰撞器
- point:交点坐标
- normal:碰撞面法线
- distance:起点到交点距离
normal用于特效朝向(如弹孔法线对齐)
point用于生成命中特效(如子弹痕迹)
参数顺序必记顺序
1. 射线/起点
2. 方向(非必填,重载支持)
3. out 碰撞信息(单碰撞)
4. 距离(0=无限)
5. 层掩码
6. 触发器模式
易错:层掩码误填为第2参数(正确:第4/5位)
示例:Raycast(ray, out hit, 100, 1<<8)
触发器处理QueryTriggerInteraction枚举:
- Collide(检测触发器)
- Ignore(忽略)
- UseGlobal(全局设置)
全局设置路径:Project Settings > Physics > Queries Hit Triggers(默认检测触发器)
性能优化- 预分配数组:RaycastHit[] hits = new RaycastHit[10]
- 缓存射线:避免重复创建(如Camera.main缓存)
NonAllocRaycastAll少生成临时数组,适合高频场景(如技能检测)
典型场景1. 鼠标选物体ScreenPointToRay + Raycast(层过滤UI)
2. 射线攻击:检测首个碰撞目标(distance限制射程)
3. 视线阻挡Raycast返回distance与预设值比较
示例:FPS射击检测墙体遮挡:if (hit.distance < 敌人距离) 被遮挡

三、Unity核心

1.图片纹理

1.1.Unity支持的图片格式

BMP:是Windows操作系统的标准图像文件格式,特点是几乎不进行压缩,占磁盘空间大。
TIF:基本不损失图片信息的图片格式,缺点是体积大。
JPG:一般指JPEG格式,属于有损压缩格式,能够让图像压缩在很小的存储空间,一定程度上会损失图片数据,无透明通道。
PNG:无损压缩算法的位图格式,压缩比高,生成文件小,有透明通道。
TGA:支持压缩,使用不失真的压缩算法,还支持编码压缩。体积小,效果清晰,兼备BMP的图像质量和JPG的体积优势,有透明通道。
PSD:是PhotoShop(PS)图形处理软件专用的格式,通过一些第三方工具或自制工具可以直接将PSD界面转为UI界面。
此外,Unity还支持EXR、GIF、HDR、IFF、PICT等格式。其中,在Unity中最常用的图片格式是JPG、PNG和TGA三种。

1.2.纹理类型参数

纹理类型描述相关参数及解释
Default(默认)大部分导入的模型贴图都是该类型无特殊参数
sRGB(Color Texture)(sRGB颜色纹理)启用可以将纹理存储在伽马空间中(对每一个像素做一次幂函数运算),一般勾选。
人眼看线性渐变的图片会感觉不是线性的,要用伽马控件校正,校正后的图片人眼看是线性渐变的
sRGB(Color Texture):一般勾选,用于伽马校正
Alpha Source(Alpha源)指定如何生成纹理的Alpha通道- None:无论输入纹理是否有Alpha通道,导入的纹理都没有Alpha通道
- Input Texture Alpha:使用输入纹理中的Alpha通道
- From Gray Scale:从输入纹理RGB值的平均值生成Alpha,一般不用
Alpha Is Transparency(Alpha是透明的)启用可以避免边缘上的过滤瑕疵一般启用
Normal map(法线贴图)法线贴图格式:在原物体的凹凸表面的每个点上均作法线(法线是垂直于某个点的切线的方向向量)。
游戏中有时不使用高精度、多三角面片的模型(避免卡顿),记录高精度模型的各个点的法线做成法线贴图,在低精度模型中,通过法线贴图和一些着色器算法,在三角面片更少的低精度模型里能得到效果更好、看起来更高精度的效果
- Create From Grayscale:启用此属性可以从灰度高度贴图创建法线贴图
- Bumpiness:控制凹凸程度,值越大凹凸感越强
- Filtering:
   - Sharp:生成比标准模式更锐利的法线贴图
   - Smooth:使用标准算法生成法线贴图
Editor GUI and Legacy GUI(编辑器GUI和旧功能GUI)一般在编辑器中或者GUI上使用的纹理无特殊参数
Sprite(2D and UI)(精灵(2D和UI))2D游戏或者UGUI中使用的格式- Sprite Mode:
   - Single:按原样使用精灵图像,图片是一张图(非图集)就选这个选项
   - Multiple:瓦片模式,如果是图集,使用该选项,可以在Sprite Editor编辑窗口自定义图片
   - Polygon:网格精灵模式,如果图片或者图集是多边形可以选择这种模式
- Pixels Per Unit:世界空间中的一个距离单位(Unity中为一米)对应多少像素
- MeshType(只有Sprite模式是Single模式和Multiple模式才支持,因为Polygon模式可自定义多边形大小):
   - Full Rect:创建四边形,将精灵显示在四边形上,若图片为三角形,渲染到3D引擎里会创建矩形做成两个三角面片来渲染
   - Tight:基于像素Alpha值来生成网格,更加贴合精灵图片的形状,任何小于32*32的精灵都使用FullRect模式,即使设置成Tight模式也是,若图片为三角形,渲染到3D引擎里会把三角形切割成几个三角面片来渲染
- Extrude Edges:使用滑动条确定生成的网格中精灵周围留出的区域大小,可理解为三角形图片边的溢出渲染区域的大小
- Pivot(Single模式才有此选项):精灵图片的轴心点,对应九宫格布局的九个点,还可以自定义
- Generate Physics Shape(只有Single 和Multiple模式才可使用,因为Polygon是自己手动设置的):启用此选项,Unity会自动根据精灵轮廓生成默认物理形状,若图片要进行物理判断(如碰撞器或者物理检测),就勾选它
- Sprite Editor:编辑Sprite,需要安装2D Sprite包
Cursor(光标)自定义光标,设置鼠标的图片无特殊参数
Cookie(光源剪影格式)用于设置光照类型的纹理形状- Light Type:
   - Spotlight:聚光灯类型,需要边缘纯黑色纹理,TextureShape纹理形状需设置为2D形状
   - Directional:方向光,平铺纹理,需要设置TextureShape纹理形状为2D形状
   - Point:点光源,需要设置TextureShape纹理形状为立方体形状
Lightmap(光照贴图)光照贴图格式- Single Channel:纹理只需要单通道的格式
- Channel:
   - Alpha:使用Alpha通道,不允许进行压缩
   - Red:使用红色通道

1.3.纹理形状参数

Texture Shape(纹理形状)描述
2D最常用设置,这些纹理将应用于模型和 GUI 元素上
Cube(立方体)主要用于天空盒和反射探针
Mapping(贴图)如何将纹理投影到游戏对象上,具体如下:
- Auto(自动):根据纹理信息创建布局。
- 6 Frames Layout(6 帧布局(立方体环境)):纹理包含以标准立方体贴图布局之一排列的六个图像。
- Latitude-Longitude Layout(纬度精度布局(立方体)):将纹理映射到 2D 维度/经度。
- Mirrored Ball(镜面球):将纹理映射到类似球体的立方体贴图上。
Convolution Type(卷积型)纹理的过滤类型,具体如下:
- None(无):无过滤。
- Specular(镜面(光泽反射)):将立方体作为反射探针。
- Diffuse(漫反射(发光)):将纹理进行过滤表示辐照度,可作为光照探针。
Fixup Edge Seams(固定边缘对接处)适用情况:当 Convolution Type 为 None 和 Diffuse 时才有用。
作用:解决低端设备上立方体贴图过滤错误的问题。

1.4.纹理高级参数设置

参数描述选项及说明
Non - Power of 2(非2次幂)处理纹理尺寸非2的幂的情况。因图形学规则,纹理通常须是2的幂尺寸
  • None:纹理尺寸保持不变
  • ToNearest:将纹理缩放到最接近2的幂的大小(PVRTC格式要求纹理为正方形)
  • ToLarger:将纹理缩放到最大尺寸值的2的幂的大小
  • ToSmaller:将纹理缩放到最小尺寸值的2的幂的大小
Read/Write Enabled(读/写已开启)启用后可使用Unity方法从纹理获取数据一般在需要代码获取图片数据时开启,否则会占内存
Streaming Mipmaps(流式Mipmaps)启用后可使用纹理串流用于控制加载在内存中的Mipmap级别,减少Unity对纹理所需内存总量,用性能换内存
Mip Map Priority(Mipmap优先级)-Unity根据该优先级确定分配资源时优先考虑的Mipmap
Generate Mip Maps(生成MipMaps贴图)允许生成MipMap开启后可在下方图片栏滚动条调整MipMaps尺寸,2D游戏一般不启用,3D游戏视情况而定
Border Mip Maps(边框Mip贴图)-启用可避免颜色向外渗透到较低MIP级别的边缘
Mip Map Filtering(Mip贴图过滤)优化图像质量的过滤方法
  • Box:随着尺寸减小,级别更平滑
  • Kaiser:Mipmap尺寸下降时使用的锐化算法,适用于远处纹理模糊的情况
Mip Maps Preserve Coverage(MipMaps保留覆盖范围)-Mipmap的Alpha通道在Alpha测试期间保留覆盖率
Alpha Cutoff Value(Alpha修剪值)-覆盖率参考值
Fadeout Mip Maps(交叉淡化Mip贴图)-级别递减时使Mipmap淡化为灰色

1.5.纹理平铺拉伸参数

参数描述选项及说明
Wrap Mode(贴图间拼接模式)平铺纹理时的方式。可通过创建四边形面片、材质,拖拽图片,修改平铺拉伸参数和材质的平铺 XY 及偏移来查看效果
  • Repeat(重复):在区块中重复纹理
  • Clamp(钳制):拉伸纹理的边缘
  • Mirror(镜像):在每个整数边界上镜像纹理以创建重复图案
  • Mirror Once(镜像一次):镜像纹理一次,然后将拉伸边缘纹理
  • Per - axis(每轴):单独控制如何在 U 轴和 V 轴上包裹纹理
Filter Mode(过滤模式)纹理在通过 3D 变化拉伸时的过渡方式
  • Point(点):纹理在靠近时变为块状
  • Bilinear(双线性):纹理在靠近时变得模糊,一般常用此模式
  • Trilinear(三线性):与 Bilinear 类似,但纹理也在不同的 Mip 级别之间模糊
Aniso Level以大角度查看纹理时提高纹理质量,但性能消耗高-

1.6.纹理平台打包相关参数

参数描述选项及说明
Max Size(最大尺寸)设置导入纹理的最大尺寸,可将美术提供的大尺寸图片限制在一定范围内,一般选择 2048-
Resize Algorithm(重设大小算法)当纹理尺寸大于指定的 Max Size 时,用于缩小纹理的算法Mitchell:默认米切尔算法,是常用的尺寸缩小算法
Bilinear:使用双线性插值调整大小,对于细节重要的图片,比米切尔算法保留更多细节
Format(格式)纹理格式,各平台支持的格式不同,若选择 Automatic,会根据平台使用默认设置都支持的格式
移动端和网页端特有格式
iOS:选择默认的纹理压缩设置 (PVRTC) 可获得更大兼容性;若应用程序不包含 OpenGL ES 2 支持,可选择 ASTC 格式,该格式质量更好、灵活性更高且压缩速度比 PVRTC 快
Android:因安卓设备众多且标准不一,一般会根据不同设备标准制作多个安装包。
   - 构建以 OpenGL ES 3 为目标的 APK:访问 Android 的 Player Settings(菜单:Edit > Project Settings >Player Settings,然后选择 Android 类别),向下滚动到 Graphics APIs 部分,确保 OpenGL ES 2 不在列表中,然后构建 APK(菜单:File > Build Settings,然后单击 Build)
   - 构建以 OpenGL ES 2 为目标的单独 APK:访问 Android Player Settings,向下滚动到 Graphics APIs 部分,在列表中添加 OpenGL ES 2 并删除 OpenGL ES 3 和 Vulkan,然后构建 APK
Compression(压缩)选择纹理的压缩类型,帮助 Unity 正确选择压缩格式,会根据平台和压缩格式的可用性进行压缩None(无):不压缩纹理
Low Quality(低质量):以低质量格式压缩纹理
Normal Quality(法线质量):以标准格式压缩纹理
High Quality(高质量):以高质量格式压缩纹理,一般选择高质量
Use Crunch Compression(使用 Crunch 压缩)启用后,使用 Crunch 压缩,Crunch 是一种基于 DXT 或 ETC 纹理压缩的有损压缩格式,特点是压缩时间长,解压速度快-
Split Alpha Channel(拆分 Alpha 通道)Alpha 通道分离,可节约内存,会把一张图分成两张纹理,一张包含 RGB 数据,一张包含 Alpha 数据,渲染时再合并渲染-
Override ETC2 fallback(覆盖 ETC2 回退)在不支持 ETC2 压缩的设备上使用的格式-

在这里插入图片描述

2.SpriteEditor精灵编辑器

2.1.Single 图片编辑功能

功能描述
Sprite Editor 基础图片设置Name:设置图片名称。
Position:调整图片在其中的偏移位置以及宽高。
Border:设定九宫格的 4 条边。
Pivot:确定轴心(中心)点的位置。
Pivot Unit Mode:
Normalized:标准化模式,取值在 0 至 1 之间。
Pixels:像素模式,显示当前轴心在图片中的像素位置。
Custom Pivot:自定义轴心点。
Custom Outline 自定义边缘线(决定渲染区域)可自定义精灵网格的轮廓形状。默认在矩形网格上渲染,边缘外部透明区域会被渲染,存在性能浪费。通过自定义轮廓,可缩小透明区域,提升性能。
Snap 捕捉:使控制点贴近最近的像素,默认选择该选项。
Outline Tolerance:控制轮廓点的复杂性和准确性,取值范围 0 至 1,值越大,轮廓点越多,越准确。
Generate:生成网格轮廓,可手动编辑点,修改后需应用。
Custom Physics Shape 自定义物理形状(决定碰撞判断区域)用于自定义精灵图片的物理形状,主要针对需要物理碰撞判断的 2D 图形,确定碰撞检测区域,其参数和操作与自定义边缘线基本相同。
Skinning Editor 皮肤编辑器暂不讲解,后续涉及。
Secondary Textures 辅助纹理(为图片添加特殊效果)可将其他纹理与该精灵图片关联。点击加号添加关联图片作为辅助纹理并命名,着色器可利用这些辅助纹理进行效果处理,赋予精灵其他效果。

2.2.Multiple 图集元素分割

当图片资源为图集时,需将模式设为 Multiple,借助 Sprite Editor 进行图集元素分割:

操作描述
切片操作在 Sprite Editor 窗口中,选中要删除的切片按 Delete 键删除;也可按住鼠标左键用选择框进行切片。若 Delete 键无法删除,可将框移至空白处,点击 Trim 剪裁来删除。
切片设置选中切片可设置其信息,与 Single 模式下图片编辑类似,设置好后可抠出切片图使用。编辑参数后选择切片进行切割,若切割不准确可手动调整,切割后可通过下拉按钮查看切割后的图,可用于制作动画帧图。
分割参数讲解Slice Type 切片类型:
Automatic 自动分割:
Pivot 轴心:设置单张图片轴心点位置。
Custom Pivot 自定义轴心点:自定义轴心点。
Method 方法:
Delete Existing 删除现有:替换已选的任何矩形。
Smart 聪明:尝试创建新矩形并保留或调整现有矩形。
Safe 安全:添加新矩形而不改变已存在的矩形。
Grid By Cell Size 按单元格大小分割:仅适用于规范矩形图集。
Pixel Size 像素大小:设置单元格宽高。
Offset 偏移:设置左上角偏移位置。
Padding 填充:设置与边缘的偏移位置以及矩形间的偏移缝隙。
Keep Empty Rects:决定是否保留空矩形,一般不勾选。
Grid By Cell Count 按单元格数量分割:设置 Column & Row(行列数)。
Trim 剪裁:选中切片单元格,可自动去除单元格上多余的透明部分。

2.3.Polygon 多边形编辑

若使用的资源是多边形资源,可将模式设为 Polygon,在 Sprite Editor 中进行快捷设置,但实际开发中较少使用:

操作描述
多边形编辑参数点击更改形状,可设置边数,范围在 3 至 128 之间。自定义边缘线会自动生成渲染范围,仅显示圈定的图形。需注意,设置为 Polygon 多边形后再改回 Single 模式,需重新选择自定义边缘线生成,否则会保留上次的边缘线。

3.Animator

3.1.Animator 动画器组件参数说明

参数描述选项及说明
Controller(控制器)对应的动画控制器(状态机)-
Avatar(替身)对应的替身配置信息(在讲解 3D 模型时详细讲解)-
Apply Root Motion(应用根运动)是否启用动画位移更新若启用,动画中的位移信息会更新物体的位置;若不启用,物体位置不受动画位移影响
UpdateMode(更新模式)一般不修改该参数
  • Normal(正常更新):按照正常的游戏更新循环进行动画更新
  • Animate Physics(物理更新):与物理系统同步更新动画,适用于动画与物理交互的场景
  • Unscaled Time(不受时间缩放影响):动画更新不受 Time.timeScale 的影响,即使游戏时间被缩放,动画仍按正常速度播放
Culling Mode(裁剪剔除模式)-
  • Always Animate(始终播放动画):无论物体是否在屏幕内,动画都会持续播放,不会被剔除
  • Cull Update Transforms(裁剪更新变换):当摄像机没有渲染该物体时,停止对物体位置、IK(反向运动学)的写入操作,但动画本身可能仍在运行
  • Cull Completely(完全裁剪):当摄像机没有渲染物体时,整个动画被完全禁用,不进行任何计算和更新

3.2.Animator 动画器代码控制

获取 Animator 组件

//我们用代码控制状态机切换主要使用的就是Animator提供给我们的API
//我们知道一共有四种切换条件 int float bool trigger
//所以对应的API也是和这四种类型有关系的
Animator animator = this.GetComponent<Animator>();

Animator.SetXXX 方法:通过状态机条件切换动画

//通过状态机条件切换动画

//设置动画参数状态
// 设置浮点数类型的动画参数
animator.SetFloat("条件名", 1.2f); 
// 设置整数类型的动画参数
animator.SetInteger("条件名", 5); 
// 设置布尔类型的动画参数
animator.SetBool("条件名", true); 
// 设置触发类型的动画参数
animator.SetTrigger("条件名"); 

Animator.GetXXX 方法:获得动画参数状态

//获得动画参数状态
// 获取浮点数类型的动画参数值
animator.GetFloat("条件名"); 
// 获取整数类型的动画参数值
animator.GetInteger("条件名"); 
// 获取布尔类型的动画参数值
animator.GetBool("条件名"); 

// 直接切换动画(除非特殊情况,不然一般不使用)
// 注意:状态名和动画名不一样,动画名拖进来默认名字就是状态名,但是可以修改得和动画名不一样
animator.Play("状态名"); 

3.3 Animator 窗口中动画状态设置相关参数

参数描述选项及说明
Motion(运动)分配给此状态的动画剪辑-
Speed(速度)动画的默认速度-
Multiplier(乘数)控制速度的乘数,需勾选 Parameter 选中配合的 float 类型参数才能使用-
Motion Time(运动时间)运动的时间,需勾选 Parameter 选中配合的 float 类型参数才能使用,一般是 0 - 1 的数字。使用该参数后动画不会自动播放,需设置参数值才会动,如设置成 0.1,动画就卡在进度播放到 0.1 的位置,在 Update 中不断加大参数值可一帧一帧播完动画-
Mirror(镜像)是否为状态生成镜像,仅适用于人形动画,若配合参数使用需选中旁边的 Parameter 关联 bool 类型参数-
Cycle Offset(周期偏移)循环偏移时间,若配合参数使用需选中旁边的 Parameter 关联 float 类型参数。如填 0.5,动画就会从中间位置开始播放-
Foot IK(脚步反向动力学)是否遵循 Foot IK,适用于人形动画-
Write Defaults(写入默认值)AnimatorStates 是否为其运动执行未动画化的属性写回默认值,默认勾选-
Solo(单独播放)仅播放该过渡,条件都满足的动画优先切换选择了 Solo 的动画-
Mute(静音)禁用过渡,就算条件满足也不切换,Solo 和 Mute 一起选择时,Mute 优先执行-
Add Behaviour(添加行为)添加状态机行为脚本,之后会专门讲解-

3.4.Animator 窗口中动画过渡设置相关参数

参数描述选项及说明
连线名为动画过渡改名,若不改对应的名字就是”某一状态名”->”某一状态名”,一般不改-
Has Exit Time(是否有退出时间)若勾选,当切换动画时,动画一定是播放到下方的 Exit Time(百分比)的时间时才过渡到下一个动画;若希望立刻切换动画,可不勾选该选项-
Exit Time(退出时间)当选择上方的 Has Exit Time 时,该值决定了过渡生效的确切时间。该值可以大于 1,若小于 1,比如 0.85,表示当动画播放到了 85%的动画时,就会过渡;若大于 1,比如 4.5,那么动画将循环 4.5 次后过渡到下一个动画-
Fixed Duration(固定持续时间)选中后,下方的 Trnaition Duration 过渡持续时间将以秒为单位解读过渡时间;若不选中,则以百分比解读过渡时间-
Transition Duration(s/%)(过渡持续时间)从该状态切换到下一状态的过渡动画持续的时间,对应下方两个蓝色箭头包裹区域-
Transition Offset(过渡偏移)过渡到目标状态的起始播放的时间偏移。如果是 0 则从要切换到的目标状态开头开始播放,如果是 0.5 则从要切换到的目标状态的一半开始播放,可理解为切入下一个状态的切入点-
Interruption Source(中断源)该过渡中断的情况:
  • None:不在添加任何过渡
  • Current State:将当前状态过渡排队
  • Next State:使下一个状态的过渡进行排队
  • Current State Then Next State:将当前状态的过渡和下一个状态的过渡都依次排队
  • Next State Thne Current State:将下一状态的过渡和当前状态的过渡依次排队
-
Ordered Interruption(有序中断)当前过渡是否可在不考虑顺序的情况下被其它过渡中断:
  • 选中时,找到有效过渡或当前过渡时,会中断
  • 不选中时,找到有效过渡,会中断
-
Conditions(过渡条件)如果没有过渡条件,只会考虑 Exit Time-
Can Transition To self(是否可以过渡到自己)是否可以过渡到自己,一般取消勾选-
Preview source state(预览源状态)预览各种过渡状态,可以查看从任意状态切换到当前状态的过渡效果-

3.5. 动画分层和遮罩

参数描述选项及说明
Weight(权重)当动画同时播放且为叠加状态时,根据权重决定叠加的比例-
Mask(动画遮罩)该层动画全部受此遮罩影响,需创建遮罩文件并赋值给该参数。遮罩文件可设置不受影响的区域,动画播放时该区域无效果,类似模型文件 Animation 页签下的选项效果,但只影响这一层-
Blending(混合方式)
  • Override:覆盖方式,播放该层动画时忽略其他层信息
  • Additive:叠加方式,会和其它层动画叠加播放
-
Sync(是否同步其它层)主要用于直接从另一个层复制状态过来并在该层中修改。适用于正常状态和受伤状态等动作改变的情况。选择后会多一个 Source Layer 表示要复制哪一层的状态,如复制普通层 1 并修改动画选项为蹲下的待机和走路,调大这一层的权重就会播放蹲下的待机和走路-
Timing(源层)当选中 Sync 同步其它层时激活。
  • 选中:采用折中方案调整同步层上的动画时长(基于权重计算)
  • 不选中:动画时长将使用原始层做为母版
-
IK Pass(IK 处理)反向动力学-

3.6.动画融合树

3.6.1.动画 1D 混合
参数描述选项及说明
Parameter(参数)用于控制混合的参数,在参数列表中的参数。蓝色图像可控制 n 个动画的阈值,调整红色指针可在预览窗口查看动画混合情况例如,调整代表 Speed 参数数值的红色指针,0 时动画完全是默认,0.25 是走路和默认结合,0.5 是完全走路,0.75 是走路和跑步结合各一半,1 是完全跑步
Motion(关联的动画列表)可使用鼠标改变顺序-
Threshold(对应动作的临界阈值)当等于这个值时动作权重最大(完全播放该动作),数值范围不定,需取消勾选 Automate Thresholds 才能手动设置-
控制动作的播放速度--
是否镜像动作--
Automate Thresholds(是否自动设置阈值)会在取值范围内平均分,一般取消勾选以手动控制更准确-
Compute Thresholds(计算阈值的方式)从动画剪辑的根运动中获取数据,包括 Speed(速度)、Velocity X、Y、Z(xyz 上的分速度)、Angular Speed(Rad 、Deg)(角度或者弧度表示的角速度)例如,动画剪辑行走动画时 Speed 速度是 1.5 个单位每秒,慢跑是 2.3 个单位每秒,快跑是 4 个单位每秒,阈值就会根据这些值来进行设置进行混合
Adjust Time Scale(调整时间刻度)
  • Homogeneous Speed:均匀速度
  • Reset Time Scale:重置时间刻度
-
3.6.2.动画2D 混合
种类描述使用场景
2D Simple Directional(2D 简单定向模式)运动表示不同方向时使用比如向前、后、左、右走,若只有一个动作用此模式
2D Freeform Directional(2D 自由形式定向模式)运动表示不同方向时使用,可在同一方向上有多个运动比如向前跑和走,若一个方向上有走路和跑步用此模式
2D Freeform Cartesian(2D 自由形式笛卡尔坐标模式)运动不表示不同方向时使用比如向前走不拐弯、向前跑不拐弯、向前走右转、向前跑右转
Direct(直接模式)自由控制每个节点权重一般用于做表情动作等

2D 混合的使用:大体上和 1D 混合相似,只是多关联了一个参数,关联的动画也多设置了一个预制。拖动蓝色框上的红点(类似 1D 混合的红色指针)或混合树的进度条可修改参数值查看效果。

3.7. 3D 动画其他相关知识

3.7.1. 动画子状态机

概念:子状态机是在状态机里包含的另一个状态机。当某一个状态由多个动作状态组合成复杂状态时,如角色技能由跳起、攻击、落下三段动作组成,可将这些动作放在子状态机中。
创建方法:在 Animator Controller 窗口中右键选择 Create Sub-State Machine 来创建。

3.7.2.动画目标匹配

概念:当游戏中角色以某种动作移动后,其手或脚需落在特定位置,如跳过踏脚石、跳跃抓住房梁等。以跳跃动作为例,可使角色跳到实际游戏中不同高度的平面。
实现方式:利用 Unity 中 Animator 的 MatchTarget 函数。步骤为找到动作关键点位置信息(如起跳点、落地点)并传入该函数。
代码示例

if( Input.GetKeyDown(KeyCode.Space) )
{
    animator.SetTrigger("Jump");
    
    //Animator中的MatchTarget方法
    //自动调整 GameObject 的位置和旋转。
    //参数一:目标位置
    //参数二:目标角度
    //参数三:匹配的骨骼位置
    //参数四:位置和角度权重
    //参数五:开始位移动作的百分比 这个参数要观察起跳瞬间动画播放了百分之多少
    //参数六:结束位移动作的百分比 这个参数要观察落地瞬间动画播放了百分之多少
    animator.MatchTarget(targetPos.position, targetPos.rotation, AvatarTarget.RightFoot, new MatchTargetWeightMask(Vector3.one, 1), 0.4f, 0.64f);
}
3.7.3.状态机行为脚本

状态机行为脚本使用方法:新建脚本继承 StateMachineBehaviour 基类,实现特定方法进行状态行为监听,包括 OnStateEnter(进入状态时,第一个 Update 中调用)、OnStateExit(退出状态时,最后一个 Update 中调用)、OnStateIK(OnAnimatorIK 后调用)、OnStateMove(OnAnimatorMove 后调用)、OnStateUpdate(除第一帧和最后一帧,每个 Update 上调用)、OnStateMachineEnter(子状态机进入时调用,第一个 Update 中调用)、OnStateMachineExit(子状态机退出时调用,最后一个 Update 中调用)。
代码示例

// 重写该函数,当进入指定状态时调用
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    // 当前状态名称与所需状态名称相同时输出日志
    if (stateInfo.IsName(stateName))
        Debug.Log("进入HumanoidIdle状态");
}

// 重写该函数,当退出指定状态时调用
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    // 当前状态名称与指定名称相同时输出日志
    if (stateInfo.IsName("HumanoidIdle"))
        Debug.Log("退出HumanoidIdle状态");
}

// 重写该函数,当进行动画 IK 计算时调用
public override void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    base.OnStateIK(animator, stateInfo, layerIndex);
}

// 重写该函数,当进行动画更新时每帧调用
public override void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    base.OnStateMove(animator, stateInfo, layerIndex);
}

// 重写该函数,当进行动画更新时每帧调用
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    base.OnStateUpdate(animator, stateInfo, layerIndex);
    // 当前状态名称为指定名称时输出日志
    if (stateInfo.IsName("HumanoidIdle"))
        Debug.Log("处于HumanoidIdle状态");
}

// 重写该函数,当进入状态机时调用
public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
{
    base.OnStateMachineEnter(animator, stateMachinePathHash);
}

// 重写该函数,当退出状态机时调用
public override void OnStateMachineExit(Animator animator, int stateMachinePathHash)
{
    base.OnStateMachineExit(animator, stateMachinePathHash);
}
3.7.4.状态机复用

概念:游戏开发中,多个对象(如多个玩家和怪物)动画状态机行为一致但动作不同时,为避免重复创建状态机浪费时间,状态机复用用于为不同对象使用共同的状态机行为,减少工作量,提升开发效率。
选择依据:状态机行为脚本相对动画事件更准确,但使用稍麻烦,可根据实际需求选择。

状态机复用:在 Project 窗口右键选择 Create -> Animator Override Controller,为 Animator Override Controller 文件在 Inspector 窗口关联基础的 Animator Controller 文件,再关联需要的动画。
`

4.模型导入

4.1.Model模型页签

4.1.1.Scene 场景相关设置
参数描述选项及说明
Scale Factor(缩放系数)当模型比例不符合项目预期时,修改此值可改变模型全局比例。Unity 物理系统希望游戏世界 1 米在导入模型文件中为 1 个单位-
Convert Units(转换单位)启用后可将模型文件定义的比例转换为 Unity 的比例不同格式比例:
- .fbx.max.jas = 0.01
- .3ds = 0.1
- .mb.ma.lxo.dxf.blend.dae = 1
Import BlendShapes(导入 BlendShapes)是否允许 Unity 随网格导入混合形状,导入含混合形状的网格时用 Skinned MeshRenderer 组件注意:
- 导入混合形状需 FBX 文件有平滑组
- 若导入有法线的混合形状,需将 Blend Shape Normals 属性设为 Import 用 FBX 法线信息,或设为 Calculate 让 Unity 计算法线
Import Visibility(导入可见性)是否导入可见性,开启可从 FBX 文件读取可见性属性一些 3D 建模软件对可见性属性有限制,需根据软件决定是否勾选,一般可不勾选
Import Cameras(导入相机)是否导入 FBX 文件中的摄像机,Unity 支持部分摄像机属性一般不勾选
Import Lights(导入灯光)是否导入光源,支持多种光源类型和属性一般不使用
Preserve Hierarchy(保持层次结构)始终创建一个显示预制体根若多个 FBX 文件含同一层级空根对象,勾选可保留它们,避免层级不匹配影响动画播放
Sort Hierarchy By Name(按名称对层级视图排序)在层级窗口根据名字排序子物体不启用则保留 FBX 文件定义的层级顺序
4.1.2.Meshes 网格相关设置
参数描述选项及说明
Mesh Compression(网格压缩)设置压缩比减小网格文件大小,提高压缩比降低网格精度
- Off:不压缩
- Low:低压缩比
- Medium:中等压缩比
- High:高压缩比
Read/Write Enabled(读/写已启用)是否开启读写网格信息开启:Unity 传网格数据给 GPU 后,CPU 保留可寻址内存,可通过代码访问处理;关闭:传数据给 GPU 后,删除 CPU 可寻址内存中网格数据。开启增加内存占用,关闭节约运行时内存。开启场景:
- 需要在代码中读写网格数据
- 需要运行时合并网格
- 需要使用网格碰撞器
- 需要运行时用 NavMesh 构建组件烘焙 NavMesh 等
Optimize Mesh(优化网格)确定三角形在网格中列出的顺序以提高 GPU 性能
- Nothing:无优化
- Everything:对顶点及多边形顶点索引重新排序
- Polygon Order:仅对多边形重新排序
- Vertex Order:仅对顶点重新排序
Generate Colliders(生成碰撞器)启用后自动附加网格碰撞器导入网格建议不移动的环境几何体开启,移动的几何体不开启
4.1.3.Geometry 几何体相关设置
参数描述选项及说明
Keep Quads(保留四边形)启用后,Unity 不将 4 个顶点的多边形转为三角形使用曲面细分着色器时可能需启用,顶点数超四的多边形始终转为三角形。有四边形和三角形的网格,Unity 会创建两个子网格分离它们
Weld Vertices(焊接顶点)合并空间中共享相同位置且属性相同的顶点开启可减少网格顶点计数优化网格,除非想保留重复顶点用于代码处理,一般开启
Index Format(索引格式)网格索引缓冲区的大小一般选 16bits,Auto 可能默认选 16bits,必要时用 32bit,16bits 通用且节约内存
Legacy Blend Shape Normals(旧版混合形状法线)启用后基于 Smoothing Angle 值计算法线-
Normals(法线)定义如何计算法线
- Import:从文件导入法线,文件无则用 Calculate 模式计算
- Calculate:根据 Normals Mode、Smoothness Source 和 Smoothing Angle 属性计算
- None:不计算法线
Blend Shape Normals(混合形状法线)定义如何为混合形状计算法线,仅当 Legacy Blend Shape Normals 禁用时出现-
Normals Mode(法线模式)计算法线的模式,仅当 Normals 设为 Import 或 Calculate 时出现
- Unweighted Legacy:2017.1 版本前计算法线的方式,之前导入的 FBX 模型默认设置
- Unweighted:法线不加权重
- Area Weighted:法线按图面面积加权重
- Angle Weighted:法线按每个图面上的顶角加权重
- Area And Angle Weighted:法线按图面面积和顶角加权重,默认选项
Smoothness Source(平滑度源)确定平滑的方式,仅当 Legacy Blend Shape Normals 禁用时出现
- Prefer Smoothing Groups:尽可能用模型文件中的平滑组
- From Smoothing Groups:仅用模型文件中的平滑组
- From Angle:用 Smoothing Angle 值确定平滑边
- None:不拆分硬边的任何顶点
Smoothing Angle(平滑角度)控制是否为硬边拆分顶点,值越大顶点越少仅当 Normals 设为 Calculate 时可用,仅用于非常光滑或复杂的模型,否则建议在 3D 建模软件中手动平滑后导入
Tangents(切线)定义如何导入或计算顶点切线,仅当 Normals 设为 Calculate 或 Import 时可用
- Import:Normals 为 Import 时,从 FBX 文件导入顶点切线,无切线则无法用法线贴图着色器
- Calculate Legacy:用旧版算法计算切线
- Calculate Legacy With Split Tangents:用旧版算法计算切线并在 UV 图表上拆分,网格接缝影响法线贴图光照时使用
- Calculate Mikktspace:用米克特空间计算切线
- None:不导入顶点切线,无切线则无法用法线贴图着色器
Swap UVs(交换 UVs)在网格中交换 UV 通道,漫反射纹理使用光照贴图中的 UV 时使用-
Generate Lightmap UVs(生成光照贴图 UVs)为光照贴图创建第二个 UV 通道-

4.2.Rig操纵骨骼页签

4.2.1. Animation Type(动画类型)
类型描述
None(不存在动画)主要用于环境静态模型,如石头等。
Humanoid(人形模型)一般有头和四肢(一个头、两条腿、两只手)的模型视为人形模型,需要使用 Avatar 化身系统,绑定人体主要关节的映射关系。
- Avatar Definition(选择获取 Avatar 定义的位置)
- No Avatar:没有化身系统信息。
- Create From This Model:根据此模型创建 Avatar 化身信息。
- Copy from Other Avatar:指向另一个模型上设置的 Avatar 化身信息,需指定 Source(复制另一个具有相同骨架的 Avatar 化身信息以导入其动画剪辑)。
- Skin Weights(蒙皮权重):设置影响单个顶点的最大骨骼数量。
- Standard(4 Bones)标准:使用最多 4 个骨骼产生影响,出于性能考虑,建议使用此设置。
- Custom 自定义:可设置自定义的最大骨骼数,选择后会出现以下选项:
- Max Bones/Vertex:定义每个顶点的最大骨骼个数,值越大性能消耗越大。
- Max Bone Weight:设置考虑骨骼权重的最低阈值,权重计算时将忽略小于此值的内容。
- Optimize Game Objects(优化游戏对象):在 Avatar 化身系统和 Animator 动画组件中删除和存储所导入角色的游戏对象骨骼层级信息。启用后会出现 Extra Transforms to Expose 选项,角色将使用 Unity 动画系统的内部骨架,可提高动画角色的性能,一般不勾选。
- Extra Transforms to Expose(要暴露的额外变换):要公开的骨骼层级,可在下方打钩公开该骨骼层级信息。有放大镜(通过名称搜索对应骨骼信息)、Toggle All(全选或者反选)、Collapse All(全部折叠)、Expand All(全部展开)等操作。
Generic(通用模型,非人形模型)不是标准的人形模型,形状任意,如可能有 8 只腿、两个头等。这种模型主要需要设置骨骼根节点。Root Node(根节点):选择用于此 Avatar 的根节点的骨骼(仅当选择 Create From This Model 才会出现)。
Legacy(旧版动画类型)与 Unity3.x 及更早版本导入和使用动画,一般不使用。
4.2 2. Muscles&Settings(肌肉与设置)
  • Muscle Group Preview(肌肉群预览):可预览不同姿势的旋转变化,观察之前的关联映射关系是否合理,主要起预览作用,可拖拽关节点查看关节旋转效果。
  • Per - Muscle Settings(肌肉设置):用于设置各骨骼在旋转时的范围限制,避免在极限角度出现奇怪效果,可单独设置限制范围。
  • Additional Settings(高级设置):可以设置手脚的扭转和伸展值,一般不修改。其中 Translation DoF 比较重要:
    • 如果启用,将启用人形角色的移动动画,可进行骨骼的位置移动,但可能导致其他骨骼拉长。
    • 如果禁用,Unity 仅使用旋转对骨骼进行动画化。启用后会提升性能消耗,因为动画需要执行额外步骤来重定向人形动画,除非动画包含角色某些骨骼的动画式移动,否则一般禁用。
  • Muscles 肌肉下拉框:可重置所有设置。

4.3.Animation动画页签

4.3.1.导入相关参数设置
参数描述选项及说明
Import Constraints(导入约束)从此资源导入约束启用后,Unity 会自动添加相应的约束组件并关联到正确的游戏对象
Import Animation(导入动画)从此资源导入动画禁用时,其下方相关设置都不可用,且不会导入任何动画
Bake Animations(烘焙动画)通过反向动力学(IK)或模拟创建的动画以便推进运动关键帧,仅用于 Maya、3Dmax 和 Cinema4D 文件-
Anim.Compression(动画压缩类型)导入动画时使用的压缩类型
  • Off:禁用动画压缩,导入时 Unity 不会减少关键帧数量,效果最好但性能低、文件大、运行时内存占用大,通常不建议使用
  • Keyframe Reduction:减少冗余关键帧,仅适用于 Generic 通用动画类型,一般选择此项
  • Keyframe Reduction and Compression:减少关键帧并在存储动画时压缩关键帧,影响文件大小,内存大小与 Keyframe Reduction 相同,仅适用于 Legacy 旧版动画类型
  • Optimal:让 Unity 决定如何压缩,仅适用于 Generic 通用和 Humanoid 人形动画类型
Rotation Error(旋转错误)设置旋转曲线压缩容错度(百分比),即原始旋转值和减小值之间的最小角度仅在 Keyframe Reduction 或 Optimal 压缩时可用,若原始值和消减值之间的差小于原始值乘以容错百分比,会删除关键帧
Position Error(位置错误)设置位置曲线压缩容错度(百分比)同 Rotation Error 的使用条件
Scale Error(缩放错误)设置缩放曲线压缩容错度(百分比)同 Rotation Error 的使用条件
Animated Custom Properties(动画自定义属性)导入指定为自定义用户属性的任何 FBX 属性-
4.3.2.动画剪辑选择与属性设置
属性描述选项及说明
动画剪辑名称可编辑修改,修改后需应用,且剪辑列表也会改变-
时间轴
  • Start:动画剪辑的开始帧
  • End:动画剪辑的结束帧
可在时间轴中定义每个动画剪辑的帧范围
Loop Time(循环时间)播放动画剪辑时是否循环播放,到结尾时重新开始循环动作即结束动作到开始动作无缝循环运动
Loop Match(循环匹配)结束动作和开始动作循环匹配的状态,绿色表示成功,红色表示失败-
Cycle Offset(周期偏移)循环动画在其他时间开始时的周期偏移-
Root Transform Rotation(根变换旋转)与根位置的角度相关
  • Bake Into Pose(烘焙成动作):将根旋转烘焙到骨骼移动,禁用此选项将存储为根运动,不勾选会影响根对象的旋转,勾选则不会
  • Based Upon(依据):
    • Original:保持源文件中的原始旋转
    • Root Node Rotation:使用根节点的旋转(仅适用于 Generic 通用动画类型)
    • Body Orientation:保持上半身朝前(仅适用于 Humanoid 人形动画类型)
  • Offset(偏移):根旋转偏移(单位:度)
Root Transform Position(Y)(根变化位置(Y))根垂直位置(Y 轴方向)
  • Bake Into Pose(烘焙成的动作):将垂直根运动烘焙到骨骼移动,禁用此选项将会存储为根运动,如走路动作不勾选根对象会上下移动,勾选则更平稳
  • Based Upon(at Start)(依据(开始时)):
    • Original:保持源文件中的垂直位置
    • Root Node Position:使用垂直根位置(仅适用于 Generic 通用动画类型)
    • Center Of Mass:保持质心与根位置对齐(仅适用于 Humanoid 人形动画类型)
    • Feet:保持双脚与根变换位置对齐(仅适用于 Humanoid 人形动画类型)
  • Offset(偏移):垂直根位置偏移
Root Transform Position(XZ)(根变化位置(XZ))根水平位置(XZ 平面)
  • Bake Into Pose(烘焙成的动作):将水平根运动烘焙到骨骼移动,禁用此选项将会存储为根运动,不勾选根对象会水平运动,勾选则只会播放动画根对象不会水平运动
  • Based Upon(依据(开始时)):
    • Original:保持源文件中的水平位置
    • Root Node Position:使用水平根位置(仅适用于 Generic 通用动画类型)
    • Center Of Mass:保持与根位置对齐(仅适用于 Humanoid 人形动画类型)
Mirror(镜像)在此剪辑中进行左右镜像(仅 Humanoid 人形动画类型才显示)-
Additive Reference Pose(叠加型参考动作)启用后可以设置附加动画层基础参考姿势的帧,在时间轴中可见蓝色标记
  • 附加动画层:在动画控制器(状态机)中可添加新的动画层
  • Pose Frame(动画帧):当启用参考姿势帧时,该项用于选择具体的帧

4.4 Materials材质纹理页签

参数描述选项及说明
Material Creation Mode(材质创建模式)定义 Unity 为模型生成或导入材质的方式
  • None:不使用此模型中嵌入的任何材质,改用 Unity 的默认漫反射材质
  • Standard:导入时,Unity 使用默认规则来生成材质
  • Import via MaterialDescription(Experimental):导入时,Unity 使用 FBX 文件中嵌入的材质描述来生成材质。与 Standard 相比,该方法结果更准确,并且支持更广泛的材质类型
sRGB Albedo Colors(sRGB 反照率颜色)是否在伽马空间中使用反射率颜色对于使用线性颜色控件的项目,禁用此选项。若 Material Creation Mode 选择的是 Import via MaterialDescription(Experimental),该属性不可用
Location(位置)定义访问材质和纹理的方式
  • Use Embedded Materials:将导入的材质保持在导入的资源中
  • Use External Materials(Legacy):将导入的材质提取为外部资源。这是旧版材质处理方式,适用于 2017.1 或更早的 Unity 版本创建的项目
Extract Textures/Materials(纹理/材料)当 Location 位置选择 Use Embedded Materials 后出现的内容,用于提取导入资源中嵌入的所有材质和纹理如果没有需要提取的子资源,这两个按钮会显示为灰色
Naming(命名)定义材质的命名规则
  • By Base Texture Name:使用导入材质的漫反射纹理名称来命名材质。若未将漫反射纹理分配给材质,Unity 将使用导入材质的名称
  • From Model’s Material:使用导入材质的名称来命名材质
  • Model Name + Model’s Material:使用模型文件的名称与导入材质的名称相结合来命名材质
Search(搜索)定义在使用 Naming 选项定义的名称时查找现有材质的位置规则
  • Local Materials Folder:在本地 Materials 材质子文件夹(模型文件所在的同一文件夹)中查找现有材质
  • Recursive-Up:在所有父文件夹(一直向上追溯到 Assets 文件夹)中所有 Materials 子文件夹中查找现有材质
  • Project-Wide:在所有 Unity 项目文件夹中查找现有材质
EthanWhite(重新映射的材质)如果找到了,Unity 会自动关联;如果没有找到,可手动进行关联-

5.CharacterController角色控制器

5.1.角色控制器的概念

角色控制器是一种用于控制角色的组件,它使角色受制于碰撞,但不会像刚体那样产生一些奇怪的表现。例如,使用刚体判断碰撞时,角色可能在斜坡上往下滑动,或者在碰撞时被撞飞等,而角色控制器能让角色表现得更加稳定。Unity 提供了专门的角色控制器组件来实现这一功能。

注意:添加角色控制器后,无需再添加刚体,并且它能检测碰撞函数和触发器函数。

5.2.角色控制器的使用

使用角色控制器时,建议取消 Animator 组件上的根运动,以避免与角色控制器的控制产生冲突,确保角色运动的稳定性和可控性。

5.3.角色控制器组件参数

参数描述说明
Slope Limit(斜度限制)坡度度数限制,大于该值的斜坡角色无法上去-
Step Offset(每步偏移量)台阶偏移值,单位为米,低于这个值的台阶角色才能上去,且该值不能大于角色控制器的高度-
Skin Width(蒙皮宽度)皮肤的宽度,即两个碰撞体可以穿透彼此的最大宽度。较大的值可减少抖动,较小的值可能导致角色卡住,建议设置为半径的 10%,通俗理解为角色可以和刚体穿模的程度-
MinMoveDistance(最小移动距离)大多数情况下为 0,可用于减少抖动-

5.4.角色控制器代码控制

CharacterController.isGrounded 变量:用于判断在上次移动期间 CharacterController 是否接触地面。

//CharacterController中的isGrounded变量 是否接触了地面
//在上次移动期间 CharacterController 是否接触地面?
if ( characterController.isGrounded )
{
    print("接触地面了");
}

CharacterController.SimpleMove 方法:使角色受重力作用进行移动,以指定的速度移动角色。

//CharacterController中的SimpleMove方法 受重力作用的移动
//以 speed 移动该角色。
characterController.SimpleMove(Vector3.forward * 10 * Time.deltaTime);

CharacterController.Move 方法:让角色进行不受重力作用的移动,为 GameObject 的移动提供附加的 CharacterController 组件。

//CharacterController中的Move方法 不受重力作用的移动
//为 GameObject 的移动提供附加的 CharacterController 组件。
characterController.Move(Vector3.forward * 10 * Time.deltaTime);

5.5.碰撞和触发检测函数

OnControllerColliderHit 函数:当角色控制器与别的碰撞器产生碰撞时调用该函数。

//当角色控制器想要判断和别的碰撞器产生碰撞时 使用该函数
private void OnControllerColliderHit(ControllerColliderHit hit)
{
    print("角色碰撞器发生碰撞"+hit.collider.gameObject.name);
}

OnCollisionEnter 方法:对于角色控制器无效,不会被调用。

//OnCollisionEnter方法对角色控制器没用 
//private void OnCollisionEnter(Collision collision)
//{
//    print("碰撞触发");
//}

OnTriggerEnter 方法:角色控制器可以检测触发器,当进入触发器时该方法会被调用。

private void OnTriggerEnter(Collider other)
{
    print("触发器触发");
}

6.导航寻路系统

6.1.导航网格生成

Object 场景对象设置页签:设置参与寻路烘焙的对象。

参数描述选项及说明
Sceme Filter(场景过滤器)配合 Hierarchy 窗口使用,筛选对象
  • All:显示场景上所有对象
  • MeshRenderers:显示挂载的网格渲染器的对象
  • Terrains:显示挂载了地形脚本的对象
Navigation Static(导航静态物体开关)若想对对象进行地形数据生成,需打开此选项,打开对象上的这个开关实际是打开静态下的导航静态-
Generate OffMeshLinks(生成网格连接点开关)用于两个地形断开但想实现跳跃过去的情况,打开对象上的这个开关实际是打开静态下的网格连接静态-
Navigation Area(导航区域选择)配合 Areas 页签使用-
Bake 导航数据烘焙页签:设置寻路网格具体信息,点击烘焙后,场景中生成的蓝色部分为可行走区域,需设置有对象为导航静态才能烘焙成功。
参数描述说明
Agent Radius(代理半径)决定烘焙边缘精确度,控制平台可行走区域和边缘可行走区域,可理解为人物半径半径越小,烘焙出来能走的地方越多
Agent Height(代理高度)决定烘焙高度精确度,控制拱桥是否可以穿越,可理解为人物高度高度越小,能穿过的拱桥越多,烘焙出来能走的地方越多
Max Slope(最大坡度)斜坡度数,决定斜坡是否可以行走,影响斜坡的烘焙若场景里的斜坡大于最大坡道,角色将无法上去
Step Height(步高)最小楼梯高度,决定台阶是否可以行走,影响台阶的烘焙若场景里的台阶高度大于步高,角色将无法上去
Generated off mesh Links(生成分离网格链接)生成非网格连接,用于两个分开的网格之间的连接相关设置,需在 Object 场景对象设置页签中打开 Generate OffMeshLinks 生成网格连接点开关,且注意下面两个变量也要设置,否则可能不生成-
Drop Height(掉落高度)角色可以从这个高度掉下来-
Jump Distance(跳跃距离)决定不同平面上的跳跃距离,小于这个距离内角色可以跳过-
Advanced(高级)
  • Manual Voxel Size(手动设置立体像素大小):开启后可设置立体像素大小,控制烘焙的准确度,立体像素大小描述了生成的导航网格表示场景几何体的准确程度。注意立体像素大小减半会使内存使用量增加 4 倍,构建时间也增加 4 倍,一般情况下不需要修改,除非想要极其准确的导航网格
  • Voxel Size(像素大小):配合 Manual Voxel Size 使用
  • Min Region Area(最小区域面积):当面积小于此处值的导航网格区域会被移除
  • Height Mesh(高度网格构建开关):主要用来解决楼梯烘焙为斜坡时,希望在楼梯表面的位置准确放置在楼梯平面上,而不是斜坡上,启用它会增加烘焙时间
-

Areas 导航地区页签:设置对象的寻路消耗,配合 Object 页签使用。

参数描述说明
Name(区域名字)区域的名称-
Cost(成本 寻路消耗)寻路消耗,可以自己新加一个导航区域,然后去 Object 页签选择调高寻路消耗成本会影响寻路结果,例如将水的寻路消耗调高,对象就会绕着水路走

Agents 代理页签:设置寻路代理信息,可单独设置寻路对象。

6.2.NavMeshAgent

6.2.1.NavMeshAgent 组件参数

Agent Type(代理类型):配合 Agents 页签使用。
Base Offset(基础偏移值):相对对象轴心点的高度偏移,即改变圆柱体位置。
Steering(转向 移动设置)

参数描述说明
Speed(寻路时的最大移动速度)寻路时的最大移动速度(世界单位/秒)-
Angular Speed(寻路时转身的最大旋转速度)寻路时转身的最大旋转速度(度/秒)-
Acceleration(最大加速度)最大加速度(世界单位/平方秒)-
Stopping Distance(停止距离)当靠近目标点多少距离时,停止运动-
Auto Braking(自动制动)启用后,当到达目标时将减速,若存在连续移动(如巡逻移动)建议不要开启该选项-

Obstacle Avoidance(障碍躲避 避障设置)

参数描述说明
Radius(半径)用于计算障碍物和其它寻路对象之间的碰撞-
Height(高度)通过头顶障碍物时用于计算高度间隙使用-
Quality(障碍躲避品质)越高躲避障碍越准确,但性能消耗较大。若不想主动避开其它动态障碍,可设置为无,则只会解析碰撞-
Priority(优先级)0~99,避障时,数字较小的障碍物表示较高的优先级,优先级低的会忽略避障-

Path Finding(寻路 路径寻找规则)

参数描述说明
Auto Traverse OffMesh Link(自动通过分离网格连接)是否开启自动遍历网格外的其它网格连接,若要自定义判断,则关闭此功能-
Auto Repath(自动重新寻路)是否开启自动重设路线,开启后,当到达路径后段时会再次尝试寻路,当没有到达目标的路径时,会生成一条到达与目标位置最近的可达点,默认勾选-
Area Mask(寻路时考虑的区域)若寻路时不想考虑某些区域,则取消选中,常见于塔防游戏-
6.2.2.NavMeshAgent 代码控制

常用内容

方法/变量描述代码示例
NavMeshAgent.SetDestination 方法自动寻路设置目标点,传入 Vector3 变量,设置或更新目标,从而触发新路径计算navMeshAgent.SetDestination()
NavMeshAgent.isStopped 变量停止寻路,此属性持有导航网格代理的停止或恢复条件navMeshAgent.isStopped = true;

不常用内容

方法/变量描述代码示例
NavMeshAgent.speed 变量遵循路径时的最大移动速度print(navMeshAgent.speed);
NavMeshAgent.acceleration 变量代理遵循某一路径时的最大加速度,以单位/秒² 表示print(navMeshAgent.acceleration);
NavMeshAgent.angularSpeed 变量遵循路径时的最大回转速度(以 deg/ s 为单位)print(navMeshAgent.angularSpeed);
NavMeshAgent.hasPath 变量代理当前是否有路径(只读)if ( navMeshAgent.hasPath ) { }
NavMeshAgent.destination 变量代理目标点,可以设置也可以得到,获取代理在世界坐标系单位中的目标或尝试设置代理在其中的目标print(navMeshAgent.destination);
NavMeshAgent.path 变量获取和设置当前路径的属性print(navMeshAgent.path);
NavMeshAgent.pathPending 变量路径是否在计算中,是否正在计算过程中而尚未就绪的路径(只读)if ( navMeshAgent.pathPending ) { }
NavMeshAgent.pathStatus 变量当前路径的状态(完整、部分或无效)print(navMeshAgent.pathStatus);
NavMeshAgent.updatePosition 变量获取或设置变换位置是否与模拟的代理位置同步,默认值为 truenavMeshAgent.updatePosition = true;
NavMeshAgent.updateRotation 变量代理是否应该更新变换方向navMeshAgent.updateRotation = true;
NavMeshAgent.velocity 变量获取 NavMeshAgent 组件的当前速度,或者设置一个速度来手动控制代理print(navMeshAgent.velocity);
NavMeshAgent.CalculatePath 方法计算到指定点的路径并存储生成的路径NavMeshPath navMeshPath = new NavMeshPath();if(navMeshAgent.CalculatePath(Vector3.zero, navMeshPath) ){}
NavMeshAgent.SetPath 方法为此代理分配一条新路径if (navMeshAgent.SetPath(navMeshPath)) { }
NavMeshAgent.ResetPath 方法清除当前路径navMeshAgent.ResetPath();
NavMeshAgent.Warp 方法将代理调整至指定的位置navMeshAgent.Warp(Vector3.zero);

6.3.OffMeshLink

参数描述选项及说明
Start(起始点)连接的起始位置-
End(结束点)连接的结束位置-
Cost Override(成本覆盖)覆盖消耗值。若为负数或 0,则使用所属 Area 区域中的消耗值,即两岸上烘焙区域的寻路成本;若为正数,则使用 Area 区域寻路消耗值乘以该正数作为该连接点的寻路消耗,可自定义连接点的寻路消耗主要用于解决当存在“步行”路径和连接点都能到达某一目标时的路径选择问题。例如有两个连接桥,可通过比较该参数,优先选择成本消耗更低的路径
Bi Directional(双向)是否开启双向连接点。开启后连接可从 Start 到 End,也能从 End 到 Start;关闭时则只能从 Start 到 End-
Activated(已激活)是否启用该连接点。若关闭,自动寻路时该连接点相当于失效-
Auto Update Positions(是否自动更新位置)如果启用,当开始和结束位置改变时,导航网格也将更新;如果不启用,即使改变了开始和结束位置,仍会按照刚开始的位置进行计算,主要用于运行时修改路径-

6.4.NavMeshObstacle

参数描述选项及说明
Shape(动态障碍的形状)动态障碍物的形状类型
  • Capsule:胶囊
  • Box:盒装
Carve(切割 是否开启雕刻功能)是否开启雕刻功能。开启后,障碍物会在导航网格中挖一个孔,生成对应的网格信息,使该区域被认为无法前往;若动态障碍物是固定不动的,建议开启,如门、木桶、栅栏等;若动态障碍物是频繁移动的,建议不开启,如汽车和玩家-
Move Threshold(移动阈值)当障碍物移动超过该距离时,会被认为处于移动状态,进而更新移动的孔-
Time To Stationary(静止时间)障碍物作为静止状态需要等待的时间,单位为秒。当静止时间超过该值,才会被认为真正静止-
Carve Only Stationary(仅在静止时切割)只有在障碍物处于静止状态时才会计算孔-

四、Unity进阶

1.InputSystem

开启方法:File——>Build Setting——>Player Setting——>Other——>Active Input Handling

1.1.代码检测输入

1.1.1.键盘输入
获取方式操作检测说明
using UnityEngine.InputSystem; <br> Keyboard keyBoard = Keyboard.current;单个按键按下通过keyBoard.具体按键.wasPressedThisFrame判断,如if (Keyboard.current.spaceKey.wasPressedThisFrame) 可检测空格键按下
单个按键抬起利用keyBoard.具体按键.wasReleasedThisFrame,例如if (Keyboard.current.dKey.wasReleasedThisFrame) 检测D键抬起
单个按键长按使用keyBoard.具体按键.isPressed,像if (Keyboard.current.spaceKey.isPressed) 检测空格长按状态
文本输入监听lambda表达式:keyBoard.onTextInput += (c) => {print("通过lambda表达式" + c);};
普通函数:先定义private void TextInput(char c) ,再keyBoard.onTextInput += TextInput;
任意键按下if (Keyboard.current.anyKey.wasPressedThisFrame) ,但无法得知具体按下的键
1.1.2.鼠标输入
获取方式操作检测说明
Mouse mouse = Mouse.current;各键位按下以左键为例,if (Mouse.current.leftButton.wasPressedThisFrame) 判断左键按下
各键位抬起if (Mouse.current.leftButton.wasReleasedThisFrame) 检测左键抬起
各键位长按例如if (Mouse.current.rightButton.isPressed) 检测右键长按
当前位置Mouse.current.position.ReadValue() ,原点是左下角,值为屏幕最大分辨率
两帧偏移向量Mouse.current.delta.ReadValue() ,获取鼠标两帧间移动向量
滚轮方向向量Mouse.current.scroll.ReadValue() ,往上滚大于0,往下滚小于0
1.1.3.触屏输入
获取方式操作检测说明
Touchscreen touchscreen = Touchscreen.current;
使用前判空:if (touchscreen == null) return;
手指数量print(touchscreen.touches.Count) 输出当前触屏手指数量
单个触屏手指touchscreen.touches[0] 获取指定索引的手指信息
遍历所有触屏手指foreach (var item in touchscreen.touches) 遍历所有触屏手指
手指按下if (touchControl.press.wasPressedThisFrame)touchControl 为指定手指对象
手指抬起if (touchControl.press.wasReleasedThisFrame) 检测手指抬起
手指长按if (touchControl.press.isPressed) 判断手指长按状态
点击手势if(touchControl.tap.isPressed) 检测手指点击
连续点击次数print(touchControl.tapCount) 输出手指连续点击次数
手指位置print(touchControl.position.ReadValue()) 获取当前手指位置
首次接触位置print(touchControl.startPosition.ReadValue()) 得到手指第一次接触时位置
接触区域大小touchControl.radius.ReadValue() 读取手指接触区域半径大小
偏移位置touchControl.delta.ReadValue() 获取手指偏移位置
手指状态UnityEngine.InputSystem.TouchPhase touchPhase = touchControl.phase.ReadValue();
通过switch语句判断:
switch (touchPhase)
{
//无
case UnityEngine.InputSystem.TouchPhase.None:
break;
//开始接触
case UnityEngine.InputSystem.TouchPhase.Began:
break;
//移动
case UnityEngine.InputSystem.TouchPhase.Moved:
break;
//结束
case UnityEngine.InputSystem.TouchPhase.Ended:
break;
//取消
case UnityEngine.InputSystem.TouchPhase.Canceled:
break;
//静止
case UnityEngine.InputSystem.TouchPhase.Stationary:
break;
default:
break;
}

希望这个更新后的表格能满足你的需求。如果你还有其他问题,请随时告诉我。

1.1.4.手柄输入
获取方式操作检测说明
Gamepad gamePad = Gamepad.current;
使用前判空:if (gamePad == null) return;
左摇杆方向向量print(gamePad.leftStick.ReadValue()) ,右和上是正方向
右摇杆方向向量print(gamePad.rightStick.ReadValue())
左摇杆按下if (gamePad.leftStickButton.wasPressedThisFrame) 判断左摇杆按下
左摇杆抬起if (gamePad.leftStickButton.wasReleasedThisFrame) 检测左摇杆抬起
左摇杆长按if (gamePad.leftStickButton.isPressed) 检测左摇杆长按
方向键(以左方向键为例)按下:if (gamePad.dpad.left.wasPressedThisFrame)
抬起:if (gamePad.dpad.left.wasReleasedThisFrame)
长按:if (gamePad.dpad.left.isPressed)
右侧按键(以北向按钮为例)gamePad.buttonNorth ,按下检测如if (Gamepad.current.buttonNorth.wasPressedThisFrame) ,也可按具体名字如gamePad.triangleButton 等监听
中央按键(开始键)gamePad.startButton ,按下检测if (Gamepad.current.startButton.wasPressedThisFrame)
中央按键(选择键)gamePad.selectButton ,按下检测if (Gamepad.current.selectButton.wasPressedThisFrame)
肩部按键(左侧前方)gamePad.leftShoulder ,按下检测if (Gamepad.current.leftShoulder.wasPressedThisFrame)
肩部按键(左侧后方)gamePad.leftTrigger ,按下检测if (Gamepad.current.leftTrigger.wasPressedThisFrame)
1.1.5.其他输入
设备类型说明学习方式
Joystick(摇杆)用于输入操作查看官方文档或类内部成员,了解属性和方法
Pen(电子笔)实现特定输入同上
Sensor(传感器)包含陀螺仪(UnityEngine.InputSystem.Gyroscope )、重力传感器等查看官方文档,或通过代码示例如UnityEngine.InputSystem.Gyroscope gyroscope = UnityEngine.InputSystem.Gyroscope.current; gyroscope.angularVelocity.ReadValue(); ,查看类内部成员使用

1.2.InputAction

以下是对上述“InputAction”相关内容整理的表格,涵盖了InputAction的定义、参数设置、不同类型的输入绑定、使用方法以及相关设置等方面:

1.2.1.InputAction参数设置
设置项详情
Actions输入动作设置设置检测的输入类型
Action Type(动作类型)Value:用于状态连续更改的输入,多个设备绑定时只发送最受控制设备的输入
Button:每次按下时触发的Action
Pass Through:和Value类似,多个设备绑定时发送所有设备的输入
Control Type(控制类型)选择类型后会筛选输入设备,如Vector2只能选返回Vector2变量类型的设备(手柄摇杆、鼠标位置等),Button只能选按钮返回值设备(鼠标左键、手柄按键等),包括AnyAnalogAxisBoneDigitalDoubleDpadEyesIntegerQuaternionStickTouchVector2Vector3
Interactions相互作用设置用于特殊输入(长按、多次点击等),满足条件时触发行为,有started(开始)、performed(触发)、canceled(结束)三个事件
相互作用设置参数Hold:长按操作,按下触发started,按住时间大于等于Hold Time触发performed,否则触发canceled
Tap:点击操作,按下触发started,在Max Tap Duriation时间内松开触发performed,否则触发canceled
SlowTap:类似Hold,按住时间大于等于Max Tap Duriation,松开时触发performed
MultiTap:多次点击操作,Tap Count为点击次数,Max Tap Spacing为点击间隔,Max Tap Duration为每次点击持续时间,满足条件触发performed
Press:类似按钮操作,Trigger BehaviorPress Only(按下触发startedperformed,不触发canceled)、Release Only(按下触发started,松开触发performed)、Press And Release(按下和松开都触发startedperformed,不触发canceled)、Press Point(利用按钮浮点值区分按下状态)
Processors值处理加工设置Clamp:将输入值钳制到[min..max]范围
Invert:反转控件值(乘以-1)
Invert Vector 2:反转Vector2轴的值
Invert Vector 3:反转Vector3轴的值
Normalize:将输入值规格化为[0..1][-1..1]
Normalize Vector 2:将输入向量规格化为单位长度
Normalize Vector 3:将输入向量规格化为单位长度
Scale:将输入值乘以系数
Scale Vector 2:沿xy轴乘以相应值
Scale Vector 3:沿xyz轴乘以相应值
死区设置Axis Deadzone:缩放控件值,使绝对值小于最小值为0,大于最大值为1或-1,避免无意输入和确保最大值
Stick Deadzone:缩放Vector2控件值,幅值小于最小值为(0,0),大于最大值规格化为长度1
1.2.2.InputAction输入绑定类型
绑定类型详情
Add Binding添加单按键输入绑定,如鼠标左右键按下
Add Positive\Negative Binding Or Add 1D Axis Composite添加1D轴组合(类似水平竖直热键,返回-1~1值),参数有Negative(负面按键)、Positive(正向按键)、Composite Type(复合类型)、MinValue(最小值)、MaxValue(最大值)、Which Side Wins(同时按下处理方式,Neither:取中间值,Positive:取maxValueNegative:取minValue
Add Up\Down\Left\Right Composite Or Add 2D Vector Composite添加2D向量组合(类似水平竖直热键组合,Vectorxy表示两个轴),参数有UpDownLeftRightComposite Type(复合类型)、Mode(处理模式,Analog:模拟值,Digital Normalized:单位化向量,Digital:未单位化向量)
Add Up\Down\Left\Right\Forward\Backward Composite添加3D向量组合,比2D多一维参数,需关联多两个键
Add Button With One Modifier Composite添加带有一个复合修改器的按钮(双组合键,如Ctrl+C),参数有Modifier(复合输入内容)、Button(输入内容)
Add Button With Two Modifier Composite添加带有两个复合修改器的按钮(三组合键,如Ctrl+K+U),参数有Modifier(两个复合输入内容)、Button(输入内容)
1.2.3.InputAction使用方法
操作详情
启用输入检测move.Enable();
操作监听 - 开始操作move.started += StartedTestFun;
private void StartedTestFun(InputAction.CallbackContext context) { print("开始事件调用"); }
操作监听 - 真正触发move.performed += (context) => { print("触发事件调用"); }
操作监听 - 结束操作move.canceled += (context) => { print("结束事件调用"); }
关键参数CallbackContext可获取当前状态(context.phase,如DisabledWaitingStartedPerformedCanceled)、动作行为信息(context.action.name)、控件(设备)信息(context.control.name)、获取值(context.ReadValue<float>)、持续时间(context.duration)、开始时间(context.startTime
1.2.4.InputAction特殊设置及系统设置
设置项详情
特殊输入设置可在Interactions中为整个动作或单个设备设置特殊输入条件,如长按时间等;可点击创建InputSystem默认值设置文件并修改
Input System Package设置UpdateMode:更新模式(Process Events In Dynamic UpdateProcess Events In Fixed UpdateProcess Events Manually
Background Behavior:后台行为(Reset And Disable Non Background DevicesReset And Disable All DevicesIgnore FocusFilter Noise on .currentCompensate Orientation
Default Deadzone Min:默认死区最小值
Default Deadzone Max:默认死区最大值
Default Button Press Point:默认按钮按下点
Button Release Threshold:按钮释放阈值
Default Tap TIme:默认点击时间
Default Slow Tap Time:默认慢速点击时间
Default Hold Time:默认保持时间
Tap Radius:点击半径
MultTap Delay TIme:多次点击延迟时间
Supported Devices:可设置支持的设备,不设置则支持所有可识别设备,设置后缩小编辑器显示范围并避免无关设备输入
Motion Usage:动作使用
Description:描述
Play Mode Input Behavior:播放模式输入行为(Pointers And Keyboards Respect Game View FocusAll Devices Respect Game View FocusAll Device Input Always Goes To Game View
以下是根据你提供的内容整理的关于输入配置文件的表格:
1.2.5.InputActions输入操作配置文件
类别详情
定义输入系统中是 InputAction 的集合,记录想要处理的行为和动作(InputAction 相关信息),可自定义 InputAction(如开火、移动、旋转等)并关联对应的输入动作,与 PlayerInput 关联后,PlayerInput 自动解析文件,触发输入动作时以分发事件形式通知执行行为
创建方式Project 窗口右键选择 Create 创建 InputActions 配置文件,文件后缀为 .inputactions,本质是 json 文件
编辑方式双击创建出的文件弹出配置窗口进行配置,每次更改后需点击保存配置或勾选自动保存
配置窗口参数ActionMaps 行动地图窗口:可理解为行为分组配置,能配置多套操作规范,可右键或点击加号创建新配置、移除等
Actions 输入动作窗口:在此可通过加号或右键创建各种 InputAction,无需在代码中声明变量,可直接添加键盘配置
Properties 输入操作绑定的输入属性:与普通 InputAction 点击齿轮的选项相同
工具栏:提供保存、搜索等功能按键
设置编辑器显示的控制方案选项Gamepad(手柄)、Joystick(摇杆)、KeyboardMouse(键盘鼠标)、Touch(触屏)、XR(VR/AR 等)、All Devices(设备选择)
作用:切换控制方案后,若该方案由多个设备配合控制,可进一步筛选对应设备,如切换键盘鼠标方案后可二次筛选
保存配置Auto-Save:自动保存配置
搜索栏:可搜索对应动作行为
编辑配置文件基本操作流程1. 左上角添加控制方案(如手柄和鼠标键盘),在下面小列表分别选择设备
2. 在每个绑定设备中选择设备的控制方案
3. 左上角选择控制方案可筛选设备,选择后还可二次筛选设备

InputSystem中专门用于任意键按下的方案

InputSystem.onAnyButtonPress.CallOnce
InputSystem.onAnyButtonPress.CallOnce((control) =>
{
    print("InputSystem中专门用于任意键按下的方案 路径" + control.path);
    print("InputSystem中专门用于任意键按下的方案 名字" + control.name);
});

通过Json数据加载配置文件

string json = Resources.Load<TextAsset>("PlayerInputTest").text;

// 使用 InputActionAsset 类的静态方法 FromJson 解析 json 字符串,返回解析后的 InputActionAsset 对象,并将其存储在变量 asset 中
InputActionAsset asset = InputActionAsset.FromJson(json);

// 将解析后的 InputActionAsset 对象赋值给 input 对象的 actions 属性
input.actions = asset;
1.2.6.输入配置文件生成CSharp代码
类别详情示例
课前准备创建配置文件,在配置文件中创建两套行为假设创建一个游戏相关的输入配置文件,一套行为是角色的战斗操作(如开火等),另一套行为是角色的移动和跳跃操作
根据配置文件生成C#代码1. 选择 InputActions 文件,勾选 Generate C# Class
2. 在 Inspector 窗口设置生成路径(如 Assets/Scripts/GeneratedInputCode)、类名(如 CustomInputActions)、命名空间(如 MyGame.Input
3. 应用后生成代码,生成的代码根据 InputAction 配置文件解析 Json 生成类并提供一些方法
例如,在 Unity 项目中,已经创建好名为 MyInputActions.inputactions 的配置文件,选中它后在 Inspector 窗口勾选 Generate C# Class,设置生成路径为 Assets/Scripts/InputCode,类名为 GameInputActions,命名空间为 GameProject.Input,点击应用后,在指定路径下生成对应的 C# 代码文件
使用C#代码进行监听声明对象GameInputActions input; 声明一个用于监听输入的配置文件对象(这里以 GameInputActions 为例,对应前面生成的类名)
Start 方法1. 创建生成的代码对象:input = new GameInputActions(); 实例化配置文件对象
2. 激活配置文件的输入:input.Enable(); 启用输入
3. 添加事件监听:
input.Action1.Fire.performed += (context) => { print("鼠标点击 开火"); };
input.Action2.Space.performed += (context) => { print("空格按下 跳跃"); };
假设 Action1 是战斗操作行为组,Fire 是其中的开火输入动作;Action2 是移动跳跃行为组,Space 是其中的跳跃输入动作
Update 方法print("wasd移动" + input.Action1.Move.ReadValue<Vector2>()); 监听输入并打印相关信息
假设 MoveAction1 行为组中用于控制角色移动的输入动作,通过 ReadValue<Vector2> 获取移动的向量值并打印

1.3.PlayerInput

1.3.1.PlayerInput介绍
类别详情
PlayerInput定义InputSystem提供的用于接受玩家输入并处理自定义逻辑的组件
PlayerInput工作原理1. 配置输入文件(InputActions文件)
2. 通过PlayerInput关联配置文件,自动解析
3. 关联响应函数,处理对应逻辑
PlayerInput好处1. 无需自己书写输入逻辑
2. 通过配置文件配置监听行为
3. 专注于输入事件触发后的逻辑处理
添加PlayerInput组件选择一个对象(一般为玩家对象),为其添加PlayerInput组件
PlayerInput参数Actions(行为)
Default Scheme(默认控制方案)
Ui Input Module(UI输入模块)
Camera(摄像机)
Behavior(行为执行模式)SendMessage:逻辑脚本挂载在与PlayerInput同一对象上,通过SendMessage通知执行函数
BroadcastMessage:逻辑脚本可挂载在自身或子对象上,通过BroadcastMessage通知执行函数
Invoke UnityEvent Actions:在Inspector窗口通过拖拽关联函数,响应函数参数类型为InputAction.CallbackContext,可关联其他对象的脚本函数
Invoke CSharp Events:通过获取PlayerInput进行事件监听,可得到对应行为的值,如input.currentActionMap["Move"].ReadValue<Vector2>()

SendMessage示例:在自定义脚本中声明名为“On+行为名”的函数,无参数或参数类型为InputValue,挂载到PlayerInput依附对象上。代码如下:

public void OnMove(InputValue value)
{
    print("Move");
    print("Move" + value.Get<Vector2>());
}


public void OnFire(InputValue value)
{
    print("Fire");
    if (value.isPressed)
    {
        print("Fire按下");
    }
}


BroadcastMessage示例:基本规则同SendMessage,自定义脚本还可挂载在子对象上
Invoke Unity Events示例|在脚本中声明函数,如:

public void MyFire(InputAction.CallbackContext context)
{
    print("开火1");
}

public void MyMove(InputAction.CallbackContext context)
{
    print("移动1");
}

public void MyLook(InputAction.CallbackContext context)
{
    print("Look1");
}

Inspector窗口通过拖拽关联函数|
Invoke C Sharp Events示例|
(1). 获取PlayerInput组件:

PlayerInput input = this.GetComponent<PlayerInput>();

(2). 添加委托函数:

input.onDeviceLost += OnDeviceLost;
input.onDeviceRegained += OnDeviceRegained;
input.onControlsChanged += OnControlsChanged;
input.onActionTriggered += OnActionTrigger;

(3). 处理事件:

public void OnActionTrigger(InputAction.CallbackContext context)
{
    print("触发OnActionTrigger");
    switch (context.action.name)
    {
        case "Fire":
            if (context.phase == InputActionPhase.Performed)
                print("开火");
            break;
        case "Look":
            print("看向");
            print(context.ReadValue<Vector2>());
            break;
        case "Move":
            print("移动");
            print(context.ReadValue<Vector2>());
            break;
    }
}
1.3.2.PlayerInput玩家输入管理组件
类别详情详情
关键参数InputValue判断是否按下:inputValue.isPressed
获取Vector2类型值:inputValue.Get<Vector2>()
InputAction.CallbackContext获取Vector2类型值的xy属性:callbackContext.ReadValue<Vector2>().xcallbackContext.ReadValue<Vector2>().y
获取输入行为名字:callbackContext.action.name
获取输入控件名字:callbackContext.control.name
获取输入控件所属设备名字:callbackContext.control.device.name
获取输入阶段枚举值:callbackContext.phase
获取输入阶段字符串表示:callbackContext.phase.ToString()
PlayerInputManager作用用于管理本地多人输入的输入管理器,管理玩家加入和离开,如分屏游戏和双手柄游戏
PlayerInputManager组件参数Notification Behavior当玩家进入时,PlayerInputManager通知关联对象的方式,与PlayerInput工作方式相同
Join Behavior(玩家加入机制)Join Players When Button Is Pressed:新设备加入或无玩家时按下任意键加入
Join Players When Join Action Is Triggered:新设备加入时按下指定按键触发加入,一般选择此项
Join Players Manually:手动加入玩家
Player Prefab挂载PlayerInput组件的游戏对象
Joining Enabled By Default启用后,新加玩家按JoinBehavior规则加入,默认勾选
Limit Number Of Players启用后,可限制加入游戏的玩家数量,Max Player Count为允许的最大玩家数
Enable Split_Screen启用后,自动为每个对象分配屏幕区域用于多人分屏游戏
Maintain Aspect Ratio:控制分屏区域纵横比与实际屏幕分辨率匹配
Set Fixed Number:大于零时,始终将屏幕分割为固定数量矩形
Screen Rectangle:用于分配玩家分屏的规范化屏幕矩形

PlayerInputManager使用示例:
(1). 创建预制体方块,添加PlayerInput组件和脚本,创建配置文件并关联到预制体的PlayerInput组件,再关联到PlayerInputManger的玩家预制体上(预制体需有PlayerInput组件)

(2). 调整方块预制体对象输入行为为手动关联模式,关联脚本上的Move函数,代码如下:

private Vector3 dir;
void Update()
{
    this.transform.Translate(dir * 10 * Time.deltaTime);
}

public void Move(InputAction.CallbackContext context)
{
    dir = context.ReadValue<Vector2>();
    dir.z = dir.y;
    dir.y = 0;
}

(3). 选择模式(如按A键和手柄开始键创建新预制体),PlayerInputManager自动处理输入控制

(4). 让方块预制体挂载摄像机,勾选分屏选项实现分屏效果

(5). 使用单例获取PlayerInputManager并添加玩家加入和离开事件:

//获取PlayerInputManager
//PlayerInputManager.instance
//玩家加入时
PlayerInputManager.instance.onPlayerJoined += (playerInput) =>
{
    print("创建了一个玩家");
};
//玩家离开时
PlayerInputManager.instance.onPlayerLeft += (playerInput) =>
{
    print("离开了一个玩家");
};

1.4.UGUI配合使用

类别详情
InputSystem对UI的支持情况不支持IMGUI(GUI),此限制仅对编辑器代码有效。若激活InputSystem,OnGUI中输入判断内容不触发,让OnGUI内容有效需选“Both”或只激活老输入系统InputManager;支持UGUI,需用新输入系统的输入模块(Input System UI Input Module)处理相关输入
UGUI中新输入系统输入模块参数Move Repeat Delay
Move Repeat Rate移动动作保持激活时,生成重复导航事件的间隔(秒),受帧速率限制,每帧不会有多个移动重复事件
XR Tracking Origin无明确详细说明
Deselect On Background CLick默认点击指针未击中游戏对象时清除当前选择,可能妨碍键盘和游戏板导航,设为false可防止自动取消选择
Pointer BehaviorSingle Mouse Or Pen BUt Multi Touch And Track:未分类为触摸或跟踪输入的按单个统一指针处理,跟踪和触摸输入按所有指针处理,触摸或跟踪设备输入时,鼠标和笔的单个统一指针会被删除
Single Unified Pointer:所有指针输入统一为一个指针,只有帧中最后一个输入生效
All Pointers As Is:UI输入模块不统一指针输入,每个设备输入都是独立指针,可能出现多个指针同时指向多个对象的情况
Actions Asset包含控制UI的所有操作的输入操作资产,默认引用DefaultInputActions内置资产,可创建自定义资源并在此分配,编辑器会根据命名约定自动映射操作到UI输入
Point提供2D屏幕位置的动作,用于鼠标样式的UI交互,设置为传递操作类型和向量2值类型
Left Click映射到与UI交互的主光标按钮的操作,设置为传递操作类型和按钮值类型
Middle Click映射到与UI交互的中间光标按钮的操作,设置为传递操作类型和按钮值类型
Right Click映射到与UI交互的辅助光标按钮的操作,设置为传递操作类型和按钮值类型
Scroll Wheel提供手势输入以允许在UI中滚动的操作,设置为传递操作类型和向量2值类型
Move提供用于选择当前活动用户界面的二维矢量的操作,允许游戏板或箭头键样式的UI导航,设置为传递操作类型和向量2值类型
Submit与当前选择的UI接触或“单击”的操作,设置为按钮动作类型
Cancel退出与当前选定UI的任何交互的操作,设置为按钮动作类型
Tracked Position提供一个或多个空间跟踪设备(如XR hand控制器)的3D位置的动作,结合跟踪设备方向实现XR样式的UI交互,设置为传递操作类型和向量3值类型
Tracked Orientation传递表示一个或多个空间跟踪设备(如XR hand控制器)旋转的四元数的操作,结合跟踪设备位置实现XR样式的UI交互,设置为传递操作类型和四元数值类型
VR项目使用注意事项在VR项目中用新输入系统配合UGUI,需在Canvas对象上添加Tracked Device Raycaster组件
多人游戏使用多套UI同一设备多人游戏,每人想用独立UI,需将EventSystem中的EventSystem组件替换为Multiplayer Event System组件(先移除InputSystemUIInputModuleEventSystem组件再添加);可同时激活多个MultiplayerEventSystem,每个玩家有自己的InputSystemUIInputModuleMultiplayerEventSystem组件及操作来驱动UI;若使用PlayerInput组件,可设置其自动配置玩家的InputSystemUIInputModuleMultilayerEventSystem组件属性与事件系统中属性相同,还添加了playerRoot属性,可设为包含此事件系统应处理的所有UI可选择项的游戏对象
On - Screen组件相关可模拟UI和用户操作的交互,如On - Screen Button用于按钮交互,On - Screen Stick用于摇杆交互,关联之前输入配置文件设置好逻辑和关联设备的小球输入,如On - Screen Stick关联手柄摇杆可像手柄摇杆一样控制小球移动,On - Screen Button关联空格键可像按空格键一样控制小球跳跃

1.5.InputDebug输入调试器

类别详情
InputDebug定义即输入调试器,可通过输入调试窗口检测输入相关信息,用于在输入不按预期工作时排查问题
打开InputDebug窗口的方式1. 通过菜单栏:Window(窗口)-> Analysis(分析)-> Input Debugger(输入调试器)
2. 通过PlayerInput组件:点击PlayerInput组件上的Open Input Debugger
InputDebug窗口信息 - 未运行状态Options操作下拉框
Devices
Unsupported
Layouts
Controls
Abstract Devices
Specific Devices
Settings
Metrics
InputDebug窗口信息 - 运行状态双击设备可进行相关操作和查看更详细信息(文档中未明确具体内容,仅提及双击设备这一操作)

2.VideoPlayer

2.1.视频剪辑设置

以下是将上述内容整理为表格的形式,方便你更清晰地了解视频剪辑设置的相关知识:

类别参数介绍
设置参数sRGB是否开启 sRGB,sRGB 是通用色彩标准,避免不同设备出现色差,一般默认勾选
Transcode是否开启转码,开启后下方参数才能设置
Dimensions控制源文件内容大小调整方式:
1. Original:保持原始大小
2. Three Quarter Res:调整为原始宽高的四分之三
3. Half Res:调整为原始宽高的一半
4. Quarter Res:调整为原始宽高的四分之一
5. Square(1024x1024):调整为 1024x1024 正方形图像,宽高比可控
6. Square(512x512):调整为 512x512 正方形图像,宽高比可控
7. Square(256x256):调整为 256x256 正方形图像,宽高比可控
8. Custom:调整为自定义分辨率,宽高比可控,可设置Width(生成图像的宽)、Height(生成图像的高)
9. Aspect Ratio:调整图像大小时的宽高比,有No Scaling(添加黑色区域保留原始宽高比)、Stretch(拉伸原始内容填充目标分辨率)
Codec选择用于转码的解编码器:
1. Auto:为目标平台选择最合适的视频编解码器
2. H264:MPEG–4 高级视频编码 (AVC) 视频编解码器,受大多数平台硬件支持
3. H265:MPEG-H Part 2 或高效视频编码 (HEVC) 视频编解码器,受某些平台硬件支持
4. VP8:VP8 视频编解码器,受大多数平台软件支持,部分平台(如 Android 和 WebGL)硬件支持
Bitrate Mode相对于所选编解码器的基线配置文件的低、中或高比特率
Spatial Quality决定视频图像在转码过程中是否压缩大小:
1. Low Spatial Quality:转码时图像大小显著减小(通常为原始尺寸的四分之一),播放时扩展回原始大小,节省存储空间但播放时模糊度最大
2. Medium Spatial Quality:转码时图像大小适度减小(通常为原始尺寸的一半),播放时扩展回原始大小,图像更清晰,存储空间有所减少
3. High Spatial Quality:不调整大小,保持视频原始视觉清晰度
Keep Alpha保留 Alpha 透明通道并在转码期间将其编码,仅对具有 Alpha 通道的源显示,Android 平台原生 VP8 不支持透明度,需启用转码
Deinterlace(去交错设置)控制隔行扫描源在转码期间如何解除隔行扫描,优化动态画面清晰度:
1. Off:源文件没有隔行扫描,不进行隔行扫描
2. Even:采用每个帧的偶数行,插入创建缺失内容,丢弃奇数行
3. Odd:采用每个帧的奇数行,插入创建缺失内容,丢弃偶数行
隔行扫描和逐行扫描区别:
隔行扫描:每一帧被分割为两场,包含奇数或偶数扫描行,交替显示,存在闪烁,人眼易疲劳
逐行扫描:每次显示整个扫描帧,画面更平滑,闪烁较小
Filp Horizontally选中时,转码时将视频源文件内容沿水平轴翻转实现上下翻转
Flip Vertically选中时,转码时将视频源文件内容沿垂直轴翻转实现左右翻转
Import Audio只有存在音频轨道的视频才会出现该选项,勾选时,转码期间会导入音频轨道

2.2.VideoPlay视频播放器

2.2.1.VideoPlayer组件参数
参数分类参数名称参数说明
视频源设置Source视频源类型,有 Video Clip 和 URL 两种选择
Video Clip可直接将视频剪辑拖入或选择视频剪辑进行关联
URL选择视频的路径,可以是远程视频路径,可点击 Browse 选择,也能通过代码关联
播放控制Play On Awake场景启动时自动播放视频,若想自行控制播放时机则取消勾选
Wait For First Frame勾选后,Unity 等待视频第一帧准备好显示;取消勾选可能丢弃前几帧以同步游戏时间
Loop设置视频是否循环播放
Skip On Drop决定是否允许视频播放器跳过帧以赶上当前时间
Playback Speed播放速度的乘数,取值范围 0 - 10,1 为正常速度,2 表示两倍速播放
渲染方式Render Mode包括 Camera Far Plane、Camera Near Plane、Render Texture、Material Override、API Only 等多种渲染模式
Camera Far Plane在摄像机的远平面上渲染视频
Camera定义接受视频的摄像机,Alpha 可设置视频的全局透明度
3D Layout包含不同的 3D 布局渲染方式
Camera Near Plane在摄像机的近平面上渲染视频
Render Texture将视频渲染到渲染纹理中,Target Texture 用于指定渲染图像的渲染纹理,分辨率最好和视频一致,可通过 UI 创建 image 关联视频纹理
Material Override通过游戏对象渲染器的材质将视频渲染到游戏对象的选定纹理属性中,Renderer 用于指定渲染图像的渲染器,若为 None 则使用 Video Player 依附对象的渲染器
API Only不预先设置渲染位置,通过代码使用 Video Player 中的 texture 属性设置视频渲染位置
宽高比设置Aspect Ratio有 No Scaling、Fit Vertically、Fit Horizontally、Fit Inside、Fit Outside、Stretch 等多种宽高比设置方式
No Scaling不使用缩放
Fit Vertically垂直适应目标矩形,必要时裁剪左右或留黑边保留原宽高比
Fit Horizontally水平适应目标矩形,必要时裁剪上下或留黑边保留原宽高比
Fit Inside对原视频缩放不裁剪,但可能留黑边
Fit Outside对原视频缩放,可能裁剪但不留黑边
Stretch水平和垂直方向均缩放以适应目标矩形,不保留源宽高比
音频输出设置Audio Output Mode包括 None、Audio Source、Direct、API Only 等音频输出模式
None不播放音频
Audio Source将音频发送给指定的音频源对象,允许 Unity 的音频处理,关联音频源后可通过其控制视频声音
Direct直接绕过 Unity 音频处理,发送给音频输出硬件输出,如手机硬件
Mute设置静音
Volume调节音量
API Only通过代码将音频样本发送到关联的 AudioSampleProvider 听诊器
Track Enabled启用关联的音频轨道用于播放,必须在播放前设置,如“Track 0[en, 2 ch]”表示双声道音频轨道
2.2.2.VideoPlayer参数和方法

参数设置

// 是否自动播放,设置为 false 表示不自动播放
videoPlayer.playOnAwake = false; 
// 设置渲染模式为在摄像机的远平面上渲染
videoPlayer.renderMode = VideoRenderMode.CameraFarPlane; 
// 设置目标渲染贴图为 renderTexture(需提前定义)
videoPlayer.targetTexture = renderTexture; 
// 设置目标摄像机为名为 "Main Camera" 的摄像机
videoPlayer.targetCamera = GameObject.Find("Main Camera"); 
// 设置目标摄像机的透明度为 0.5
videoPlayer.targetCameraAlpha = 0.5f; 
// 以 Over-Under3D 格式呈现视频
videoPlayer.targetCamera3DLayout = Video3DLayout.OverUnder3D; 
// 设置视频源模式为使用视频剪辑
videoPlayer.source = VideoSource.VideoClip; 
videoPlayer.clip = videoClip; 
// 或者设置视频源模式为使用 URL 路径
// videoPlayer.source = VideoSource.Url; 
// videoPlayer.url = Application.streamingAssetsPath + "/Video.mp4"; 
// 设置视频不循环播放
videoPlayer.isLooping = false; 

视频状态输出

// 输出视频总时长,单位为秒
print(videoPlayer.length); 
// 输出当前视频播放的时长,单位为秒
print(videoPlayer.time); 
// 输出视频的总帧数
print(videoPlayer.frameCount); 
// 输出当前视频播放到的帧
print(videoPlayer.frame); 

方法

// 播放视频
videoPlayer.Play(); 
// 停止视频,再次播放时会从头开始
videoPlayer.Stop(); 
// 暂停视频播放
videoPlayer.Pause(); 
// 为视频准备数据,提前调用可避免播放时卡顿
videoPlayer.Prepare(); 

事件

// 准备完成事件,当视频准备完成后触发,可用于避免播放卡顿
videoPlayer.prepareCompleted += (v) =>
{
    print("准备完成");
    isPrepareCompleted = true;
};
// 开始事件,当执行 videoPlayer.Play() 方法后调用
videoPlayer.started += (v) =>
{
    print("当执行 player 播放方法后 会调用的事件");
};
// 结尾事件,当视频播放到结尾处时调用
videoPlayer.loopPointReached += (v) =>
{
    print("视频播放到结尾处时会调用的事件");
};

2.3.全景视频

Unity 支持两种类型的全景视频:

  • 等距圆柱投影布局:也被称为球面投影、简化圆柱投影、矩形投影或普通圆柱投影。这种布局的全景视频,其宽高比通常为 2:1(对应 360 度内容)或 1:1(对应 180 度内容)。
  • 立方体贴图布局:由六个正方形纹理的集合构成。该布局的全景视频宽高比包括 1:6、3:4、4:3、6:1 等。可以通过视频分辨率的比值来判断该全景视频属于哪种布局类型。

在 Unity 中使用全景视频
(1). 导入等距圆柱投影布局的视频文件时,可以通过观察其分辨率是否为 2:1 来进行初步判定。
(2). 使用 Video Player 组件,将其渲染模式设置为以 Render Texture(渲染纹理)来播放视频。
(3). 设置接受渲染纹理的天空盒材质,具体操作为将天空盒材质的着色器设置为 Skybox>Panoramic。
(4). 配置场景,使其使用所设置的天空盒材质。
(5). 运行测试,尝试旋转摄像机的角度,查看全景视频的播放效果。

需要注意的是,为了获得更好的视觉效果,尽量使用较高分辨率的全景视频,如 4K 或 8K 分辨率。但对于一些老旧设备或者移动设备,由于性能限制,可能最多只能支持 2K 分辨率,具体情况需根据实际设备性能来确定。

** 使用全景视频时的注意事项**
(1). Render Texture(渲染纹理)方面:确保 Render Texture 的 Size(尺寸)与视频的尺寸保持一致,可以在视频预览窗口中选择 Source Info(源信息)来查看视频的分辨率。同时,将渲染纹理的 Depth Buffer(深度缓冲区)设置为 No depth buffer(无深度缓冲区)。
(2). 天空盒材质方面
- 对于等距圆柱投影布局,在天空盒材质中将 Mapping(映射)设置为 Latitude Longitude Layout(经纬度布局),然后根据视频是 180 视图还是 360 视图,相应地选择 360 degree(360 度)或者 180 degree(180 度)。
- 对于立方体贴图布局,将 Mapping 设置为 6 Frames Layout(6 帧布局)。
- 如果视频是 VR 视频:
- 当视频内容分为左右双眼显示时,需要将天空盒材质的 3D Layout(3D 布局)设置为 Side by Side(并排)。
- 当左右侧内容在视频中呈上下分布时,3D Layout 应设置为 Over Under(上下)。

3.ScriptableObject

3.1.ScriptableObject数据文件的创建

注意:需要继承ScriptableObject类

(1)为类添加CreateAssetMenu通过菜单创建资源特性 [CreateAssetMenu(fileName = “默认文件名”, menuName = “在Asset/Create菜单中显示的名字”, order = 再Asset/Create菜单中的位置(多个时可以通过它来调整顺序))]


[CreateAssetMenu(fileName ="MrTangData", menuName ="ScriptableObject/我的数据", order = 0)]
public class MyData : ScriptableObject
{
}

(2)利用ScriptableObject的静态方法创建数据对象,然后将数据对象保存在工程目录下

// 调用ScriptableObject的静态方法CreateInstance<T>,创建一个继承自ScriptableObject的MyData类型的实例
// 这里的MyData是自定义的数据类,必须继承自ScriptableObject
MyData myDataAsset = ScriptableObject.CreateInstance<MyData>(); 

// 使用Unity编辑器的API AssetDatabase的CreateAsset方法,根据创建的实例myDataAsset
// 在指定路径"Assets/Unity进阶ScriptableObject教程/Lesson02_ScriptableObject数据文件的创建/MyDataTest.asset"创建一个数据资源文件
AssetDatabase.CreateAsset(myDataAsset, "Assets/Unity进阶ScriptableObject教程/Lesson02_ScriptableObject数据文件的创建/MyDataTest.asset");

// 调用AssetDatabase的SaveAssets方法,保存当前创建的所有资源文件到项目中
AssetDatabase.SaveAssets();

// 调用AssetDatabase的Refresh方法,刷新Unity编辑器的界面,使新创建的资源在编辑器中及时显示出来
AssetDatabase.Refresh();

3.2.ScriptableObject数据文件的使用

方法一:通过Inspector中的public变量进行关联
方法二:通过资源加载的信息关联
myData = Resources.Load<MyData>("MyDataTest");

3.3.ScriptableObject非持久数据和持久化

分类详情
回顾创建非持久化数据MyData myData = ScriptableObject.CreateInstance();
回顾数据持久化数据在硬盘和内存之间交互,使用时从硬盘读取,改变后保存到硬盘,游戏退出或程序关闭后数据存储在硬盘实现持久化。已讲授的数据持久化方案包括PlayerPrefs、XML、Json、二进制等
利用Json结合ScriptableObject存储数据示例代码如下:
csharp<br>myData.PrintInfo();<br>myData.i = 9999;<br>myData.f = 6.6f;<br>myData.b = true;<br>//将数据对象序列化为json字符串:<br>string str = JsonUtility.ToJson(myData);<br>print(str);<br>//把数据序列化后的结果存入指定路径当中:<br>File.WriteAllText(Application.persistentDataPath + "/testJson.json", str);<br>print(Application.persistentDataPath);<br>
利用Json结合ScriptableObject读取数据示例代码如下:
csharp<br>//从本地读取Json字符串:<br>str = File.ReadAllText(Application.persistentDataPath + "/testJson.json");<br>//根据json字符串反序列化出数据将内容覆盖到数据对象中:<br>JsonUtility.FromJsonOverwrite(str, myData);<br>// FromJsonOverwrite方法是将JSON数据覆盖到现有对象<br>// FromJson方法JSON数据转换为新的对象实例用一个新对象来接(就算用老对象来接 也是引用新的实例)<br>myData.PrintInfo();<br>
总结ScriptableObject的数据在游戏发布运行过程中无法持久化,可借助PlayerPrefs、XML、Json、二进制等方式实现持久化,但不建议用ScriptableObject做数据持久化

3.4.ScriptableObject单例

实现单例模式化获取数据
实现单例模式化获取数据需要运用到面向对象、单例模式、泛型等知识。我们可以创建一个ScriptableObject数据单例模式基类,这样一来,只要让子类继承这个基类,就可以直接获取到数据,而无需再使用public关联或者资源动态加载的方式。

我们定义了一个名为SingleScriptableObject的泛型类,它继承自ScriptableObject。这个类的作用是实现单例模式的ScriptableObject对象。在类中,定义了一个私有静态字段instance,用于存储单例对象;还定义了一个公共静态属性Instance,用于获取单例对象,该属性的类型为泛型参数T

Instance属性的get访问器中,首先检查单例对象instance是否为空。如果为空,就尝试从资源路径下加载对应的数据资源文件。按照约定,数据资源文件的路径为Resources/ScriptableObject/,并且文件名与类名相同。如果没有找到对应的数据资源文件,为了保证程序的正常运行,会直接创建一个新的数据对象。最后,返回单例对象。具体代码如下:

public class SingleScriptableObject<T> : ScriptableObject where T : ScriptableObject
{
    private static T instance;

    public static T Instance
    {
        get
        {
            // 如果为空 首先应该去资源路径下加载 对应的 数据资源文件
            if (instance == null)
            {
                // 我们定两个规则
                // 1.所有的 数据资源文件都放在 Resources文件夹下的ScriptableObject中
                // 2.需要复用的 唯一的数据资源文件名 我们定一个规则:和类名是一样的
                instance = Resources.Load<T>("ScriptableObject/" + typeof(T).Name);
            }

            // 如果没有这个文件 为了安全起见 我们可以在这直接创建一个数据
            if (instance == null)
            {
                instance = CreateInstance<T>();
            }
            // 甚至可以在这里 从json当中读取数据,但是我不建议用ScriptableObject来做数据持久化

            return instance;
        }
    }
}

例如,让RoleInfo类继承SingleScriptableObject

public class RoleInfo : SingleScriptableObject<RoleInfo>

或者创建TestData类继承SingleScriptableObject

[CreateAssetMenu]
public class TestData : SingleScriptableObject<TestData>
{
    public int i;
    public bool b;
}

这样,就可以直接使用Instance单例来获取数据文件了。无论Resource/ScriptableObject路径下有没有对应的数据文件都可以正常获取。如果没有,程序会动态生成默认的数据。使用示例如下:

print(RoleInfo.Instance.roleList[0].id);
print(RoleInfo.Instance.roleList[1].tips);

print(TestData.Instance.i);
print(TestData.Instance.b);

4.TextMeshPro

4.1.TextMeshPro UI

4.1.1.TextMeshPro UI组件参数
分类具体项目详细说明
Enable RTL Editor开启后文本从右向左显示,下方出现RTL Text Input框,可查看并编辑反转文本
Text StyleH1、H2、H3:标题级别,数字越大级别越低
C1、C2、C3:颜色级别,区分文本颜色
Quote:引用文本样式
Link:超链接文本格式样式
Title:标题样式
Normal:普通正文文本样式
字体相关Font Asset:可选择默认字体资源,TMP字体支持自定义
Material Preset:TMP字体显示基于材质球,切换材质球改变渲染效果(因Shader着色器不同),可调整材质球参数(如边缘线)
Font StyleB:加粗(Bold);I:斜体(Italic);U:下划线(Underline);S:删除线(Strikethrough);ab:小写文本(Small Caps Lowercase);AB:大写文本(All Caps);SC:大写文本,按实际输入字母大小显示(Small Caps)
Auto Size:勾选后有更多设置选项,消耗大少用。Auto Size OptionsMin:最小字体大小(Minimum Size);Max:最大字体大小(Maximum Size);WD%:水平挤压字符(Width Percentage);Line:减少行间距(负数)(Line Spacing Reduction,negative value)
颜色顶点颜色与材质和纹理颜色相乘,决定字体最终颜色
颜色渐变勾选后有新参数:
Color Preset:颜色预设(Color Preset)
Color ModeSingle:与顶点颜色叠加(Overlay with Vertex Color);Horizontal Gradient:双色水平渐变(Two-Color Horizontal Gradient);Vertical Gradient:双色垂直渐变(Two-Color Vertical Gradient);Four Corners Gradient:四色四角渐变(Four-Color Four-Corners Gradient)
Colors:依颜色模式设置多个颜色值
Override Tags启用可忽略富文本标记对颜色的更改,通常不勾选
间距字符间距 (Character)控制每个字符间的间距
单词间距 (Word)控制每个单词间的间距
行间距 (Line)控制行与行间的间距,适用于自动换行文本
段落间距 (Paragraph)控制段落间的间距,段落由显式换行符定义
对齐水平对齐左对齐:文本靠左对齐(Left Align)
居中对齐:文本居中对齐(Center Align)
右对齐:文本靠右对齐(Right Align)
拉伸左对齐:增加间距填满行,最后一行不拉伸(Justify Left,last line not justified)
拉伸齐平:类似拉伸左对齐,最后一行也拉伸(Justify Full)
网格居中:按网格居中文本,效果更细致(Mesh Center,more delicate effect)
垂直对齐顶部对齐:文本靠顶部对齐(Top Align)
中部对齐:文本垂直居中对齐(Middle Align Vertically)
底部对齐:文本靠底部对齐(Bottom Align)
基线对齐:第一行基线与显示区域中间对齐,适用于单行文本(Baseline Align,suitable for single-line text)
中线对齐:类似中部对齐,依文本网格边界垂直放置,适合狭小空间(Middle Line Align,placed vertically according to text mesh boundary,suitable for narrow spaces)
卡普赖恩对齐:第一行中间与显示区域中间对齐(Cap Height Align,align the middle of the first line with the middle of the display area)
包裹与溢出WrappingDisabled:文本不自动换行,溢出显示(受溢出选项影响)(Text does not wrap automatically, and overflows as shown (affected by the overflow option))
Enabled:控件大小变化时文本自动换行(Text wraps automatically when the control size changes)
OverflowOverflow:文本溢出到显示区域外,若启用包裹会自动换行(Text overflows outside the display area. If wrapping is enabled, the text will wrap automatically)
Ellipsis:超出部分用省略号代替(Replace the overflowing part with an ellipsis)
Masking:类似Overflow,隐藏显示区域外内容(Similar to Overflow, hide the content outside the display area)
Truncate:超出内容直接截断不显示(Truncate the overflowing content and do not display it)
Scroll Rect:仅用于旧版TextMesh Pro项目兼容,新项目建议用遮罩模式(Only used for compatibility with legacy TextMesh Pro projects. It is recommended to use the masking mode for new projects)
Page:文本切分为多个页面,可选择显示具体页面内容(Divide the text into multiple pages, and you can select the specific page content to display)
Linked:文本扩展到指定TextMesh Pro游戏对象,当前对象溢出内容在关联对象显示(Extend the text to the specified TextMesh Pro game object, and the overflowing content of the current object will be displayed in the associated object)
UV映射Horizontal MappingCharacter:在每个文字上水平拉伸纹理(Stretch the texture horizontally on each character)
Line:在每条线宽度上水平拉伸纹理(Stretch the texture horizontally across the entire width of each line)
Paragraph:在整个文本中水平拉伸纹理(Stretch the texture horizontally across the entire text)
Match Aspect:水平缩放纹理,保持纵横比不变(Scale the texture horizontally while maintaining the aspect ratio)
Vertical MappingCharacter:在每个文字上垂直拉伸纹理(Stretch the texture vertically on each character)
Line:在每条线高度上垂直拉伸纹理(Stretch the texture vertically across the entire height of each line)
Paragraph:在整个文本中垂直拉伸纹理(Stretch the texture vertically across the entire text)
Match Aspect:垂直缩放纹理,保持纵横比不变(Scale the texture vertically while maintaining the aspect ratio)
Line Offset选择“Line”“Paragraph”或“Match Aspect”模式时,控制纹理偏移位置(Control the texture offset position when the “Line”, “Paragraph”, or “Match Aspect” mode is selected)
额外设置边缘设置 (Margins)设置文本和文本容器间的间距,可用负值使文本超出边框,可在Scene窗口操作黄色边框调整
几何排序 (Geometry Sorting)Normal:按显示顺序排序,重叠时靠近摄像机的在前面(Sort according to the display order. When quadrilaterals overlap, the ones closer to the camera are in the front)
Reverse:按相反顺序绘制四边形,重叠时远离摄像机的在前面(Draw quadrilaterals in the opposite order. When they overlap, the ones farther from the camera are in the front)
是否静态缩放 (Is Scale Static)告诉TMP文本系统文本无缩放变化,TMP跳过缩放计算,减少CPU和GPU负担,适用于缩放比例固定的文本对象
富文本 (Rich Text)控制是否开启富文本,默认开启,开启后可识别富文本关键字
射线检测目标 (Raycast Target)决定文本是否响应点击、触摸等事件,关闭时触摸和点击“穿透”,需响应则勾选
遮罩裁剪 (Maskable)决定文本是否被Mask组件裁剪,勾选时被裁剪,取消勾选时不被裁剪
转义字符解析 (Parse Escape Characters)决定文本是否解析转义字符,开启时解析,关闭时无效
可见下降 (Visible Descender)用脚本缓慢显示文本时启用,可显示底部文本,显示新行时向上移动,需将垂直对齐改为Bottom
精灵资源 (Sprite Asset)允许在文本中嵌入2D精灵图片,处理图文混排,如嵌入表情符号
样式表资源 (Style Sheet Asset)管理和应用文本样式,TMP_Style Sheet文件定义多种样式,可在多个文本组件重复使用,确保样式一致
自动字符间距调整 (Kerning)自动调整字符间距,提高文本可读性和美观性
额外填充 (Extra Padding)为文本边界添加额外填充,避免文本与边界过近,提升视觉效果
4.1.2.TextMeshPro UI参数和方法```

TextMeshPro UI 组件常用属性

属性说明示例代码
文本内容 (text)用于设置或获取文本显示的内容textMeshProUGUI.text = "123123adfasdklf545454564654654646454564654132156465424";
字体 (font)可获取或设置所使用的字体textMeshProUGUI.font = ...; // 获取或设置字体
字体大小 (fontSize)设置字体的大小textMeshProUGUI.fontSize = 10;
颜色 (color)设置文本的颜色textMeshProUGUI.color = Color.black;
对齐方式 (alignment)设置文本的对齐方式textMeshProUGUI.alignment = TextAlignmentOptions.Center;
行间距 (lineSpacing)设置文本行与行之间的间距textMeshProUGUI.lineSpacing = 50;
是否启用富文本 (richText)决定是否启用富文本格式textMeshProUGUI.richText = false;

TextMeshPro UI 组件常用方法

方法说明示例代码
SetText设置文本内容,支持富文本格式textMeshProUGUI.SetText("<color=blue>Hello, World!</color>");
Rebuild强制重新构建文本网格,在文本内容或样式更改后调用textMeshProUGUI.Rebuild(UnityEngine.UI.CanvasUpdate.Prelayout);
ForceMeshUpdate在运行时动态更改文本时,强制更新文本网格textMeshProUGUI.ForceMeshUpdate();
Length获取文本中字符的数量print(textMeshProUGUI.text.Length);

CanvasUpdate 枚举

  • Prelayout:布局前调用
  • Layout:布局时调用
  • PostLayout:布局后调用
  • PreRender:渲染前调用
  • LatePreRender:渲染后调用
  • MaxUpdateValue:最后调用

** UI 事件监听**
若要为 TMP UI 添加交互事件,可使用 UGUI 中的 EventTrigger 组件。

4.2. 3D 文本和 UI 文本区别:

分类3D 文本(TextMeshPro)UI 文本(TextMeshProUGUI)
使用的组件使用 TextMeshPro 组件使用 TextMeshProUGUI 组件
用途主要用于在 3D 场景中显示文字主要用于在 UI 中显示文字,具备与 UI 相关的一些属性
渲染方式直接渲染在场景上通过 UGUI 的 Canvas 系统渲染
交互方式通常通过添加碰撞器进行碰撞检测来判断交互一般利用 UI 系统的交互规则,比如 EventTrigger
如何选择如果文本需要与 3D 场景交互,或者需要在 3D 场景中显示,选择 3D 文本 TextMeshPro,将其视为 3D 物体进行处理如果文本需要在 UI 系统中使用,选择 TextMeshProUGUI,将其视为 UI 组件处理
参数相关3D 文本的参数设置与 UI 文本的相关参数几乎完全一致UI 文本有与 UI 系统相关的一些属性设置
脚本控制示例代码:
using TMPro;using UnityEngine;public class Lesson09_3D 文本 : MonoBehaviour{ public TextMeshProUGUI textMeshProUGUI; // UI 文本组件<br> public TextMeshPro textMeshPro; // 3D 文本组件}
与 3D 文本在脚本控制上,组件名称不同,其他部分属性和方法几乎一致

4.3.字体资源

4.3.1.字体资源-基本信息设置
分类设置项详细说明
更新纹理图集操作按钮点击“更新纹理图集”,打开字体资源创建器新窗口,用于配置字体的图集纹理信息和生成静态字体资源,可将 Unity 字体资源转换为 TMP 字体资源,生成后若不再用源字体资源重新生成 TMP 字体,可删除源字体资源
基本信息设置Source Font File选择用于生成 TMP 字体资源的字体
Sampling Point Size设置用于生成字体纹理的字体大小(以磅为单位),有“Auto Sizing”(使用尽可能大的大小,常用设置)和“Custom Size”(自定义大小)两种方式
Padding指定字体纹理中字符之间的间距(以像素为单位),填充越大,过渡越平滑
Packing MethodFast:字符打包速度快,但字体的大小可能更小,测试字体时可使用
Optimum:尽可能合理利用纹理中的空间,保持字符最大可能的字体大小,正式确定字体时使用
Atlas Resolution根据字符集选择合适的分辨率,如只有 ASCII 字符,用 512x512 即可;中文字体时,需要更大更多的图集(比如 1024x1024)
Character SetASCII:标准 ASCII 字符集(字母,数字,标点符号)
Extended ASCII:拓展 ASCII 字符集(增加了许多特殊字符和符号)
ASCII Lowercase:仅包含小写字母字符(a~z)
ASCII Uppercase:仅包含大写字母字符(A-Z)
Numbers + Symbols:包含数字(0-9)和常见的符号(如 !, @, #, $, % 等)
Custom Range:允许用户定义一个自定义字符范围,用户可以指定要包含的 Unicode 范围
Unicode Range(Hex):允许用户输入 Unicode 范围的十六进制值
Custom Characters:用户可以手动输入要包含的具体字符,可以是任何字符(如字母、符号等)
Characters from File:从文本文件中读取字符,允许用户根据文件内容自动生成字符集,适合大量字符的处理
Select Font Asset选择对应的字体资源
Character Sequence当选择需要自己输入字体的相关模式时,会出现
Render ModeSMOOTH_HINTED:抗锯齿位图,字符像素和纹理像素对齐,以获得更清晰的结果,通常用于小字体或需要精确对齐的情况
SMOOTH:采用抗锯齿效果,提供平滑的边缘,适合大多数情况下的文本显示
COLOR_HINTED:基于颜色的抗锯齿效果,强调颜色的呈现,适合需要突出颜色的文本
COLOR:不使用抗锯齿,直接渲染文本的颜色,适合在高对比度或需要清晰边缘的场景中使用
RASTER_HINTED:位图渲染,通常用于较小字体,能够提供较高的清晰度
RASTER:位图渲染,不进行抗锯齿处理,提供快速渲染,但在边缘可能出现锯齿现象
SDF:使用带符号的距离场技术渲染,能够在缩放时保持清晰度
SDF8:使用 8 位 SDF 渲染,支持更小的纹理,适合资源受限的环境
SDF16:使用 16 位 SDF 渲染,提供更高的清晰度和更细腻的边缘
SDF32:使用 32 位 SDF 渲染,具有最高的细节和清晰度
SDFAA_HINTED:使用抗锯齿的 SDF 渲染,提供平滑的边缘和清晰的字符显示
SDFAA:使用 SDF 渲染,但不进行抗锯齿处理,快速渲染
Get Kerning Pairs用于在字体资源中获取字偶间距调整(Kerning)对
Generate Font Atlas生成字体图集
Save保存图集
Save as…另存为
字体属性设置Family Name字体名称,无法手动修改,创建字体资源时默认设置
Style Name样式名称,无法手动修改,创建字体资源时默认设置
Point Size字体大小(以磅 Point,缩写 pt 为单位),1 磅等于 1/72 英寸(约 0.353 毫米),在字体设计中,磅数用来表示字体的高度
Scale对字体进行缩放,1 为原始大小,不缩放
Line Height表示每行文本的高度,通常是基于最大字形的高度计算的,决定了两行文本之间的距离
Ascent Line字形中最高的点到基线的垂直距离,表示字母中最高部分(大写字母或某字符的上部)的位置
Cap Line表示所有大写字母的顶部所处的水平线,通常略低于上升线
Mean Line表示小写字母的顶部所处的水平线,表示小写字母的标准高度
BaseLine所有字母字符所处的水平线,大多数字符都在这条线的上方
Descent Line字形中最低的点到基线的垂直距离,表示字母中最低部分的水平线
Underline Offset下划线相对基线的位置
Underline Thickness控制下划线的粗细
Strikethrough Offset控制删除线相对于基线的位置
Superscript Offset使上标文本相对基线偏移
Superscript Size相对于正常字体大小缩放上标文本
Subscript Offset使下标文本相对基线偏移
Subscript Size相对于正常字体大小缩放下标文本
Tab Width指定 TAB 字符的宽度
4.3.2.字体资源-生成设置和图集纹理
分类设置项详细说明
基本设置Source Font File用于指定字体资源所使用的字体文件
Atlas Population Mode纹理图集生成方式,有以下两种模式:
Static(静态模式):字体集在创建时需要一个固定的纹理图集,适用于字符已知且不需要动态变化的情况,如仅有少量英文字符时。
Dynamic(动态模式):字体纹理图集会在运行时根据需要动态生成,能够显示更多字符,适合中文项目或多语言项目
Atlas Render Mode字体渲染模式,具体如下:
SMOOTH_HINTED:抗锯齿位图,字符像素和纹理像素对齐,适合小字体或精确对齐的场景。
SMOOTH:提供平滑边缘,适用于大多数文本显示,兼顾清晰度和性能。
COLOR_HINTED:基于颜色的抗锯齿,突出颜色效果。
COLOR:不使用抗锯齿,适用于高对比度或需要清晰边缘的场景。
RASTER_HINTED:位图渲染,适合较小字体,但放大时可能模糊。
RASTER:快速渲染模式,但边缘可能出现锯齿。
SDF:带符号距离场技术,支持缩放时保持清晰。
SDF8:8 位 SDF 渲染,适用于资源受限环境。
SDF16:16 位 SDF 渲染,提供更高清晰度。
SDF32:32 位 SDF 渲染,适合需要极高质量的文本。
SDFAA_HINTED:抗锯齿的 SDF 渲染,提供平滑边缘和清晰字符显示。
SDFAA:SDF 渲染但无抗锯齿,快速渲染但可能出现锯齿
Sampling Point Size设置生成字体纹理时的字体大小,单位为磅,有以下两种设置方式:
Auto Sizing:使用尽可能大的字体大小(推荐)。
Custom Size:自定义字体大小
Padding指定字体纹理中字符之间的间距,单位为像素,较大的填充值可以提供更平滑的过渡效果
Atlas Width设置字体纹理图集的宽度
Atlas Height设置字体纹理图集的高度
Multi Atlas Textures是否采用多图纹理,允许在字体资源中生成多个纹理图集(Atlas),而不仅仅是一个。这样可以更灵活地管理不同字符集或不同字体样式,提高性能和内存使用效率,尤其是在需要渲染大量不同字符的情况下建议使用
Clear Dynamic Data On Build在构建时清除动态生成的数据。若选择了动态字体模式,构建时会移除不再需要的动态字符数据,以节省内存,减少最终构建包的大小,确保只包含必要的字符数据
Font Atlas生成字符资源时创建的字体纹理图集
Font Material生成字体资源时创建的字体材质
4.3.3.字体资源-字体粗细
分类设置项详细说明
字体类型Regular Typeface常规字体
Italic Typeface斜体字体
字体粗细等级100 - thin
200 - Extra - Light超轻
300 - Light
400 - Regular常规(仅限斜体)
500 - Medium
600 - Semi - Bold半粗
700 - Bold粗体
800 - Heavy
900 - Black黑体
默认粗细Normal Weight没有字体资源用时使用的常规字体粗细
Bold Weight没有字体资源用时使用的粗体字体粗细
间距设置Spacing Offset使用普通文本样式时,在字符之间的间隙偏移
Bold Spacing没有指定粗体资源时,粗体文本字符之间的间距偏移
斜体样式Italic Style400 - Regular > Italic Style 变体指定字体资源没有设置时,TMP将使用常规样式字体资源中的字符倾斜该字段中的量来达到斜体效果
制表符设置Tab Multiple该值乘以字体空格符的宽度,用来表示制表符的大小
4.3.4.字体资源-其他设置
分类设置项详细说明
备用字体资源Fallback Font Assets每个字体资源包含字符数量有限,当使用当前字体资源不包含的字符时,TMP 会搜索回退字体列表,找到包含该字符的字体资源用于呈现字符
Fallback List列出所有备用字体资产,主字体缺少某些字符时,系统按顺序尝试使用这些备用字体查找。可创建字体变体关联该列表,在字体变体中做特殊字符添加等处理
字符表Character Table - Character Search用于字符查找
字形表Glyph Table - Glyph Search用于字形搜索
X、Y、W、H字符在纹理中对应的位置范围
W、H字形的宽高
BX、BY相对基线的左上角位置
AD和下一个字符间隔的宽
Scale缩放大小
Atlas Index图集索引,在开启多图集时,表示在第几个图集中
字形调整表Glyph Adjustment Table控制特定字符对之间的间距
Adjustment Pair Search用于调整对搜索
Char 左和右想要查找的字符
ID 左和右唯一标识符,一般显示左右字符的 ASCII 十进制编码
OX 左和右字符原点坐标 X
OY 左和右字符原点坐标 Y
AX 左和右字符的宽度
Add New Glyph Adjustment Record添加新的字形调整记录

4.4.富文本标签

标签详情
文本加粗<b></b>
文本斜体<i></i>
加下划线<u></u>
改变大小<size=数值></size>
改变颜色<color=#RGBA 16 进制></color>
对齐方式<align=left、center、right、justified、flush></align>
背景高亮<mark=#RGBA 16 进制></mark>
透明度<alpha=#A 16 进制>
全部大写<allcaps></allcaps>
改字体和材质(可选)<font="字体名" material="材质名"></font>
加上标 (平方)<sup></sup>
加下标 (化学式)<sub></sub>
超链接<link="链接"></link>
文本加粗示例<b>这是文本加粗示例。</b>
文本斜体示例<i>这是文本斜体示例。</i>
加下划线示例<u>这是加下划线示例。</u>
改变大小示例<size=30>这是改变大小示例。</size>
改变颜色示例<color=#00FF00>这是改变颜色示例。</color>
左对齐示例<align=left>这是左对齐示例。</align>
背景高亮示例<mark=#FFFF00>这是背景高亮示例。</mark>
透明度示例<alpha=#80>这是透明度示例。</alpha>
全部大写示例<allcaps>这是全部大写示例。</allcaps>
改字体和材质示例<font="LiberationSans SDF" material="LiberationSans SDF - Outline">123 这是改字体和材质示例。</font>
加上标示例正常<sup>这是加上标示例。</sup>
加下标示例正常<sub>这是加下标示例。</sub>
超链接示例<link="https://www.example.com">这是超链接示例。</link>

4.5.样式表

分类详情
定义样式表是 TMP 提供的与富文本标签配合使用的功能,可自定义文本样式,在富文本中用<style="样式表名"></style>标签包裹文字应用样式,本质是对富文本标签的复用,能避免重复书写冗余的富文本样式编码
修改和创建修改默认样式表
创建样式表
配置参数Name
HashCode
Opening Tags
Closing Tags
Up、Down
+、-
Previous、Next
样式对应
设置关联每一个 TMP 控件中的额外设置中,都可关联对应的样式表资源,若未设置,则使用默认样式表

4.6.图文混排

分类操作详情
定义精灵图片资源是与富文本标签配合使用的资源,可在 TMP 文本中显示图片,实现图文混排,创建并配置好后,利用富文本标签在文本中展示图片
创建创建图集根据需求建立图集纹理,Texture Type 设为 Sprite,Sprite Mode 设为 Multiple,需导入 2D Sprite 包,在 Sprite Editor 中将图集中图片划分为单独的 Sprite
创建精灵图片资源准备好图集文件后,在 Project 窗口选中图集右键 → Text Mesh Pro → Sprite Asset 创建。创建后需设置:
1. 图片名称。
2. 图片位置和宽度相关参数,配合全局偏移和缩放参数设置。
关键参数:
BX、BY:相对于基线的原点的左上角。
AD:放置下一个内容时向右前进的位置
使用默认资源获取图片使用以下标签格式:
1. <sprite index=图片ID color=#RGBA的16进制(可选)>
2. <sprite name="图片名" color=#RGBA的16进制(可选)>
3. <sprite=图片ID color=#RGBA的16进制(可选)>
指定资源获取图片使用以下标签格式:
1. <sprite="资源名" index=图片ID color=#RGBA的16进制(可选)>
2. <sprite="资源名" name="图片名" color=#RGBA的16进制(可选)>
关联使用可将精灵图片资源直接关联到对应的 TMP 文本控件中使用,若不关联,则使用默认资源
示例演示<sprite index=0 color=#FF0000>
<sprite name="EmojiOne_0" color=#00FF00>
<sprite=0 color=#0000FF>

4.7.项目设置TextMeshPro基本设置

分类设置项详细说明
默认字体设置Default Font Asset存储默认字体设置相关信息
Path字体资源的存储位置
备用字体资源Fallback Font Assets设置备用字体资源,用于当前字体资源无法满足需求的场景
Fallback Material Settings备用材质设置
Match Material Presets启用后,备用字体中的字形与主字体的样式匹配,使主字体和后备字体看起来更接近
动态字体系统设置Dynamic Font System Setting配置动态字体系统相关选项
Get Font Features at Runtime运行时获取字体功能
Missing Character Unicode当找不到字符时使用的替代字符,默认值为 0,显示为一个正方形轮廓
Disable warnings启用后可避免 Unity 为每个缺失字形记录的警告
文本容器默认设置Text Container Default Setting设置文本容器的默认行为和选项
TextMeshPro3D 文本默认大小
TextMeshPro UIUI 文本默认大小
Enable Raycast Target是否默认为文本对象启用射线检测
Auto Size Text Container启用后会自动调整文本容器的大小
Is Object Scale Static是否为静态缩放
文本组件默认设置Text Component Default Setting设置文本组件相关的默认行为
Default Font Size默认字体大小
Text Auto Size Ratios文本自动调整大小比例
Word Wrapping是否启用自动换行
Kerning是否启用字偶间距调整
Extra Padding是否额外进行填充,可降低字符在精灵边界处被截断的几率
Tint All Sprites为所有精灵图片着色
Parse Escape Sequence是否解析转义字符
默认精灵图片资源Default Sprite Asset设置文本精灵图片相关选项
Missing Sprite Unicode精灵缺失时采用的替代符,默认为方形轮廓
IOS Emoji Support是否支持 IOS 表情符号
Path精灵图片资源存储路径
默认样式表Default Style Sheet设置默认样式表的路径
Path样式表资源存储路径
默认颜色渐变预设Color Gradient Presets设置默认颜色渐变选项
Path颜色渐变预设存储路径
亚洲语言换行规则Line Breaking for Asian Languages用于处理亚洲语言的换行规则,设置亚洲语言换行相关的行为
Leading Characters前导符号,一般不允许出现在行首,遇到这些字符触发自动换行时,字符会显示在尾部
Following Characters尾随符号,一般不允许出现在行尾,如果这些符号出现在行尾触发自动换行时,会将这些符号移动到下一行
韩语相关设置Korean Language Options用于设置与韩语换行规则相关的选项
Use Modern Line Breaking使用现代换行,启用后将采用更符合韩语规则的换行方式

4.8.SDF材质球

分类设置项详细说明
SDF 含义有符号(Signed)距离可以为正或负,正表示点位于边界外部,负表示点位于边界内部
距离(Distance)每个像素点到字符边缘的距离
场(Field)整个字体或图形周围的距离值的分布
技术本质在 Shader 中利用 SDF 算法渲染文字,生成的字体纹理基于每个像素到字体边缘的距离值,存储在纹理灰度通道,渲染时着色器根据距离值计算字体边缘,呈现平滑字符轮廓
在 TMP 中的作用用于生成和渲染文本,使字体在任意大小或距离下保持清晰和锐利效果
SDF 材质球含义本质使用了 SDF Shader 的材质球
效果利用该 Shader 渲染的字体效果更好
可配置性Shader 提供许多可配置参数,调整参数可实现复杂美术表现效果
SDF 材质球主要内容基础表面设置(Face)Color:文本表面颜色,与 TMP 组件中设置颜色相乘叠加
Texture:为文本添加贴图
Tiling:平铺(缩放)
Offset:偏移
Speed:移动速度(可实现滚动效果,配合 UV 配置)
Softness:边缘柔和度,使文字边缘模糊
Dilate:拓展,类似改变字体粗细
边缘线设置(Outline)Color:边缘线颜色
Texture:边缘线纹理,与轮廓颜色相乘叠加
Thickness:轮廓粗细,值越大越粗
阴影(底层)设置(Underlay)Underlay Type
None:无阴影
Normal:标准底图样式
Inner:反转底图,用原始文本遮罩它
Color:底图阴影颜色
Offset X:X 轴偏移
Offset Y:Y 轴偏移
Dilate:拓展,改变粗细
Softness:边缘柔和度,使阴影边界模糊
照明设置(Lighting) - 斜面设置(Bevel)Type 类型
Outer Bevel:外斜面,字体有倾斜侧面的凸起效果
Inner Bevel:内斜面,字体轮廓向内凹陷
Amount:陡峭程度
Offset:位置偏移
Width:斜面大小
Roundness:使斜面更平滑
Clamp:限制斜面最大高度
照明设置(Lighting) - 本地照明设置(Local Lighting)Light Angle:光照角度
Specular Color:镜面反射颜色
Specular Power:镜面反射强度
Reflectivity Power:反射强度
Diffuse Shadow:漫反射阴影
Amblent Shadow:环境阴影
照明设置(Lighting) - 凹凸贴图设置(Bump Map)Texture:凹凸贴图
Face:凹凸影响程度
Outline:凹凸贴图对文本轮廓的影响程度
照明设置(Lighting) - 环境设置(Environment Map)Face Color:立方体贴图对文本颜色的影响
Outline Color:立方体贴图对轮廓颜色的影响
Texture:环境立方体贴图
Rotation:旋转环境贴图
发光设置(Glow)Color:发光颜色
Offset:发光效果中心偏移值
Inner:发光效果向内延伸距离
Outer:发光效果向外延伸距离
Power:发光强度
调试设置(Debug Settings)Font Atlas:字体图集
Gradient Scale:渐变比例
Texture Width/Height:纹理宽高
Scale X/Y:SDF 比例乘数
Sharpness:清晰度
Perspective Filter:透视过滤器,使文本在透视摄像机下更柔和
Offset X/Y:每个字符顶点位置的偏移量
Mask
关闭蒙版
硬蒙版
柔和蒙版
Clip Rect:剪辑矩形,设置遮罩矩阵范围
Stencil ID:模板 ID
Stencil Comp:模板成分
Uset Ratios:使用率
Cull Mode:裁剪模式

4.9.MP_TextEventHandler

主要类委托事件参数
TMP_TextEventHandleronLinkSelection当用户悬停或点击超链接时触发string linkInfo:超链接的相关信息;
string linkText:超链接显示的文本;
int index:超链接在文本中的索引位置
TMP_TextEventHandleronCharacterSelection当用户悬停或点击某个字符时触发char charInfo:被点击或悬停的字符;
int i:字符在文本中的索引位置
TMP_TextEventHandleronSpriteSelection当用户悬停或点击某一精灵图片时触发char spirteInfo:与精灵图片相关的字符信息;
int i:精灵图片在文本中的索引位置
TMP_TextEventHandleronWordSelection当用户悬停或点击某个单词时触发string word:被点击或悬停的单词;
int i1:单词在文本中的起始索引位置;
int i2:单词在文本中的结束索引位置
TMP_TextEventHandleronLineSelection当用户悬停或点击某一行文本时触发string lineInfo:被点击或悬停的行文本内容;
int i1:行在文本中的起始索引位置;
int i2:行在文本中的结束索引位置

4.10.TMP_TextUtilities

分类详情
获取给定位置文本中的具体信息获取链接索引int FindIntersectingLink(TMP_Text text, Vector3 position, Camera camera)
获取单词索引int FindIntersectingWord(TMP_Text text, Vector3 position, Camera camera)
获取单字符索引int FindIntersectingCharacter(TMP_Text text, Vector3 position, Camera camera)
获取行索引int FindIntersectingLine(TMP_Text text, Vector3 position, Camera camera)
获取离给定位置最近的文本信息获取链接索引int FindNearestLink(TMP_Text text, Vector3 position, Camera camera)
获取单词索引int FindNearestWord(TMP_Text text, Vector3 position, Camera camera)
获取单字符索引int FindNearestCharacterOnLine(TMP_Text text, Vector3 position, Camera camera)
获取行索引int FindNearestLine(TMP_Text text, Vector3 position, Camera camera)
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;

public class Lesson22_TMP_TextUtilities : MonoBehaviour, IPointerClickHandler
{
    public TextMeshProUGUI textMeshProUGUI;

    public void OnPointerClick(PointerEventData eventData)
    {
        print("OnPointerClick TextMeshProUGUI");

        // 获取链接索引,传入 TMP、鼠标位置、UI 摄像机(默认可以传 null)
        int linkIndex = TMP_TextUtilities.FindIntersectingLink(textMeshProUGUI, eventData.position, null);

        // 如果不为 -1,则证明点击到了一个超链接信息
        if (linkIndex != -1)
        {
            // 获取超链接显示的文本信息,例如 "百度"
            print(textMeshProUGUI.textInfo.linkInfo[linkIndex].GetLinkText());

            // 获取富文本标签 <link=?> 中的? 具体地址信息,例如 "谷歌"
            print(textMeshProUGUI.textInfo.linkInfo[linkIndex].GetLinkID());
        }

        // 获取单字符索引,传入 TMP、鼠标位置、UI 摄像机(默认可以传 null)、是否检测可见性
        int charIndex = TMP_TextUtilities.FindIntersectingCharacter(textMeshProUGUI, eventData.position, null, true);

        // 如果索引不为 -1,打印点击到的字符
        if (charIndex != -1)
        {
            print(textMeshProUGUI.textInfo.characterInfo[charIndex].character);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值