mcpField
U
unity-2d

unity-2d

github.com/nice-wolf-studio开发4079 次安装6 周前更新
代码仓库

关于 unity-2d

unity-2d 是 Unity 2D 项目开发参考技能,面向 Unity 开发者。内容涵盖精灵、Tilemap、2D 物理、URP 照明、渲染顺序及相关脚本 API。

主要功能

  1. 012D 项目设置与所需程序包
  2. 02精灵编辑、渲染和图集
  3. 03Tilemap 创建与脚本操作
  4. 042D 物理组件和查询
  5. 05URP 2D 灯光与排序

适用场景

  1. 01设置 Unity 2D 项目
  2. 02创建并渲染精灵场景
  3. 03实现 2D 碰撞和移动
  4. 04配置 URP 2D 照明

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-2d

安装后在 Claude Code 中输入/unity-2d确认已加载。

附带文件references/sprites-and-atlas.mdreferences/tilemaps.md

详细介绍

Unity 2D 开发

2D 项目设置

Unity 支持创建专用的 2D 项目。启动 2D 项目时:

  • 创建新项目时,选择 2D 模板(或选择 2D (URP) 以支持 2D 光照)
  • 2D 模板会自动安装所需的软件包:2D Sprite、2D Tilemap Editor、2D Animation
  • 场景视图默认采用正交视图(自上而下的 XY 平面)
  • 相机默认设置为正交投影
  • 导入的图像默认使用 Sprite(2D and UI)纹理类型

文档中的核心 2D 子系统:

  • Sprites:“2D 图形对象”——2D 游戏的基础
  • Tilemaps:“一种 GameObject,可让你使用图块和网格叠加快速创建 2D 关卡”
  • 2D Physics:专用物理系统,包含针对 2D 优化的组件
  • 2D Rendering in URP:2D 光源、光照效果和像素化视觉风格

来源:https://docs.unity3d.com/6000.3/Documentation/Manual/Unity2D.html

Sprites 和 SpriteRenderer

Sprite 资源

Sprites 是“可在 Unity 项目中使用的一种 2D 资源”。它们是 2D 图形对象,并具备专门的导入和管理功能。必须安装 2D Sprite 软件包(2D 模板已包含此软件包)。

Sprite 的主要功能:

  • 从纹理导入 Sprites 或 spritesheet
  • 使用 Sprite Editor 从纹理中切割 Sprites(切片)
  • 应用裁剪以移除透明区域
  • 为 Sprite 物理创建碰撞几何体
  • 使用 9-slicing,以不同尺寸重复利用 Sprites
  • 使用 Masking 隐藏或显示 Sprite 或 Sprite 组的部分区域

来源:https://docs.unity3d.com/6000.3/Documentation/Manual/sprite/sprite-landing.html

SpriteRenderer 组件

SpriteRenderer 组件控制 Sprites 在场景中的显示方式。主要属性:

属性说明
sprite要渲染的 Sprite 资源
color应用于 Sprite 的色调颜色(默认值:白色 = 无色调)
flipX / flipY沿轴翻转 Sprite,而不移动 Transform
drawModeSimple、Sliced 或 Tiled
size使用 Sliced 或 Tiled 绘制模式时的尺寸
sortingLayerName渲染器的排序图层名称
sortingOrder在排序图层中的优先级(数值越低越先渲染)
maskInteractionNone、Visible Inside Mask 或 Visible Outside Mask
spriteSortPointCenter 或 Pivot——决定与相机的排序距离

绘制模式:

  • Simple(默认):对整个 Sprite 进行等比缩放
  • Sliced:用于 9-sliced Sprites;根据 9-slice 区域使用 Width/Height 进行缩放
  • Tiled:用于 9-sliced Sprites;平铺中间部分。Tile Mode 选项:Continuous(均匀平铺)或 Adaptive(拉伸至阈值后再平铺)

默认材质:Sprite-Lit-Default(可通过 Material 选择器自定义)

// SpriteRenderer basic usage
SpriteRenderer sr = GetComponent<SpriteRenderer>();
sr.sprite = newSprite;
sr.color = Color.red;
sr.flipX = true;
sr.flipY = true;
sr.sortingLayerName = "Foreground";
sr.sortingOrder = 5;

