3D游戏实战开发 | 青训营笔记

124 阅读7分钟

3D游戏实战开发

  1. 3D 实体搭建

在游戏场景中搭建静态物体

  1. 相机,光照,天空盒

营造游戏场景中的氛围感

  1. 控制与碰撞

让实体在游戏场景中动起来

  1. 玩法逻辑与UI

为游戏注入玩法和规则的灵魂

3D 实体搭建

3D 实体

3D 游戏是由一个个具有形状的实体组成的。每个实体在空间中存在于特定的位置,有特定的姿态(旋转角度)

image.pngimage.png

3D 实体的位姿态(Transform)

  1. 位置 Position(x,y,z),是一个三维向量坐标
  2. 旋转 Rotation(x,y,z),是一个三维向量坐标
  3. 缩放 Scale(x,y,z),是一个三维向量坐标

在Unity中,绝大部分情况下,是先缩放,后旋转,最后平移image.pngimage.png

3D 实体的创建

  1. 通过加载3D模型创建,如 fbx、gltf、obj
  2. 通过组合参数化的基本几何体创建

image.png

3D 实体的绘制

  1. 材质
  2. 颜色
  3. 纹理

image.pngimage.png

敌机模型制作

image.png

预制体

  • 将游戏对象保存在工程中,在需要的时候创建出来,这就是预制体(prefab)
  • 预制体存储着一个游戏对象,包括游戏对象的所有组件以及其下的所有子游戏对象

image.pngimage.png

相机,光照,天空盒

相机

  1. Clear Flag
  2. 背景颜色
  3. Culling Mask
  4. 投影(透视、正交)

image.pngimage.png

透视投影(Perspective)与正交投影(Orthographic)image.png

光照

  1. 类型:点光源、平行光、聚光灯、面积光
  2. 颜色
  3. 强度
  4. 阴影类型

image.png

天空盒

  1. 相机的清除标志设为“天空盒”
  2. 窗口——渲染——照明设置
  3. 环境——天空盒材质

image.pngimage.pngimage.png

控制与碰撞

docs.unity3d.com/Manual/Exec…image.pngimage.png

为主角飞船添加控制逻辑

  1. 添加刚体组件
  • Add Compontent > Physics > Rigidb
  • Use Gravity 设置为 false,忽略重力的影响
  • isKinematic 设置为 true,飞船通过脚本而非力影响运动属性
  • 设置 Constraints,冻结Z轴位移以及X、Y、Z轴旋转
  1. 添加自定义脚本
  • Add Component > New Scricp

MonoBehaviour 是一个基类,所有 Unity 脚本都派生自该类image.png

  • Start()

在首次调用任何 Update 方法之前在帧上调用 Start

  • Update()

每帧调用 Update

  • FixedUpdate()

用于物理计算且独立于帧率。具有物理系统的频率;每个固定帧率调用该函数

  • LateUpdate()

LateUpdate 在每一次调用 Update 函数后调用

  • OnGUI()

系统调用 OnGUI 来渲染和处理 GUI 事件。OnGUI 实现可以每帧调用多次(每个事件调用一次)

  • OnDisable()

该函数在对象被禁用时调用。对象销毁时也会调用该函数

  • OnEnable()

该函数在对象变为启用和激活状态时调用

docs.unity3d.com/cn/2020.2/S…

image.png

Input.GetAxis()和输入管理器(InputManager)

  • InputManager 是 Unity 设置输入响应方式的管理列表,它的设置在 Edit > Project Setting > Input 中

image.png

添加敌机:

  • 为每架敌机预制体添加一个刚体

    • 选中敌机预制体,在菜单栏执行 Component > Physics > Rigidbody
    • 在新添加的刚体组件中,将 Use Gravity 设置为 false
    • 将 isKinematic 设置为 true
    • 打开 Constraints 旁边的三角形展开按钮,冻结Z轴的坐标和XYZ轴的旋转
  • 建立敌机的脚本 Enemey.cs

  • 为每架敌机预制体均添加脚本 Enemy.cs

image.png

随机生成敌机:

  • 新建一个名为 Main 的 C# 脚本,绑定到 Main Camera 上

image.pngimage.png

  • 敌机与玩家控制的飞船没有碰撞效果
  • 玩家控制的飞船会移出相机视野之外
  • 敌机会不断添加进场景中,导致场景中的实体越来越多

设置标签、图层和物理规则:

