Unity3D笔记

背景

工作中需要在网页上展示一些模型内容,需要能够旋转缩放等等.
由于需要比较丰富的模型拼接和组装效果.暂时放弃了three.js等库.
由于受到所谓轻量级的诓骗,使用了Unity3D.

介绍

Unity3D,或者通常称为Unity.也算是主流游戏引擎之一.
最常见的使用场景是play store上一些消磨时间用的物理式手游.
开发者需要的主要是拖拖拽拽,然后给物品挂载一些C#脚本来控制目标行为.

个人体会是,如果用来做物理式小游戏,unity可能更适合,其他场景并不推荐.

  1. 文档社区不完善
    1. 官方社区程序员少
    2. 能搜到的提问和自己想问的内容不对路
    3. “我们知道了,等我们有空再解决.”
    4. 官方狠推的UIElements库到现在还要一些类没有构造函数的文档,需要借助个人开发者的博客和自己的猜测
  2. UI界面bug多
    1. 项目打开时间长了有时候会出现两个窗口,一个是正常编辑窗口,另一个是白色无意义点又不能点的窗口
    2. 在不同分辨率屏幕移动编辑窗口时,里面的物品坐标会变化
    3. 官方的UI Builder的预览框,大小经常变化
    4. 自定义的layout经常在启动时报错,只好恢复默认layout
  3. 命名混乱
    1. API和面板内容有时不对应
      1. 空格变驼峰
      2. TMP命名混乱
      3. 分不清哪里是名字,哪里是类名
      4. Rotation不是Vector3类型
    2. 菜单内容的命名区分度不够,完全不能理解什么是什么
  4. 版本更替频繁
    1. 像安卓一样喜欢改API,但却不能像安卓一样对API有完整说明
    2. 新版本API库的文档里,已经没有了还能使用的旧API
    3. 默认引导页面的模板,随着版本剧烈变化,让人不爽
  5. 中文支持少,WebGL支持少
    1. 导出WebGL时资源打包是个谜,色彩,字体,文件,常常无法被包含
    2. 官方的内容导出WebGL中,输入框无法对IME响应,无法输入中文
    3. 许多类库比如sqlite,Json.NET在WebGL中会报错,无法使用
  6. 本身拖拖拽拽和代码结合就不是什么好想法
    1. 分不清物品的行为是代码控制的还是面板控制的
    2. 面板设置的内容无法复制粘贴到其他项目

开始一个新项目

在Unity Hub的项目标签下管理当前的项目,
点击新建并选择一个合适的,比如3D或2D项目.

界面简介

网上能搜到答案的多是英文页面,因此也使用英文语言环境.
界面的分区

Hierachy

以树状结构管理游戏中的各种对象.
在该窗口中点击右键可以插入新的物品
通常这里可以有

  • Main Camera
  • Directional Light
  • 其他Object
  • Canvas
    • Panel
      • Label
      • Button
  • EventSystem

此处的物品,同级的情况下,靠下的后渲染,因此会覆盖在已经渲染的物品上方.

Scene

游戏的物品摆放样式的预览框.
通过一些功能键可以拖动和设置大小等

  • 手 拖动布景而不动物品
  • 十字箭头 按照坐标来移动物品
  • 旋转箭头 旋转物品
  • 方框 一种是用于设置矩形的四个边,一种是相对于中心来设置

这些快捷功能绑定了qwer等快捷键

按住鼠标右键可以旋转视角

Game

启动游戏进行预览时的窗口

可以选择游戏的偏好分辨率,
注意此处可以呈现的效果不代表导出到webgl后也能呈现

  1. 中文字体支持(导出后可能不包含字体,无法显示)
  2. 高亮的色彩(导出后可能不包含材质,无法显示)
  3. 中文输入法支持(导出后就不再能使用了)
  4. 数据库(导出后可能不能再使用)

Project

类似文件夹目录,保存了该项目所需要的一些东西.
在这里点击右键可以新建许多东西,文件夹,脚本,材质等等等等.

通常的目录结构是

  • Scenes

  • Scripts

  • Plugin

  • Prefabs

  • Models

  • Materials

  • Audio

目前的一些问题是:

  • 官方似乎规定了一些文件夹的命名,比如存放外部库的文件夹必须是Plugin而不能是Plugins
  • 不知道为什么会产生一个meta文件,只有meta而没有对应的原文件还会报错
  • 文件在外部修改后需要重载文件到Unity中(可能是为了更新meta文件?),需要设置是手动还是自动
  • 官方提供了有限的重命名/文件移动支持
    • 重命名cs文件可以正常修改文件中的类名
    • 重命名或移动UIElements文件后,引用该文档的关联文件却不能被一同修改