有关绘制模式示例、Sprite 遮罩和更改回调,请参阅 references/sprites-and-atlas.md。

来源:https://docs.unity3d.com/6000.3/Documentation/ScriptReference/SpriteRenderer.html

Sprite Atlas

Sprite Atlas 是“一种将多个 Sprite 纹理紧密打包到单个纹理(称为图集)中的工具”。这可以减少绘制调用——Unity 对整个图集使用一次绘制调用,而不是为每个 Sprite 单独调用。

创建:Assets > Create > 2D > Sprite Atlas(生成 .spriteatlas 文件)

Sprite Atlas 属性
属性描述
类型Master(默认)或 Variant
包含在构建中包含在当前构建中(默认:启用)
允许旋转打包时旋转精灵以最大限度提高密度(默认:启用)。对于 Canvas UI,请禁用
紧密打包使用精灵轮廓而不是矩形进行打包,以提高打包密度(默认:启用)
边距精灵之间的缓冲空间(默认:4 像素)
启用读写允许脚本访问纹理数据(内存占用翻倍)
生成 Mip Map为图集启用 mipmap
过滤模式控制纹理过滤,并覆盖各个精灵的设置
打包对象要打包到图集中的精灵/文件夹列表

运行时 API:「你可以使用 Sprite Atlas API 在项目运行时控制 Sprite Atlas 的加载。」

// Load a sprite from a SpriteAtlas at runtime
using UnityEngine;
using UnityEngine.U2D;

public class AtlasLoader : MonoBehaviour
{
    [SerializeField] private SpriteAtlas atlas;
    private SpriteRenderer spriteRenderer;

    void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
        Sprite sprite = atlas.GetSprite("player_idle");
        spriteRenderer.sprite = sprite;
    }
}

延迟绑定:订阅 SpriteAtlasManager.atlasRequested,以按需加载图集(适用于 Addressables/AssetBundle 工作流)。完整的延迟绑定示例请参阅 references/sprites-and-atlas.md。

来源:https://docs.unity3d.com/6000.3/Documentation/Manual/sprite/atlas/atlas-landing.html

Tilemap 系统

Tilemap 可使用瓦片和网格叠加层快速创建 2D 关卡。Tilemap 组件「存储和管理 Tile 资源」,并「将放置在其上的瓦片所需的信息传递给其他相关组件,例如 Tilemap Renderer 和 Tilemap Collider 2D」。

Tilemap 组件属性
属性描述
动画帧速率瓦片动画的播放速度倍率
颜色应用于所有瓦片的色调(默认:白色)
瓦片锚点瓦片锚点位置的偏移量(以网格单元为单位)
方向XY、XZ、YX、YZ、ZX、ZY 或 Custom
TilemapRenderer 模式
模式描述
Chunk按位置/纹理对瓦片分组以进行批处理。渲染性能最佳
Individual单独渲染每个瓦片。支持与其他渲染器交互和自定义排序
SRP Batch兼容 URP 15+。通过顺序批处理对瓦片进行分组

其他 TilemapRenderer 属性:

  • 排序顺序:渲染期间瓦片的排序方向
  • 检测 Chunk 剔除边界:自动或手动(防止精灵被裁剪)
  • 材质:用于渲染精灵纹理的材质
  • 遮罩交互:无、在遮罩内可见或在遮罩外可见
  • 排序图层 / 图层顺序:控制渲染优先级
Tilemap 脚本 API
using UnityEngine;
using UnityEngine.Tilemaps;

Tilemap tilemap = GetComponent<Tilemap>();

// Single tile operations
tilemap.SetTile(new Vector3Int(x, y, 0), tile);      // Place tile
tilemap.SetTile(new Vector3Int(x, y, 0), null);       // Remove tile
TileBase t = tilemap.GetTile(new Vector3Int(x, y, 0)); // Read tile

// Batch operations (faster than individual SetTile in loops)
tilemap.SetTiles(positionsArray, tilesArray);
tilemap.BoxFill(pos, tile, startX, endX, startY, endY);
tilemap.FloodFill(pos, tile);
tilemap.SwapTile(oldTile, newTile);

