前言

玩了很多年游戏,心血来潮,想学游戏开发,打算做出符合自己XP的游戏,全部人物和玩法全是要在我的xp上,绝不妥协。
我之前写单片机裸机代码,略懂C语言,跑了很多项目吧,有一定的工程经验(单片机),这些经验应该对游戏开发有用吧(?),现在从零开始打算学习下游戏开发,做出自己想要的游戏。
写文章主要记录下自己在游戏开发的学习和实践吧,回头看看自己的心路例程反省下,也请大家看看有哪些不妥之处并指出。

一、主流游戏引擎选择

游戏开发的程序部分先从游戏引擎的选择开始:

1. Unity

Unity 是由 Unity Technologies 公司开发的跨平台 2D/3D 游戏引擎,2005 年首次发布。目前是全球移动游戏、独立游戏与 AR/VR 应用的主流开发工具,市占率极高。除游戏外,也用于建筑可视化、汽车、影视、教育等实时 3D 领域。

极致跨平台:一次开发,编译部署到 20+ 平台(iOS/Android/Windows/macOS/ 主机 / WebGL/VR/AR 等)。
轻量易用、迭代快:编辑器直观、拖放式开发,适合快速原型与小团队。
生态极丰富:Asset Store 海量插件、模型、材质、教程。
灵活渲染管线:支持 Built-in、URP(通用)、HDRP(高清)。
面向数据的技术栈 DOTS:高性能多线程架构,适合大规模场景。
授权模式:个人免费;企业按收入 /seats 收费。
脚本语言C#(唯一主流)

Unity公司的商业模式有些迷茫,在之前有过收费政策的改动,导致一些独立游戏开发者寒心,对公司不信任并放弃用Unity进行开发转向Godot,近来又传出国内业务分家的传闻,最近出了有团结Hub和原先的Unity Hub印证了这点,并且国内的Unity用户还无法正常从官方素材库购买下载美术资源,不知道未来政策变化如何?

2.Unreal Engine(虚幻,UE)

由 Epic Games 开发的顶级 3D 实时创作引擎,起源于 1998 年 FPS《Unreal》。以电影级画质、物理与渲染能力著称,广泛用于 3A 游戏、影视虚拟制作、建筑、数字人等。UE5 引入 Nanite(微多边形)与 Lumen(全局光照),实现影视级实时渲染。

顶级渲染画质:Lumen 全局光照、Nanite 几何细节、超高清材质 / 阴影 / 粒子。
双开发模式:C++ 底层 + 蓝图可视化编程。
完整工具链:关卡、动画、材质、物理、音效、Sequencer(影视剪辑)。
开源可深度定制:引擎完整源码开放,可修改内核。
收费模式:免费使用;产品年收入超 100 万美元后收取 5% 分成。
脚本语言:C++(核心 / 高性能)

黑猴的引擎,是大公司制作3A游戏的标配游戏引擎,一般需要大量美术素材,黑猴就各种全国各地扫描古代建筑之类的来实现游戏场景的搭建,背后的Epic公司比Unity安分点,也不知道后续什么政策?

3.Godot

Godot 是一款完全免费、开源(MIT 协议)、轻量级、跨平台 2D/3D 游戏引擎,以极简、高效、无束缚、独立开发者友好著称。
由阿根廷开发者 Juan Linietsky 和 Ariel Manzur 创造,2014 年开源,采用 MIT 许可证——永久免费、无版税、无分成、可商用、可修改源码。

完全开源免费:无版税、无功能限制、可任意修改分发。
轻量极速:安装包小、启动快、内存占用低。
节点化架构:场景由节点树组成,模块化、复用性强。
2D 能力极强:2D 渲染、物理、精灵、瓦片地图、动画系统原生优化。
跨平台:支持 Windows/macOS/Linux/Android/iOS/Web/ 主机(需社区适配)。
社区驱动:文档、插件、示例丰富,更新活跃。
脚本语言:GDScript(官方首选)、C#(.NET 版本)、C/C++(GDExtension)

2014年才创建的后发劣势导致相关资源都比较少,但是本着开源精神得到了独立游戏开发者的拥护

综合考虑选择了Unity,原因就是奔着成熟、省事、懒着折腾这点。

二、粗略C#例程阅读

C#比C还是存在好多差异,粗略看了下就很多地方不懂。

1.类 class → 对应 C 的 结构体

struct public class Snake : MonoBehaviour
对应 C 语言概念 struct Snake;

  1. MonoBehaviour:Unity 自带的功能基类,不用管,理解成带了系统功能的结构体。
  2. public /private → 控制变量能不能被外部访问
 public int score = 0;    // 外面能访问
private int a = 0;       // 只有内部能用

2.变量定义

private Vector2 _direction = Vector2.right;
  1. private:只能内部用 = C 的只在本文件可见
  2. Vector2:一个C 里的存 x/y 的结构体

3.List

List<Transform> _segments = new List<Transform>();
  1. Transform:Unity的类型,表示物体的位置position (x, y, z)、旋转rotation、缩放localScale
  2. List:动态数组,能无限加长的数组
  3. segments :表示蛇的一段,前面加的 “”是C#命名规范而加,私有成员变量前面 + 下划线 _不是函数里的临时变量,不是 public 公开变量
  4. = new List():创建一个空的动态数组, 是在告诉程序:我这个 List 数组里,只能装 Transform 类型的东西。这样可以防止内存溢出,比C语言
    List = 一个存“物体位置旋转缩放信息”的动态数组

4.System.Action

public System.Action<int> OnScoreChanged;

System.Action 就是 C# 里的【带一个 int 参数的函数指针】

  1. System:C# 的根命名空间(相当于 C 语言的头文件集合)
  2. Action:C# 自带的委托类型,代表一个没有返回值、可以带参数的函数
  3. 在这里的应用,当蛇吃掉食物时,调用这个函数指针,更新分数变化

在游戏中的使用流程
蛇自己不负责显示分数,它只负责 “通知别人分数变了”。这个 OnScoreChanged 就是通知用的信号。

5.void Update() / FixedUpdate() / Start()

这些是 Unity 自动调用的函数,像 C 的 main 一样:
Start() → 程序启动时执行一次 = C 的 main 开头
Update() → 每帧执行 = C 死循环 while(1) 里的逻辑,Update每帧执行,间隔不固定电脑卡、帧率低,Update 就变慢
FixedUpdate() → 固定间隔执行 = 定时器,FixedUpdate按固定时间跑,和帧率无关不管游戏卡不卡,永远严格按 Fixed Timestep 间隔执行,Unity 默认 FixedUpdate 每 0.02 秒执行一次

6.输入检测 Input.GetKeyDown

Input:Unity 引擎自带静态类。专门管:键盘、鼠标、触屏输入的工具类,Unity 内置写好的。
GetKeyDown:Unity Input 类里的静态方法。作用:按下瞬间那一帧触发一次
KeyCode:Unity 自带枚举类型。KeyCode.W是枚举里的常量成员

7.创建/销毁对象

创建对象:

Transform segment = Instantiate(segmentPrefab, ...);

销毁对象

Destroy(_segments[i].gameObject);

8. OnTriggerEnter2D碰撞检测

private void OnTriggerEnter2D(Collider2D other)

当 两个 2D 碰撞体碰到一起 时:
其中至少一个带 Rigidbody2D
其中至少一个勾选了 Is Trigger
满足条件 → Unity 自动调用 OnTriggerEnter2D

三、总结及展望

对C#还缺乏很多系统理解

1、后续了解下C#的命名规范;
2、Unity常见的类;


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