URP是什么?
URP,即 Universal Render Pipeline(通用渲染管线),是 Unity 提供的一种轻量级、高性能的渲染管线,旨在为开发者提供灵活且可扩展的渲染框架,以便在不同平台上实现高质量的图形渲染效果
特点
-
轻量级设计:URP 专为移动设备和中低端 PC 优化,适合性能受限的平台。
-
单通道前向渲染:与 Unity 内置管线的多 Pass 渲染不同,URP 使用单 Pass 渲染,减少 Draw Call,提升性能。
-
可扩展架构:URP 支持通过 Renderer Features 添加自定义渲染效果,开发者可以灵活扩展渲染管线。
-
Shader Graph 集成:URP 支持 Shader Graph,允许开发者通过可视化界面编辑着色器。
-
性能优化:URP 提供了 GPU Instancing、SRP Batcher 等优化技术,减少 CPU 到 GPU 的数据传输。
适用场景
-
移动端游戏:适用于 Android 和 iOS 平台,优化了性能和功耗。
-
VR/AR 应用:适合需要高性能渲染的虚拟现实和增强现实项目。
-
中低端 PC 游戏:在性能受限的设备上提供高质量的渲染效果。
-
2D/3D 混合项目:支持 2D 和 3D 游戏开发。
与内置渲染管线的对比
-
灵活性:URP 提供了更高的灵活性,允许开发者自定义渲染流程。
-
性能:URP 在移动设备和中低端 PC 上表现更优,适合资源受限的平台。
-
扩展性:URP 支持通过 Renderer Features 插入自定义渲染 Pass。
知识点一、Global Volume(全局体积)
1、什么是Global Volume
Global Volume 是 Unity 中用于后期处理(Post-Processing)的一个组件,属于通用渲染管线(URP)或高清渲染管线(HDRP)的一部分。它允许开发者为整个场景添加全局的视觉效果,例如颜色调整、光晕(Bloom)、景深(Depth of Field)、运动模糊(Motion Blur)等
在 Global Volume 的 Overrides
部分,点击 Add Override
按钮,选择需要的效果(如 Bloom、Color Adjustments 等),调整效果的参数以达到期望的视觉效果。
2、功能
-
全局影响:Global Volume 的效果会应用于场景中的所有摄像机。
-
配置文件(Profile):通过 Volume Profile 来定义和存储效果的参数。开发者可以创建或编辑配置文件,以实现不同的视觉风格。
-
效果覆盖(Overrides):可以在 Global Volume 中添加和调整各种效果的覆盖,从而改变默认的渲染行为。
-
优先级(Priority):当场景中有多个 Volume 时,可以通过设置优先级来决定哪个 Volume 的效果优先生效。
3、应用场景
-
全局视觉风格:为整个游戏或项目设置统一的视觉风格,例如整体色调调整、光晕效果等。
-
环境氛围增强:通过添加雾效(Fog)、环境光(Ambient Lighting)等效果,增强场景的氛围和沉浸感。
-
电影化效果:在过场动画或剧情场景中,通过运动模糊、景深等效果提升视觉质量。
-
艺术风格定制:通过颜色分级(Color Grading)和其他后期处理效果,实现复古、赛博朋克等特定的艺术风格。
知识点二、Animator和Animator Controller
1、Animator
Animator 是一个附加到游戏对象(GameObject)上的组件,它负责控制和管理 Animator Controller。
作用
-
引用 Animator Controller:Animator 组件引用一个 Animator Controller,该控制器定义了动画状态机和动画播放逻辑。
-
参数管理:Animator 组件提供了一个接口,用于从脚本中设置和获取动画参数(如布尔值、浮点数、整数、触发器等)。
-
事件触发:Animator 组件可以发送动画事件到附加到同一游戏对象的其他脚本,这些事件通常在特定的动画状态转换时触发。
-
层和子状态机:Animator 组件支持动画层和子状态机,允许更复杂的动画逻辑和重用。
-
动画播放控制:Animator 组件提供了播放、停止、重置动画的方法,以及控制动画播放速度和时间的方法。
2、Animator Controller
Animator Controller 是一个资源文件,它定义了动画状态机、状态转换规则、动画参数和动画事件。
作用
-
动画状态机:Animator Controller 包含一个或多个动画状态机,每个状态机由多个动画状态组成,状态之间可以定义转换条件和过渡动画。
-
状态转换:Animator Controller 定义了状态之间的转换规则,包括转换条件、过渡动画和过渡时间。
-
动画参数:Animator Controller 可以定义多种类型的动画参数,这些参数可以影响动画状态机的行为。
-
动画事件:Animator Controller 可以在特定的动画状态或转换中设置动画事件,这些事件可以在动画播放时触发。
-
层和子状态机:Animator Controller 支持动画层和子状态机,允许更复杂的动画逻辑和重用。
3、关系
-
Animator 和 Animator Controller 是紧密相关的:Animator 组件引用并使用 Animator Controller 来播放和管理动画。Animator Controller 定义了动画的逻辑和结构,而 Animator 组件则负责执行这些逻辑并控制动画的播放。
-
Animator 组件是 Animator Controller 的执行者:Animator 组件根据 Animator Controller 中定义的规则来播放动画,并根据游戏逻辑(如玩家输入、游戏状态等)动态调整动画参数和状态。
-
Animator Controller 是动画逻辑的定义者:Animator Controller 提供了一个可视化界面,允许动画师和开发者定义动画状态、转换规则、参数和事件,而无需编写代码。
通过这种分工合作,Animator 和 Animator Controller 使得在Unity中创建和管理复杂动画变得简单而高效。
知识点三、CinemachineVirtualCamera电影机/虚拟相机
1、CinemachineVirtualCamera是什么
CinemachineVirtualCamera 是 Unity 中 Cinemachine 系统的核心组件之一,它提供了一种无需编写代码即可实现复杂相机行为的方法。它允许开发者通过设置 Follow 和 Look At 参数来简单地实现相机的跟随和看向物体的功能
2、功能介绍
-
Follow:相机跟随的目标对象。
-
Look At:相机朝向的目标对象。
-
Priority:相机被激活的优先级。
-
Blending:相机切换时的过渡效果设置。
-
Lens:相机镜头的属性,如焦距、视场等。
2、应用场景
-
游戏内相机自动化控制。
-
电影化的游戏相机效果。
-
VR/AR 中的沉浸式相机体验。
-
动态相机视角调整以增强玩家体验。
知识点四、输入系统重构
第一步:勾选Generate C# Class选项,自动生成一个C#文件
第二步
双击PlayerInputActions,打开输入动作(Input Actions)的配置界面
配置WASD和Arow Keys 动作
绑定设置
第三步:输入代码处理
GameInput.cs
public class GameInput : MonoBehaviour
{
private PlayerInputActions playerInputActions;
private void Awake()
{
playerInputActions = new PlayerInputActions();
playerInputActions.Player.Enable();
}
public Vector2 GetMovementVectorNormalized()
{
Vector2 inputVector = playerInputActions.Player.Move.ReadValue<Vector2>();
inputVector = inputVector.normalized;
return inputVector;
}
}
private PlayerInputActions playerInputActions;存储输入动作的实例
playerInputActions = new PlayerInputActions(); 创建输入动作的实例
playerInputActions.Player.Enable();启用输入动作,使其可以监听
Player.cs
[SerializeField] private float moveSpeed = 8f;
[SerializeField] private GameInput gameInput;
private bool isBodyAmin;
void Update()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized();
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y);
transform.position += moveDir * moveSpeed * Time.deltaTime;
isBodyAmin = moveDir != Vector3.zero;
float rotateSpeed = 10f;
transform.forward =Vector3.Slerp(transform.forward,moveDir,Time.deltaTime*rotateSpeed);
}
Vector2 inputVector = gameInput.GetMovementVectorNormalized();获取归一化化的玩家移动输入