// Coordinate conversion
Vector3 worldPos = tilemap.CellToWorld(cellPos);
Vector3Int cellPos = tilemap.WorldToCell(worldPosition);

// Bounds management -- ALWAYS call after procedural generation
tilemap.CompressBounds();
BoundsInt bounds = tilemap.cellBounds;

// Clear
tilemap.ClearAllTiles();
tilemap.RefreshAllTiles();

关键属性:cellBounds、localBounds、size、origin、animationFrameRate 关键事件:tilemapTileChanged、tilemapPositionsChanged、loopEndedForTileAnimation

程序化生成示例、Rule Tiles 和 TilemapCollider2D 设置请参阅 references/tilemaps.md。

来源:https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Tilemaps.Tilemap.html

2D 物理概述

Unity 的 2D 物理系统提供了针对 2D 交互优化的组件。「Unity 的物理系统让你能够处理 2D 物理,从而利用 2D 提供的优化。」

核心组件
组件描述
Rigidbody2D「允许 GameObject 受模拟重力和其他力影响的组件」
Collider2D「用于处理对象物理碰撞的不可见形状」
Physics Material 2D控制发生碰撞的 2D 物理对象之间的摩擦和弹性
Constant Force 2D为带有 Rigidbody 的 GameObject 添加恒定力或扭矩
Effectors 2D控制 GameObject 碰撞体接触时的作用力
2D JointsRigidbody 组件之间的动态连接,可实现受约束的移动
Rigidbody2D 关键属性
属性描述
bodyTypeDynamic、Kinematic 或 Static
linearVelocity位置变化速率(世界单位/秒)
angularVelocity旋转速度(度/秒)
massRigidbody 的重量
gravityScale重力影响程度
linearDamping线性速度阻力
angularDamping角速度阻力
constraints冻结各轴上的位置/旋转
collisionDetectionModeDiscrete 或 Continuous
interpolationNone、Interpolate 或 Extrapolate
Rigidbody2D 关键方法
Rigidbody2D rb = GetComponent<Rigidbody2D>();

// Apply forces
rb.AddForce(Vector2.up * 10f);
rb.AddForce(Vector2.right * 5f, ForceMode2D.Impulse);
rb.AddForceAtPosition(force, position);
rb.AddTorque(15f);

// Move (use in FixedUpdate for physics-safe movement)
rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
rb.MoveRotation(rb.rotation + rotationSpeed * Time.fixedDeltaTime);

// Query
rb.Cast(direction, results, distance);
rb.ClosestPoint(worldPoint);
rb.Distance(otherCollider);
rb.GetContacts(contacts);
rb.IsAwake();
rb.IsSleeping();
Physics2D 静态方法(查询)
// Raycast
RaycastHit2D hit = Physics2D.Raycast(origin, direction, distance, layerMask);
RaycastHit2D[] hits = Physics2D.RaycastAll(origin, direction);

// Shape casts
RaycastHit2D boxHit = Physics2D.BoxCast(origin, size, angle, direction, distance);
RaycastHit2D circleHit = Physics2D.CircleCast(origin, radius, direction, distance);

// Overlap detection
Collider2D col = Physics2D.OverlapCircle(point, radius, layerMask);
Collider2D[] cols = Physics2D.OverlapCircleAll(point, radius);
Collider2D boxCol = Physics2D.OverlapBox(point, size, angle, layerMask);
Collider2D pointCol = Physics2D.OverlapPoint(point, layerMask);

// Utilities
float dist = Physics2D.Distance(colliderA, colliderB).distance;
bool touching = Physics2D.IsTouching(colliderA, colliderB);
// 2D platformer: ground check + jump + horizontal movement
Rigidbody2D rb = GetComponent<Rigidbody2D>();

// In Update: ground check and jump
bool isGrounded = Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
// Note: Uses legacy Input Manager for simplicity. See unity-input for the new Input System.
if (Input.GetButtonDown("Jump") && isGrounded)
    rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);

// In FixedUpdate: horizontal movement (preserves vertical velocity)
float move = Input.GetAxisRaw("Horizontal");
rb.linearVelocity = new Vector2(move * moveSpeed, rb.linearVelocity.y);