游戏中存在不同类型的游戏对象,它们需要放置在不同的图层中,并与其他游戏对象发生不同的交互。

  • 主角飞船(Hero):会与敌机、敌机炮弹、升级道具碰撞,但不会与主角飞船的炮弹相碰撞
  • 主角飞船的炮弹(ProjectileHero):与敌机、敌机的炮弹相碰撞
  • 敌机(Enemy):与主角飞船和主角飞船的炮弹相碰撞
  • 敌机的炮弹(ProjectileEnemy):只与主角飞船相碰撞
  • 升级道具(PowerUp):只与主角飞船相碰撞

标签和图层管理器:

  1. 菜单栏中执行 Edit > Project Settings > Tags and Layers 命令
  2. 打开 Tags 左侧的三角形展开按钮,单击标签下方的+符号并输入标签名称
  3. 单击 Layers 旁边的三角形展开按钮从 User Layer8 开始,依次输入图层名称

image.png

物理管理器:

  • 菜单栏中执行 Edit > Project Settings > Physics 命令

image.png

为游戏对象指定合适的图层:

  1. 在层级面板中选中_Hero,然后在检视面板中从 Layer 下拉菜单中选择“Hero”选项,Unity 会询问是否将_Hero的子对象也指定到该图层上,选择“Yes,change children”选项
  2. 在检视面板中,在 Tag 下拉菜单中选择Hero选项,为_Hero设置标签,不需要修改_Hero子对象的标签
  3. 从项目面板中选择这5个敌机预设,设置图层为 Enemy,如果出现提示,同样选择“Yes,change children”选项
  4. 设置每个敌机预设的标签为Enemy,不需要修改它们的子对象的标签

敌机碰撞主角飞船:

  • 为主角飞船和敌机添加碰撞体。球体碰撞检测的效率较高。我们将主角飞船与敌机飞船及其子组件上已有的碰撞盒去掉,每个对象的母体上 Add Component > Sphere Collider

image.png

添加碰撞代码:

  • 在 Hero 类中添加 OnTriggerEnter函数

void OnTriggerEnter(Collider other) {

// 可以用下面这行代码在Console窗口输出碰撞对象的名称

// print("触发碰撞事件:"+other.gameObject.name)

if (other.tag == "Enemy") {

    Destroy(this.gameObject);
    
}
复制代码

}

玩法逻辑与 UI

主角飞船增加射击功能:

  • 新建一个新的预制体,命名为 PrijectileHero。模型为一个立方体,Position与Rotation均为[0,0,0],Scale为[0.25,1,0.5].保留默认的 Box Collider。Box Collider的Size.z设置为10

  • 创建一个名为 Mat_ProjectileHero 的新材质,将着色器指定为 ProtoTools > UnlitAlpha,并将新材质应用到 ProjectileHero上

  • 为 ProjectileHero 游戏对象添加一个新的刚体组件,设置如下:

    • Use Gravity 为 false
    • isKinematic 为 false
    • Collision Detection 为 Continuous
    • Constraints 冻结Z坐标与X、Y、Z旋转轴
  • Tag 和 Layer 均设置为 ProjectileHero

按下空格后实例化新炮弹:image.png

为子弹添加碰撞事件:image.png

屏幕右上角显示计分板:

  • 在菜单栏中执行 GameObject > UI > Text 命令

    • Canvas:匹配游戏面板尺寸的画布
    • EvenSystem:用于运转按钮、滚动条等交互元素
  • 选中Text对象,修改名称为Score

  • 设置Text对象的Anchors、Pivot、Pose、Width、Height、Text、Font Style、Font Size、Color等显示属性

image.pngimage.png

每次消灭敌机为玩家增加50分:image.png

重新开始游戏:

  • 主角飞船被消灭2秒后重新开始游戏:

image.png

知识点总结

  • 学习在Unity中创建实体,给实体设置位姿、材质、刚体、脚本。学会配置相机、光、天空盒。
  • 学习在Unity中创建实体,给实体设置位姿、材质、刚体、脚本。学会配置相机、光、天空盒。
  • 理解实时游戏update的时序机制。
  • 通过Input.GetAxis()与InputManager监听玩家输入。
  • 用Instantiate()动态生成游戏实体实例。
  • 从Camera.main获得相机参数,设置场景中的物体在画面中的位置。
  • 利用标签、图层管理器区分实体种类并设置物理规则。
  • 通过Collider组件与OnTrigger 函数添加碰撞事件。
  • 通过图形用户界面(GUI)管理游戏界面。

推荐课程

  • GAMES 101 - 现代计算机图形学入门-闫令琪(中级)
  • GAMES 104 - 现代游戏引擎入门必修课-王希(高级)
  • GAMES 2022 - 高质量实时渲染-闫令琪(技美专用)