2D Platform
核心要素
包含玩法机制、关卡设计、角色控制、美术风格、音效音乐几个核心部分
玩法机制:围绕移动展开
核心机制:移动、跳跃、重力、互动(如推动箱子、触发开关)。 扩展机制:二段跳、冲刺、爬墙、特殊能力(如飞行、投掷武器)。 优化技巧:输入缓冲、空中控制、动画过渡。
关卡设计:围绕剧情展开
核心要素:平台布局、障碍物(尖刺、陷阱)、敌人、收集品(金币、隐藏道具)、检查点。 设计技巧:难度曲线、引导设计(灯光、箭头)、隐藏区域。
美术风格
常见风格:像素艺术(复古)、手绘风格(童话/奇幻)、扁平化设计(简洁/几何)。 设计技巧:层次感(前景、中景、背景)、色彩搭配、动画细节。
音效与音乐:围绕体验展开
核心要素:背景音乐、音效设计(移动、跳跃、攻击)、环境音效(风声、水流声)。 设计技巧:动态音乐、音效反馈。
剧情与叙事
常见叙事方式:环境叙事(壁画、废墟)、对话与过场动画、隐藏故事。 设计技巧:简洁明了、情感共鸣(角色成长、友情)。
基础知识
Layout
锚点(Anchors):定义UI相对于父对象的对齐
与拉伸
轴点(Pivot):定义UI元素本身的轴点,影响缩放
与旋转
Tilemap
Unity 中用于快速构建 2D 关卡的工具,用于平台跳跃游戏、俯视角游戏等需要大量重复元素的场景。
通过将小块的图像(称为 Tile)拼接在一起,形成一个完整的关卡。
组成部分
- Tile(瓦片):构成 Tilemap 的基本单元,通常是一个小图像(如 16x16 或 32x32 像素)
- 用于表示关卡中的地面、墙壁、平台、装饰物等。
- Tile 可以是静态的,也可以是动画的(如流动的水、闪烁的灯光)。
- Tilemap(瓦片地图):由多个 Tile 组成的网格,用于构建关卡
- 快速搭建复杂的 2D 场景,支持分层(如背景层、地面层、前景层)
- Tilemap 支持碰撞、动画和自定义规则
进阶使用
(Sorting Layer && Order in Layer)Tilemap分层:将关卡分为多个层次,如背景层、地面层、装饰层
- 使用不同的tilemap,即不同的tilemap文件作为不同类型砖块的抽象,即可抽象出各种想要的平面材质
(Tilemap Collider 2D)物理碰撞:为 Tilemap 添加碰撞,使角色可以与地面、墙壁等交互
(Animated Tile) 动画:创建动态的 Tile,如流动的水、闪烁的灯光
(Rule Tile)自定义规则:根据相邻 Tile 自动调整 Tile 的外观,如草地、墙壁的衔接。
常见问题
Tile 显示不正确
- 原因:Tile 的
Pixels Per Unit
设置不正确。 - 解决:将 Tile 的
Pixels Per Unit
设置为与图像分辨率一致(如 16x16 像素设置为 16)。
- 原因:Tile 的
Tilemap 碰撞不生效
- 原因:未添加
Tilemap Collider 2D
或Composite Collider 2D
。 - 解决:确保为 Tilemap 添加了正确的碰撞器组件。
- 原因:未添加
Tilemap 渲染顺序错误
- 原因:Sorting Layer 或 Order in Layer 设置不正确。
- 解决:调整 Tilemap 的 Sorting Layer 和 Order in Layer,确保渲染顺序正确。
RigidBody & Collider
RigidBody负责物理模拟,Collider负责碰撞检测
RigidBody
为物体添加了质量、速度、重力、摩擦力等现实物理属性。只有开启了RigidBody的物体才可发生碰撞。
- Mass:质量
- Drag:空气阻力
- AngularDrag:旋转阻力
- Use Gravity:是否开启重力
- Is Kinematic:是否为运动学物体
RigidBody2D
unity中设置2D物理的组件。模拟物理行为,如重力、速度、碰撞。
常规的角色操作都需要通过RidigBody2D来进行,比如移动、跳跃
// 水平移动
float moveInput = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y); // 修改水平速度,保持垂直速度不变。
rb.velocity = new Vector2(rb.velocity.x, 10f):修改垂直速度,实现跳跃。
Collider
Collider是 Unity 中用于检测碰撞的组件。Collider本身不影响物体的运动。
碰撞检测流程:是否接触=>至少有一个物体拥有RigidBody=>运动计算
当Collider的Trigger属性启用时,会触发检测,但不会与拥有RigidBody的物体进行碰撞检测
- Box Collider 盒体
- Sphere Collider 球体
- Capsule Collider 胶囊
- Mesh Collider 网格
- Tilemap Collider 瓦片地图
Physics2D.OverlapCircle:检测指定位置和半径范围内是否存在碰撞体
LayerMask:指定碰撞检测的图层,避免检测到不需要的物体
public Transform groundCheck; // 地面检测点
private bool isGrounded; // 是否在地面上
public float groundCheckRadius = 0.2f; // 地面检测范围
public LayerMask groundLayer; // 地面图层
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
Input
Input.GetAxis
- 用于获取水平方向的输入(如键盘的 A/D 或方向键)。
- 返回值:-1 到 1 之间的浮点数,表示输入的强度和方向。
float moveInput = Input.GetAxis("Horizontal") 获取水平输入。
Input.GetKeyDown
检测按键按下,与Input.GetKey不同的是,Input.GetKeyDown是按下后检测,而Input.GetKey是按住就检测
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape)) OnPanelChange();
}
Input.GetButtonDown
用于检测跳跃键(如空格键)是否被按下。
- 返回值:布尔值,按下时为
true
,否则为false
。
if (isGrounded && Input.GetButtonDown("Jump");
Render
将 3D 或 2D 场景中的对象绘制到屏幕上的过程
涉及到渲染管线与渲染属性
常用属性
- Material(材质,定义物体表面的外观)
- Albedo:基础颜色或纹理。
- Normal Map:法线贴图,用于模拟表面细节。
- Metallic/Smoothness:金属感和光滑度。
- Emission:自发光效果。
- Shader(着色器,控制材质的渲染方式)
- Standard Shader:内置渲染管线的默认 Shader。
- Unlit Shader:不受光照影响的 Shader,适合 UI 或特效。
- URP Lit Shader:URP 中的标准 Shader。
- Lighting(光照,定义场景中的光源和阴影)
- Directional Light:平行光,模拟太阳光。
- Point Light:点光源,模拟灯泡。
- Spot Light:聚光灯,模拟手电筒。
- Shadow:阴影类型(如 Hard Shadow、Soft Shadow)。
- Post-Processing(后期处理,渲染完成后对画面进行进一步处理)
- Bloom:泛光效果。
- Color Grading:颜色校正。
- Depth of Field:景深效果。
- Vignette:暗角效果。
Renderer
SpriteRenderer:用于渲染 2D 图像的组件
private SpriteRenderer spriteRenderer;
float moveInput = Input.GetAxis("Horizontal");
spriteRenderer = GetComponent<SpriteRenderer>();
// 翻转角色朝向
if (moveInput > 0)
spriteRenderer.flipX = false;
else if (moveInput < 0)
spriteRenderer.flipX = true;
Camera
常用属性
- Field of View (FOV):视野范围,控制摄像机的视角宽度
- Clipping Planes:裁剪平面,定义摄像机渲染的最近和最远距离
- Culling Mask:剔除遮罩,选择渲染哪些图层(Layer)
- Clear Flags:清除标志,定义如何清除屏幕(如 Solid Color、Skybox)
- Background:背景颜色或天空盒
基础实现
基本逻辑:每帧修改摄像机的位置,与角色位置同步
基础版本
public class CameraController : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.125f;
public Vector3 offset;
void LateUpdate()
{
if (target == null) return;
transform.position = Vector3.Lerp(transform.position, target.position + offset, smoothSpeed);
}
}
进阶:增加视角限制
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.125f;
public Vector3 offset;
public Vector2 restrictMin;
public Vector2 restrictMax;
void LateUpdate()
{
if (target == null) return;
Vector3 desiredPosition = target.position + offset;
desiredPosition.x = Mathf.Clamp(desiredPosition.x, restrictMin.x, restrictMax.x);
desiredPosition.y = Mathf.Clamp(desiredPosition.y, restrictMin.y, restrictMax.y);
transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
}
}
进阶:添加动态偏移 ( y轴动态,适用于角色跳跃 )
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.125f;
public Vector3 offset;
public float yOffsetMultipiler = 1.5f;
public Vector2 restrictMin;
public Vector2 restrictMax;
void LateUpdate()
{
if (target == null) return;
Vector3 dynamicOffset = offset;
dynamicOffset.y = offset.y + (target.position.y * yOffsetMultipiler);
Vector3 desiredPosition = target.position + offset;
desiredPosition.x = Mathf.Clamp(desiredPosition.x, restrictMin.x, restrictMax.x);
desiredPosition.y = Mathf.Clamp(desiredPosition.y, restrictMin.y, restrictMax.y);
transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
}
}
CinemachineCamera
基础使用:绑定Follow属性为要跟随的角色
DataStructure
Sprite:2D图像资源
GameObject:基类
Transform:方向、旋转、缩放
Vector2 & Vector3:二维 & 三维坐标
Quaternion:旋转
Color:颜色
AutoClip:音频资源
Material:材质
Vector
转换
// Vector2 转 Vector3
Vector2 v2 = new Vector2(1, 2);
Vector3 v3 = new Vector3(v2.x, v2.y, 0); // (1, 2, 0)
// Vector3 转 Vector2
Vector3 v3 = new Vector3(1, 2, 3);
Vector2 v2 = new Vector2(v3.x, v3.y); // (1, 2)
Vector3
三维向量,包含x、y、z三个分量。适用于三维坐标体系下的计算:
- 基础的Transform计算 / 位置控制:位置、缩放、旋转
- 物理计算:速度、加速度、力
属性
Vector3.zero
:表示(0, 0, 0)
Vector3.one
:表示(1, 1, 1)
Vector3.up
:表示(0, 1, 0)
Vector3.down
:表示(0, -1, 0)
Vector3.left
:表示(-1, 0, 0)
Vector3.right
:表示(1, 0, 0)
Vector3.forward
:表示(0, 0, 1)
Vector3.back
:表示(0, 0, -1)
方法
Vector3.Magnitude
:返回向量的长度c#Vector3 v = new Vector3(3, 4, 0); float length = v.magnitude; // 5
Vector3.Normalize
:将向量归一化(长度为 1)c#Vector3 v = new Vector3(3, 4, 0); Vector3 normalized = v.normalized; // (0.6, 0.8, 0)
Vector3.Distance
:计算两个点之间的距离c#Vector3 a = new Vector3(1, 2, 3); Vector3 b = new Vector3(4, 5, 6); float distance = Vector3.Distance(a, b); // 5.196
Vector3.Lerp
:线性插值c#Vector3 start = Vector3.zero; Vector3 end = Vector3.one; Vector3 result = Vector3.Lerp(start, end, 0.5f); // (0.5, 0.5, 0.5)
Vector2
二维向量,包括x、y两个分量。适用于二维坐标体系下的计算:
- 平面计算:UI、Transform基础计算、二维物理计算
属性
Vector2.zero
:表示(0, 0)
Vector2.one
:表示(1, 1)
Vector2.up
:表示(0, 1)
Vector2.down
:表示(0, -1)
Vector2.left
:表示(-1, 0)
Vector2.right
:表示(1, 0)
方法
Vector2.Magnitude
:返回向量的长度c#Vector2 v = new Vector2(3, 4); float length = v.magnitude; // 5
Vector2.Normalize
:将向量归一化(长度为 1)c#Vector2 v = new Vector2(3, 4); Vector2 normalized = v.normalized; // (0.6, 0.8)
Vector2.Distance
:计算两个点之间的距离c#Vector2 a = new Vector2(1, 2); Vector2 b = new Vector2(4, 5); float distance = Vector2.Distance(a, b); // 4.242
Vector2.Lerp
:线性插值c#Vector2 start = Vector2.zero; Vector2 end = Vector2.one; Vector2 result = Vector2.Lerp(start, end, 0.5f); // (0.5, 0.5)
Animation
组成
- Animation Controller
- Animation Clip
一个Controller控制一组同源动画,内部通过State Machine进行切换与过渡
Animator菜单
- 连接:通过右键
Make Transition
来进行状态连接 - 动画状态:左侧的Parameters为参数列表,这里来进行state condition的创建
- 触发条件:右侧的inspector的transitions设置触发动画所需的条件
动画绑定
定义Animator => 获取Animator => 使用Animator => 监听输入,切换condition状态
public class Player : MonoBehaviour
{
public Animator animator;
void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
float moveInput = Input.GetAxis("Horizontal");
if (Mathf.Abs(moveInput) > 0.1f) // 如果有水平输入
{
animator.SetBool("isMoving", true); // 切换到 Move 动画
}
else
{
animator.SetBool("isMoving", false); // 切换到 Idle 动画
}
}
}
UI
Hierarchy逻辑:
Canvas:
基础设置:RenderMode——ScreenSpace-Overlay;UIScaleMode——ScaleWithScreenSize
- Image...
- Text...
- Toggle
- Slider
EventSystem
Script逻辑:
挂载到Canvas上
using UnityEngine;
using UnityEngine.UI;
public class SettingManager : MonoBehaviour
{
public Slider slider;
public Toggle toggle;
void Start()
{
slider.onValueChanged.AddListener(OnVolumnChange);
toggle.onValueChanged.AddListener(OnToggleChange);
}
public void OnVolumnChange(float value)
{
slider.SetValueWithoutNotify(value);
}
public void OnToggleChange(bool isMuted)
{
AudioListener.volume = isMuted ? 0 : slider.value;
}
}
Prefab
资源类型,用于存储和复用游戏对象的配置与组件。
对象复用:将一个配置好的游戏对象保存为资源,然后在场景中多次实例化。
统一管理:通过修改 Prefab,可以同时更新所有实例化的对象
常用函数
Mathf.Clamp(target, restrictMin, restrictMax):限制位置,常用于限制角色、摄像机的位置范围