来源:https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Rigidbody2D.html 来源:https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Physics2D.html

2D 光照(URP)

2D 光照需要 Universal Render Pipeline(URP) 和 2D Renderer。使用 2D(URP)模板,或手动配置 URP。

Light 2D 类型
类型描述
Global照亮目标排序层上的所有对象。不能使用法线贴图
Freeform由可编辑顶点定义的自定义形状光源
Sprite使用精灵纹理定义光源形状
Spot具有方向和角度的锥形光源
Point从一个点向所有方向发光
Light 2D 属性
属性描述
Color光源颜色
Intensity亮度乘数(可超过 1,以使精灵过亮)
Light Order渲染队列中的位置(数值越小越先渲染)
Overlap OperationAdditive(相加像素值)或 Alpha Blend
Target Sorting Layers光源只照亮所选排序层上的精灵
Distance光源与表面之间的感知距离
Volume Opacity体积光照的可见度(0-1)
Shadow IntensityShadow Caster 2D 遮挡光线的程度(0-1)
Normal Maps非全局光源类型支持法线贴图
using UnityEngine;
using UnityEngine.Rendering.Universal;

public class DayNightCycle : MonoBehaviour
{
    [SerializeField] private Light2D globalLight;
    [SerializeField] private Color dayColor = Color.white;
    [SerializeField] private Color nightColor = new Color(0.1f, 0.1f, 0.3f);
    [SerializeField] private float cycleDuration = 60f;

    void Update()
    {
        float t = Mathf.PingPong(Time.time / cycleDuration, 1f);
        globalLight.color = Color.Lerp(dayColor, nightColor, t);
        globalLight.intensity = Mathf.Lerp(1f, 0.3f, t);
    }
}

来源:https://docs.unity3d.com/6000.3/Documentation/Manual/urp/2d-light-properties-explained.html

排序层和顺序

“Sorting Groups 可将带有 Sprite Renderer 的 GameObject 编组,并控制其精灵的渲染顺序。”Unity 会将同一 Sorting Group 中的所有 Sprite Renderer 视为一个统一的渲染单元。

排序层系统

排序层定义总体渲染顺序。在每个层内,Order in Layer(整数)用于设置具体优先级。数值越小越先渲染(显示在数值较大的对象后面)。

Sorting Group 组件

Sorting Group 组件会将子渲染器组织为一个可统一排序的单元。适用场景:

  • 复杂的多精灵角色(身体部位使用独立精灵)
  • 需要与环境中的对象一起排序的相关对象组

属性:

  • Sorting Layer:将该组分配到一个排序层
  • Order in Layer:在排序层内的优先级

支持嵌套 Sorting Group:内部组先在组内排序,然后外部组作为一个单元与其他渲染器进行排序。

// Y-sort for top-down games (attach to entities)
void LateUpdate()
{
    int order = Mathf.RoundToInt(-transform.position.y * 100);
    GetComponent<SpriteRenderer>().sortingOrder = order;
}

// Set sorting layer and order via script
SpriteRenderer sr = GetComponent<SpriteRenderer>();
sr.sortingLayerName = "Characters";
sr.sortingOrder = 10;
sr.sortingLayerID = SortingLayer.NameToID("Characters"); // faster

来源:https://docs.unity3d.com/6000.3/Documentation/Manual/sprite/sorting-group/sorting-group-landing.html

常见模式(C#)

俯视角移动(Rigidbody2D,无重力)
public class TopDownMovement : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 5f;
    private Rigidbody2D rb;
    private Vector2 moveInput;

    void Awake() { rb = GetComponent<Rigidbody2D>(); rb.gravityScale = 0f; }
    void Update() // legacy Input; see unity-input
    {
        moveInput = new Vector2(Input.GetAxisRaw("Horizontal"),
            Input.GetAxisRaw("Vertical")).normalized;
    }
    void FixedUpdate()
    {
        rb.MovePosition(rb.position + moveInput * moveSpeed * Time.fixedDeltaTime);
    }
}
精灵方向翻转 / 摄像机跟随 / Tilemap 点击
// Flip sprite based on movement direction (legacy Input; see unity-input)
float h = Input.GetAxisRaw("Horizontal");
if (h != 0) spriteRenderer.flipX = h < 0;