Console

显示项目的日志,不过目前还是问题一大堆

  1. 有时不显示引起报错的文件(特别是一些null问题)
  2. unity允许一些脚本在不启动游戏的情况下执行,此时的脚本报错也会显示在这里

Inspector

这里集中了对物品的所有属性和配置,在头部位置有一些基本的属性(Active,Name,Tag,Layer等等).
其余部分使用Component的概念来管理.

比如最基本的Component是Transform,主要用用于控制物品的位置和角度,还有放大程度.
在Canvas中的一些物品,比如Text,Button等,为了更精细的控制,大多数情况下最基础的Component是RectTransform.
该类是Transform的子类,相比Transform,可以设置自身的锚点和宽高等信息.
锚点主要描述该物品与父级物品在计算相对位置时,使用父级物品的哪里作为坐标原点.

EmptyObject的特性可能就这么一点,其他物品则是在这之上叠加Compnent.
比如Cube,相当与在EmptyObject上添加 TODO
而如果想给Cube添加其他效果,比如材质,刚体效果,重力效果,脚本等等,都可以通过继续添加Compnent来完成.
除了在Inspector中点击AddCompnent按钮,
Unity也允许将目标直接拖动到物品中(可以拖到Inspector也可以拖到Hierachy里的物品上).

脚本的使用

通常个人习惯在Project窗口下以右键新建C#脚本,然后拖动到物品上.

脚本与外界的接口

在一些场景中,为了调试方便不想每次都改代码,
可以在脚本的类中,将一些变量(比如色彩,灵敏度等)声明为public,这些变量就会暴露在Inspector中.

脚本的类

Mono名字的由来?

脚本的生命周期

其他补充说明

TODO Camera

可以将相机绑定到物品中,和物品一起动
相机可以有多个,还可以设置相机拍到的Layer?
相机的分类

TODO Canvas

canvas主要用来显示按钮,信息等
可以有多个canvas,主要由sort order来决定谁覆盖谁
主要将一些Canvas的一些配置

  1. 像素大小配置
  2. 信息来源配置
  3. 事件系统与Raycaster?

TODO Prefabs

可以叫做预制体?
在场景中加入别人的Prefab后,通常不让直接修改物品,而是需要修改Prefab

项目的共享

下载 *.unitypackage 文件,双击即可导入别人的项目,尽管让选择要导入哪些,不过菜鸟直接全部导入即可.
如果要自己发布打包文件, TODO

推荐开发工具

jetbrains真是个宝藏,推出了Rider for Unity3D.非常好用.
相比普通编辑器的一些优点

  1. 可以自动补全项目中dll,比如UnityEngine中的方法
  2. 可以显示脚本中变量在Unity的哪些面板中被使用了
  3. 可以显示一些性能警告
  4. 可以自动推荐一些更好的写法
    1. 合并if减少嵌套
    2. 推荐Linq写法
    3. 显示哪些库不需要
    4. 推荐一些更有效率的查找物品的API
    5. 统一变量命名风格
  5. 在Shader文件上更好的语法高亮
  6. 可以快速打开官方文档(S-F1)

另外可以和Unity联动

  1. 向Unity推送代码
  2. 操作Unity运行游戏
  3. 可以Debug,可以打断点
    1. 甚至可以反编译dll,然后将断点打到反编译后的文件内,
      对于bug不少的unity官方库来说简直是福音
  4. 可以显示Unity的Console中的日志
    1. 尽管有些日志会漏掉
  5. 点击Unity的Console中的日志,可以跳转到Rider中的编辑器区
  6. 可以显示脚本中变量在Unity的哪些面板中被使用了

这么好的功能,却不是默认能用的,需要在Unity的设置中指定使用Rider作为编辑器, TODO
Unity新建项目之后才会生成Rider所需多 *.sln 文件

TODO 其他概念性东西

  1. 材质和贴图
  2. Layer的分层和作用
  3. 坐标,local坐标

TODO 其他需要解决的问题

  1. 自定义引导页面
  2. 动画的使用
  3. 刚体的一些位置,速度,force等等,暴露unity浅薄本性的API
  4. 关于UI实现方式的探讨
    1. 以前据说是NGUI,现在官方使用的是UGUI,以后可能是UIElement
    2. 除了游戏正式运行时的UGUI,还有OnGUI函数所代表的IMGUI.

参考

  1. 做游戏的能这么紧凑没废话简直难得