Skip to content

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)。
  • Tilemap 碰撞不生效

    • 原因:未添加 Tilemap Collider 2DComposite 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来进行,比如移动、跳跃

c#
// 水平移动
        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:指定碰撞检测的图层,避免检测到不需要的物体

c#
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 之间的浮点数,表示输入的强度和方向。
c#
float moveInput = Input.GetAxis("Horizontal") 获取水平输入。

Input.GetKeyDown

检测按键按下,与Input.GetKey不同的是,Input.GetKeyDown是按下后检测,而Input.GetKey是按住就检测

c#
  void Update()
  {
    if (Input.GetKeyDown(KeyCode.Escape)) OnPanelChange();
  }

Input.GetButtonDown

用于检测跳跃键(如空格键)是否被按下。

  • 返回值:布尔值,按下时为 true,否则为 false
c#
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 图像的组件

c#
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:背景颜色或天空盒

基础实现

基本逻辑:每帧修改摄像机的位置,与角色位置同步

基础版本

c#
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);
  }
}

进阶:增加视角限制

c#
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轴动态,适用于角色跳跃 )

c#
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

转换

c#
// 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状态

c#
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上

c#
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):限制位置,常用于限制角色、摄像机的位置范围