// Simple 2D camera follow (attach to Camera, set offset.z = -10)
void LateUpdate()
{
    Vector3 desired = target.position + offset;
    transform.position = Vector3.Lerp(transform.position, desired, smoothSpeed * Time.deltaTime);
}

// Place tile at mouse click
Vector3 worldPos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3Int cellPos = tilemap.WorldToCell(worldPos);
tilemap.SetTile(cellPos, tileToPlace);

反模式

  1. 在 2D 游戏中使用 3D 物理:始终使用 Rigidbody2D 和 Collider2D,绝不要使用 Rigidbody/BoxCollider。2D 物理引擎是独立的,并针对 2D 进行了优化。

  2. 使用 Transform 移动 Rigidbody2D:绝不要使用 transform.position 移动物理对象。请在 FixedUpdate 中使用 Rigidbody2D.MovePosition(),或使用 AddForce()。直接操作 Transform 会绕过物理模拟并破坏碰撞检测。

  3. 运行时使用 Transform.localScale 缩放精灵:改用 Sliced/Tiled 绘制模式下的 SpriteRenderer.size。Transform 缩放会导致碰撞体出现问题,且性能较低。

  4. 忘记对程序化 Tilemap 调用 CompressBounds():以程序方式生成瓦片后,调用 tilemap.CompressBounds() 重新计算边界。否则,遍历 cellBounds 时会包含空白区域。

  5. 每个精灵都产生一次绘制调用(未使用图集):将相关精灵打包到 Sprite Atlas 中。如果不使用图集,每个不同的纹理都会触发一次单独的绘制调用。

  6. 不必要地为 Sprite Atlas 启用 Read/Write:这会使内存使用量翻倍。只有在需要通过 Texture2D.SetPixels 进行脚本访问时才启用。

  7. 对 UI 精灵启用 Allow Rotation:打包 Canvas UI 中使用的精灵时,请在 Sprite Atlas 设置中禁用 Allow Rotation,因为旋转会破坏 UI 布局。

  8. 未正确设置 TilemapRenderer 模式:静态 tilemap 使用 Chunk 模式(性能最佳)。只有当瓦片需要与其他渲染器交互或需要自定义排序时,才使用 Individual 模式。

  9. 到处使用连续碰撞检测:仅对快速移动的对象将 collisionDetectionMode 设为 Continuous。对于大多数 2D 对象,Discrete 的开销更低且已足够。

  10. 忽略 Sorting Layers:仅依赖 Order in Layer 会导致使用难以理解的魔法数字。定义有意义的 Sorting Layers(Background、Midground、Characters、Foreground、UI),并使用 Order in Layer 在各图层内微调顺序。

关键 API 速查

类关键成员
SpriteRenderer.sprite, .color, .flipX, .flipY, .drawMode, .size, .sortingLayerName, .sortingOrder
SpriteAtlas.GetSprite(name), .GetSprites(sprites[]), SpriteAtlasManager.atlasRequested
Tilemap.SetTile(), .GetTile(), .SetTiles(), .ClearAllTiles(), .BoxFill(), .FloodFill(), .SwapTile(), .WorldToCell(), .CellToWorld(), .CompressBounds(), .cellBounds
Rigidbody2D.linearVelocity, .angularVelocity, .AddForce(), .MovePosition(), .MoveRotation(), .Cast(), .bodyType, .gravityScale, .mass
Physics2D.Raycast(), .BoxCast(), .CircleCast(), .OverlapCircle(), .OverlapBox(), .OverlapPoint(), .IsTouching()
Light2D.color, .intensity, .lightType(需要 UnityEngine.Rendering.Universal)
SortingGroup.sortingLayerName, .sortingOrder

相关技能

  • unity-foundations —— GameObjects、Components、Transforms、Prefabs、ScriptableObjects
  • unity-physics —— 深入了解 3D/2D 物理、关节、射线检测、物理材质
  • unity-graphics —— 渲染管线、材质、着色器、后期处理
  • unity-lighting-vfx —— URP 光照设置、视觉效果、粒子系统

Additional Resources

评论

支持 Markdown