Skip to content

基本概念

Render Pipeline

游戏引擎将3D Scene渲染到屏幕上的过程

unity中有三种渲染管线

  • 内置:Built-in render pipeline
  • 通用:Universal Render Pipeline
  • 高级:High Definition Render Pipeline

URP (Universal Render Pipeline, 通用渲染管线)

  • 性能:前向渲染,对低端硬件友好;渲染控制:剔除、降级适合移动端
  • 可扩展:支持自定义渲染(custom render features) && Shade Graph自定义着色器
  • 支持多平台,增强不同设备下的视觉一致性
  • 不适合高级、极致真实的渲染

Post-Processing Effect (后处理效果)

是场景在渲染后的进一步处理,其包括

  • 抗锯齿 Anti-Aliasing
  • 景深 Depth of Field
  • 色彩调整 Color Grading
  • 动态模糊 Motion Blur
  • 辉光 Bloom
  • 屏幕空间反射 SSR

Global Volume (全局体积)

是post-process的载体,所有的后处理需要通过volume profile在global volume中定义

效果:对整个场景生效,影响相机渲染的所有内容

Local Volume(局部体积)

与全局体积对应,作用于局部效果

Canvas(画布)

canvas是UI的root节点:所有的UI元素都需要canvas才能渲染,是渲染的必要条件

维度投射:可以将三维空间的元素投射到二维

canvas在unity中有三种不同的模式

  • 默认模式:Overlay (screen space)
    • 位于最顶层,独立于相机
    • 尺寸与屏幕分辨率一致
  • 与相机绑定:Camera (screen space)
    • UI被渲染到指定相机视图中
    • 可设置渲染距离
  • World Space
    • 将UI设置为世界中的3D对象

MonoBehavior

Unity中的核心基类,继承自它的类可以基于hooks、event进行编程

hooks

  • Awake():在脚本实例被加载时调用,通常用于初始l化变量或引用其他组件。
  • Start():在脚本实例启用后,在第一帧更新之前调用,通常用于初始化需要在 Awake() 之后执行的逻辑。
  • Update():每帧调用一次,通常用于处理游戏逻辑和输入。
  • FixedUpdate():在固定的时间间隔调用,通常用于处理物理相关的逻辑。
  • LateUpdate():在 Update() 之后调用,通常用于处理相机跟随等需要在所有更新之后执行的逻辑。
  • OnEnable():当脚本实例被启用时调用。
  • OnDisable():当脚本实例被禁用时调用。
  • OnDestroy():当脚本实例被销毁时调用。

event

  • OnCollisionEnter(Collision collision):当碰撞发生时调用。
  • OnTriggerEnter(Collider other):当触发器被触发时调用。
  • OnMouseDown():当鼠标点击游戏对象时调用。
  • OnBecameVisible():当游戏对象进入相机视野时调用。
  • OnBecameInvisible():当游戏对象离开相机视野时调用。

GameObject

基本实体构建块。所有实体都通过GameObject来构建,其本身只是个容器,所有的行为通过组件来实现

默认会携带Transform组件,用于控制位置、方向、旋转、缩放

其在unity editor中可以以其作为层级结构 Hierarchy来组织场景中的对象

    GameObject gameObject = new GameObject("GameObject");
设置父级
    gameObject.transform.SetParent(transform);
RigidBody
    Rigidbody rb = gameObject.AddComponent<Rigidbody>();
    rb.mass = 2; 
    rb.useGravity = true; 
Light
	Light light = gameObject.AddComponent<Light>();
	light.type = LightType.Point;
Mesh
	MeshRenderer renderer = gameObject.AddComponent<MeshRenderer>();
	MeshFilter filter = gameObject.AddComponent<MeshFilter>();
	GameObject tempCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
	filter.mesh = tempCube.GetComponent<MeshFilter>().mesh;
	Object.Destroy(tempCube);
COllider
	Collider collider = gameObject.AddComponent<BoxCollider>();
Position
	gameObject.transform.position = new Vector3();

Mesh

mesh是三维模型的基础数据结构,定义物体的形状与外观。

由顶点、边、面组成

  • 顶点:Vertex
  • 边:Edge
  • 面:Face(多为三角形)

为什么面一般由三角形构成?

三角形是最简单的多边形,易于计算和渲染

Coroutine & Async

Coroutine

基于IEnumeratoryield return,的用于处理需要分步执行的任务的方式,通过yield return来暂停和继续。在unity中,coroutine用于轻量级异步编程,其life time与MonoBahaviour绑定

特性

  • 迭代器:基于IEnumerator实现, 通过yield return暂停执行
  • 主线程运行:Coroutine运行于主线程,适合处理与Unity对象相关的任务(动画、延时)

Async

C#的异步,基于TPL(Task Parallel Library)和状态机,通过await等待运行完毕

特性

  • 多线程并行
  • 非阻塞
  • 后台运行

具体实现

IO For User

在update中按帧调用

  void Update()
  {
    // 获取水平方向和垂直方向的输入
    float moveX = Input.GetAxis("Horizontal") * baseSpeed * Time.deltaTime;
    float moveZ = Input.GetAxis("Vertical") * baseSpeed * Time.deltaTime;
    // 根据输入移动当前GameObject
    transform.Translate(moveX, 0, moveZ);
  }

SerializeField

[SerializeField] 将private的属性强制序列化,其在Unity编辑器中显示
[System.Serializable] 标记类可被序列化,其实例可被unity中的序列化系统加载(Monobehaviour不支持序列化)

Unity UI与Script连接:在Empty Object-Serialize的类中,拖拽Unity视图节点

C#

IEnumerator

迭代器类型声明


视觉小说

文字渲染

渲染模式

  • 单字符叠加

    问题:
    - 使用特殊效果时,比如下划线、加粗,会把源码也渲染上来
    - 某个单词过长时,会导致换行出现问题
  • 打字机(tmpro)

  • 渐变(tmpro)

渲染组成

  • 文字
    • 当前要渲染的文本
    • 将要渲染的文本
    • 已有的文本
    • 整体的文本(已有文本 + 将要渲染的文本)
  • 文字颜色
  • 渲染速度
    • 基础速度
    • 加速系统
  • 渲染模式

TMPro的渲染流程

  1. 文字输入解析:文本、字体、颜色、样式
  2. 字形处理:选择字体 && 提取字形,转换为纹理或矢量数据
  3. 布局排版
  4. Mesh Generation:字符转换为一个四边形(Quad),并生成对应的顶点、UV 和三角形数据 && 使用纹理或材质渲染文本
  5. 渲染准备 & 渲染:使用着色器渲染文本 && 批处理减少绘制调用(Draw Calls) => GPU渲染

剧情组成部分

  • Dialogue System 对话系统:文本渲染 && 文本读取
    • Dialogue Container 对话容器:包括了UI层面的Container,Name,Text