非程序员用AI视频生成加Python脚本制作2D游戏Sprite的实践
プログラマーじゃない私が2Dアクションのアニメで3回挫折して、「AI動画→Pythonでスプライト化」に落ち着くまで
作者实测三种AI动画方案后,给出基于视频生成服务加Python脚本处理Sprite的完整工作流与代码细节。
我无法编写游戏程序。我通过用日语向AI发出指令,在Unity 6中制作游戏。
我开始制作一款新的2D动作游戏。因为我之前为3D游戏准备的精灵弓箭手角色很合心意,所以我决定采取将这个角色也应用于2D的方针进行构思。
问题在于如何制作2D动画。我尝试了三种方法,但都失败了。本文将介绍为什么这些方法行不通,以及我现在采用的稳定做法。
尝试过的方法
- 使用PixelOver将3D模型转换为像素艺术风格并加以使用
- 从插画出发,利用See-through(OSS / ComfyUI)等AI工具进行图层分解,再转化为动作
- 准备了多张插图,并用 Wan 2.x(ComfyUI)将其连接成动画
→ 但所有方案都行不通(以失败告终)。
①使用 PixelOver 将 3D 模型转换为像素艺术
我设想的 2D 动作游戏重视爽快感,因此动作本身需要在一定程度上进行夸张变形。
PixelOver 会对 3D 模型的动画剪辑施加骨骼并驱动其运动。也就是说,如果 3D 模型侧没有准备好一定数量的动作剪辑,就无法成立。如果前提是 2D 的夸张变形,那么就需要从动画剪辑开始重新制作。(当然可能有其他方法,但我没有深入调查)
我认为,如果前提是将 3D 模型偏写实的动作直接像素化,那么使用 PixelOver 是合适的。但这与我设想的遊戲方向不符。
※PixelOver 并非使用这位精灵弓箭手,而是使用了其他角色进行测试。将骨骼应用于3D模型的行走动画片段后进行了像素化处理。
②使用AI进行分层解析(如See-through)
基于AI的分层解析精度大约在70到80分左右。其结果无法直接用于游戏开发,需要人工进行一定程度的修正。
我原本对图形类工具不太熟悉,因此需要从使用方法、上色技巧等基础开始学习,导致效率极低。
我认为对于有一定图形类工具使用经验的人来说,这是一个可行的选择。
※这是使用See-through分解出的图层(包括刘海、脸部、耳朵、上衣、颈部、手部、下装、腿部、后发等),并在浏览器图像编辑工具中打开的状态。这是经过手动修正后的结果。
③在Wan 2.x(ComfyUI)中连接插画
我的电脑(RTX 3060 Ti 8GB)的GPU规格无法运行Wan 2.x的优秀模型。轻量级模型的精度非常差。
能够承受其规格的显卡价格超过10万日元,因此我决定尝试其他方法。
比較
| 操作方法 | 适合的人群/场景 | 我失败的原因 |
|---|---|---|
| ① PixelOver(3D→像素艺术) | 希望将接近真实的3D动作直接转换为像素化效果的人。在3D侧已备齐动作剪辑的人 | 希望进行夸张变形的动作,因此需要从头重新制作剪辑 |
| ② See-through 等图层分解 | 有图形类工具使用经验的人 | 精度为70~80分,需要进行修改。从工具使用方法开始,效率不佳 |
| ③ Wan 2.x(ComfyUI、本地部署) | 拥有充裕显存的GPU的用户 | 8GB显存无法运行优质模型,轻量模型精度较差 |
| ③´ 视频生成服务 + Python | 希望无需GPU和绘画技能即可入门的人 | 当前的采用方案 |
沉稳的做法:③´ 使用视频生成服务 + Python 制作精灵图
准备多张插画,使用 kling.ai 等视频生成服务制作短视频。然后用 Python 将其转换为精灵图,剔除多余的帧,制成游戏用的精灵图。
前提:尽量减少逐帧绘制,华丽感依靠代码和特效来实现
企划书中一开始就这样写道。
在个人开发中,为了避开“2D 动画制作的泥沼”,彻底贯彻“角色本体的逐帧动画最小化,通过程序控制(Tween、VFX、外挂装备)使其看起来更丰富”的方针。”
角色的动画只要“看起来在动就足够了”,而箭矢或斩击的光效、命中停顿等打击反馈则由 Unity 端补充实现。
整体流程
- 使用 ChatGPT / Gemini 制作角色的静态图像(单色背景、全身、包含脚部)
- 通过视频生成服务制作短视频(待机、奔跑、射箭、倒地、踢击等动作)
- 使用 Python 进行透明化处理,并导出精灵表与 JSON 文件
- 使用 Python 统一每个片段中偏移的颜色和尺寸
- 在 Unity 中读取 JSON 文件,自动进行分割
Python脚本和Unity端的集成都由AI完成。我还将操作指南(面向AI的技能文件)放在文件夹中,每次都会让AI阅读。
视频生成提示词的技巧
- 用英文编写。使用日语时容易遗漏主语(我认为这是日本人特有的问题)。
- 按照“概述 → 动作说明 → 规则(务必遵守的事项)”的顺序编写。
- 特别是,如果手脚或武器超出画面范围(帧外),则无法作为游戏精灵使用。这一点需要明确写入规则。
- 即便如此仍会出现帧外情况,因此需要反复重新制作。
示例(仅骨架):
Overview: A side view of <character> on a plain white background.
Action: <character> <does the action>, then returns to the starting pose.
Rules:
- Keep the whole body, hands, feet and weapon inside the frame at all times.
- Fixed camera. No zoom, no camera movement.
- Side view only.
文件夹结构
<キャラ>/
mp4s/Idle.mp4, Run.mp4, ArrowShot1.mp4 ... ← 生成した動画を手で置く
sprite/<Action>/
<Action>.png スプライトシート(Unityに取り込むのはこれ)
<Action>.json コマサイズ・列数・pivot・推奨fps・使用フレーム
<Action>_preview.gif 市松背景の確認用アニメ
Python/
2stripe.py 動画 → 透過スプライトシート
unify.py クリップ間の色・大きさをそろえる
透明与帧抽取(2stripe.py)
背景是通过结合面向动画的背景移除模型(rembg 的 isnet-anime)和基于背景色的抠图来消除的。由于使用全帧通用的矩形进行裁剪,因此每一帧的底部不会出现模糊。
并非全部使用原始视频帧,而是通过 --fps 进行抽取。
| 種類 | 例 | 設定 |
|---|---|---|
| 等待循环 | 空闲 | --loop --fps 8 |
| 移动循环 | 奔跑、行走 | --loop --fps 12 --loop-min 0.4 --loop-max 1.5 |
| 单次动作 | 射箭、跳跃 | --start <秒> --end <秒> --fps 12 |
python -X utf8 Python/2stripe.py "<キャラ>/mp4s/Idle.mp4" -o "<キャラ>/sprite" --loop --fps 8 --save-frames
-
--loop会自动寻找连接良好的起点和终点 - 使用
--drop移除抖动或崩坏的画面帧 - 如果抽帧后出现了类似“放箭瞬间”的定格画面,此时通过
--use直接指定要使用的画面帧 - 对于拉弓后静止数秒的视频,我们没有将其合并为一帧,而是拆分为“拉弓”和“放箭”两部分。如果在 Unity 端保留拉弓的最后画面帧,也可以用于蓄力射击
※左侧为视频生成服务生成的原始视频的一帧,右侧为使用Python去除背景后的一帧。
※右侧是将抽帧排列并输出的奔跑动作精灵表(共12帧)。
AI视频的特性及应对方法
AI生成的视频经常会做出你未曾要求的行为。出现的症状及应对方法如下:
| 症状 | 対処 |
|---|---|
| 镜头中途擅自推进,导致角色变大 |
--zoom-fix(在帧范围内平滑地恢复缩放比例)。以弓、躯干等长度不变的物体为参照,测量推进前后的尺寸来确定缩放比例。在倒下的视频中,第18帧到第34帧的缩放比例为0.74倍 |
| 推进幅度不一致 | --zoom-keys(以折线图指定每帧的缩放比例)。缩放比例通过图像特征点匹配(SIFT)进行测量 |
| 未经请求却做出口型动作 | 粘贴闭嘴表情的脚本(mouthfix.py) |
| 在地面上绘制阴影 | 消除阴影。由静态图像制作的剪辑没有阴影,因此需对所有剪辑消除阴影,并在Unity端添加统一的阴影 |
| 视频服务的水印标志 | 在--wm-rect指定的矩形内仅删除较亮的像素(重叠的鞋子等会保留) |
| 飞行的箭矢会出现在帧画面中 | 从没有箭矢的帧开始填充(erase_patch.py)。箭矢由Unity侧作为子弹发射 |
| 倒下时身体会从地面浮起 |
使用--ground将身体下端对齐到第一帧脚部位置 |
| 弦与腿之间的背景会被保留 | --key-inside |
| 拍摄中途背景色发生变化/存在色差或斑驳的绿色幕布 | --bg-per-frame --green-screen |
| 发梢出现白边、缺损,白色衣物被抠图遗漏 |
调整--erode与--key-low,--mode rembg
|
统一颜色与大小(unify.py)
视频是按每个片段分别生成的,所以即使是同一个角色,发色和角色大小也会有细微偏差。并排放在一起看会像另一个人,因此我用 Python 来进行对齐。
- 颜色:在 Lab 色彩空间中对基准片段(待机)的颜色进行 k-means 聚类,生成“颜色主色”,再将其他片段的颜色向其靠拢。阴影和渐变会保留。最初设为 12 色,但头发高光与皮肤混在了一起,所以改成了 16 色
- 大小:身高会随姿势变化,因此不能使用。以脸部和躯干的特征点(SIFT)与基准片段进行比对来得出倍率。比对分两阶段进行,先是 10 个 inlier,再是 6 个 inlier;已确认若降到 5 个点就会产生误估计
python -X utf8 Python/unify.py palette "<キャラ>" -k 16
在Unity中导入
读取 Python 导出的 JSON(帧尺寸、列数、pivot、推荐 fps、是否循环),Unity 编辑器扩展会按单元格尺寸自动切片,并将 pivot 设置在脚底位置。由于尺寸已在 Python 侧统一,Unity 侧不再调整缩放。
{ "frame_size": [W, H], "columns": N, "pivot": [x, y], "recommended_fps": 8, "loop": true }
(项目示例。数值已隐藏)
再生は自作のコマ送りコンポーネントで行っています。
【動画・GIF:ゲーム内で動いているところ】
まとめ
- 3D→ピクセルアート(PixelOver)は、リアル寄りの動きをそのまま使うなら向いている。デフォルメしたい私には合わなかった
- AIのレイヤー分解は70〜80点。グラフィック系ツールに慣れた人なら選択肢になる
- ローカルのWan 2.xは、8GBのGPUでは良いモデルが動かなかった
- 最终决定采用在视频生成服务中制作短视频,再用Python进行透明化处理、抽帧以及统一颜色和尺寸,并自动导入Unity的方式。
- 角色动画尽量精简,华丽效果通过代码和特效来实现。
链接
- 开发中的3D游戏《勇者团队的苦劳人》(itch.io): https://subaru33jp.itch.io/the-hero-partys-babysitter
- 前作の2Dゲーム「Princess Vanguard」(ブラウザで遊べます)
- itch.io: https://subaru33jp.itch.io/princess-vanguard
- ふりーむ(Free Game Mugen): https://freegame-mugen.jp/roleplaying/game_15623.html
- 演示视频: https://youtu.be/J8aooF3N8AA
- X(@PuddingAthlete)
来源:Qiita · Unity 开发社区 · qiita.com


