Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


软件:unity:unity

Unity

引擎设计

个人理解:在Unity的设计逻辑中,Component(组件)是非常重要的,一个Component实现了某一个方面的功能,Component是逻辑功能的承担者和最小单位,这样的设计也便于降低系统的耦合度,提升代码的重用度。脚本代码就是Component。这一点和Unreal不同,Unreal是通过继承来实现逻辑功能的,所以很明显的一个感受就是:写Unreal的时候,思维主体是Actor(GameObject),代码一般也都是在Actor类里面,要思考的是游戏内的某个,某类对象应该有什么逻辑,通过继承实现代码重用;写Unity的时候,除非是特别特定的脚本,只用在某个物体上,否则都是一个通用的功能,思维出发点是这个组件本身的逻辑功能,并不牵扯到特定的GameObject。继承关系的话,要一开始就设计好,后期不太方便改动;相比之下,Component就更优雅了,可以随意组合。(运行效率如何?)
关于Unity中的Script Component,它们是逻辑的主要承担者,GameObject是无法直接编辑逻辑的,但是继承自MonoBehaviour的类(可以作为Component的Script)其实已经封装了很多接口,例如GetComponent这种,是以这个Component所在的GameObject为出发点的,以GetComponent为例子:在Component中获取Component其实是不合逻辑的,本身的逻辑应该是Component的GameObject获取Component,但是获取GameObject的一步被封装起来了。那么写Component的逻辑的时候,也和直接写GameObject的逻辑有相似之处(以谁为逻辑的出发点)。

美术设计

资产管理

问题和想法:

  1. Load是资源加载,Instantiate是实例化游戏对象,二者具体的区别有哪些?实例化之前是不是都必须有加载的步骤?加载一份资源,是不是可以实例化多个游戏对象?游戏对象实例化之后,加载的资源是不是就可以卸载了?还是等游戏对象销毁的时候才能卸载资源?

外链资料:

  1. Unity学习—资源管理概览 https://warl.top/posts/Unity-Resource-Manage/ 归档
  2. Unity内存与资源管理(一) https://zhuanlan.zhihu.com/p/424210289 归档

物理仿真

用户界面

以下都是官方提供的UI系统:

一个好用的工具:RenderTexture
毛玻璃效果:背景模糊
滑动框(包括无限循环列表)
布局知识

程序逻辑

编辑器

在Unity编辑器中开发自己需要的功能。C#的代码在Editor中也可以运行。编辑器代码不应该被打包。

零散:

  • Editor外部的代码访问不到Editor文件夹里面的代码,程序集引用关系设定如此。在Editor内的代码文件,不会参与Build
  • [待验证]返回选中对象在Scene是否可见:SceneView.FrameLastActiveSceneView
  • 修改Scene中的选中对象:Selection.activeGameObject=vWay.gameObject;
  • OnOpenAssetAttribute,可以用于定制自定义资源的打开方式,参考:https://docs.unity3d.com/2020.1/Documentation/ScriptReference/Callbacks.OnOpenAssetAttribute.html。这个算是Open Asset的Callback,是全局的,在Callback里面需要判断Asset的类型是不是我们想要处理的类型
  • 可以标记某些属性是否保存在PlayMode的修改(默认情况下,PlayMode中进行的修改在退出PlayMode后就会丢失),使用[SaveDuringPlay] / [NoSaveDuringPlay]

外链资料:

  1. Unity编辑器的一些不常用功能 https://zhuanlan.zhihu.com/p/95004242 归档

渲染

预制体

动画

相机

网络

AI

插件

Package

调试

经验

  • 对象池:池的最重要的特性,也就是对象池设计模式的本质是允许我们获取一个“新的”对象而不管它真的是一个新的对象还是循环使用的对象。

零散

需要整理!分散到各个板块中去!

  • Start()和Awake()的差别:Awake在MonoBehavior创建后就立马调用,不论脚本是否是enable的,而且Awake被调用时,场景中所有的GameObject都已经实例化,使用GmeObject.Find这样的方法也是安全的;Start将在MonoBehavior创建后在该帧Update之前,在该Monobehavior.enabled == true的情况下运行,也就是说其调用时间是在对象被第一次enable之后,在第一次Update之前。两者的调用时间都是在所有的enabled对象Update被调用之前,Awake会在所有对象的Start之前调用,但是注意不同对象之间的Awake顺序是不得而知的。在默认不定义[ExecuteInEditMode]的情况下,这两个函数都是只有在Runtime中才会执行。
  • 当你要迁移一个工程,或者将工程复制给别人的时候,只需要将Assets、Packages以及ProjectSettings三个目录备份即可,至于Library会在Unity打开的时候进行检查和自动转化。
  • 所有的资产原始文件都必须要放在Unity工程的Assets目录,然后经过Unity处理之后存放在Library目录下。
  • Unity的每个GameObject都有Transform Component,这个组件也不能移除(和Unreal不同)。获取父对象可以使用transform.parent,也许就是因为每个游戏对象都必须有Transform Component,所以transform才可以作为游戏对象的唯一标示吧。UGUI的游戏对象是另一种Transform:RectTransform。
  • Unity的工程是文件夹,没有工程文件。
  • GameObject之间有父子关系,Component之间没有父子关系,但是Component之间有先后顺序。
  • VS不负责Unity脚本的编译,Unity自己处理编译,所以使用什么外部编辑器都可以。
  • 类名和文件名必须相同才能使脚本组件附加到游戏对象,有些代码不是为了添加到游戏对象上的,所以没有这个要求,文件名和类名不同的脚本也不会出现在Add Component的选项列表中。同一个项目中,默认情况下不能有同名的代码文件,即使是不同的路径,不同的路径下文件名是可以相同了,但是类名还是不能相同(除非在namespace内)。在namespace内定义的类居然也可以当作Component?会不会有歧义?
  • Event Trigger Component可以用于获取事件,比如鼠标点击GameObject,鼠标移入移出。
  • 为什么父子对象关系都要牵扯到transform,因为父子对象的关系也只体现在transform上吗?
  • Unity中创建的Script不一定是继承自MonoBehavior的,Unity中类的继承关系也比较容易更改,不像Unreal。
  • 在Update中函数中如何获取DeltaTime?使用Time.deltaTime。
  • 某些类,在文档中的标注是:struct in UnityEngine / Implemented in: UnityEngine.CoreModule,以上是Vector3类的标注,访问的时候还是在UnityEngine下访问,不用管UnityEngine.CoreModule这个。MonoBehaviour的标注是:class in UnityEngine / Inherits from: Behaviour / Implemented in: UnityEngine.CoreModule。
  • Unity的二维座标系,原点在左下角,向右/向上是正方向。
  • Unity支持同时打开多个场景(multiple scenes),直接将另一个场景拖入当前打开的场景即可,具体的工作方式和用途记得查看一下文档。
  • 在Component的代码中允许显示在编辑器的属性,如果是继承自UnityEngine.Object,就是选取的形式(相对于普通数值,普通数值是填写)。
  • 关于Camera:游戏画面最终是由哪一个Camera渲染来的(如果有多个相机的时候)?这是由什么控制的?给Camera挂上MainCamera的Tag后,可以使用Camera.main(静态成员变量)来访问,但是这个Tag在逻辑上不影响别的。根据经验来解答:Camera Component的Target Display可以选择渲染到Display X,游戏的默认画面是Display 1,Target Display相同的所有相机,根据Depth来排序(以上待验证)。
  • Asset(文件夹)里面的是资源,在Project(编辑器窗口)内显示,在Hierarchy(编辑器窗口)内编辑的是Scene的内容。
  • Unity的文档不是按照类的继承关系来组织的,而是按照类所在的Namespace来组织的,是一种包含的关系。(A中有B,B中有C,像是文件夹)。所以想看整体的类继承关系的话资料比较难找。
  • Inspector面板既可以显示资源的属性,也可以显示Scene中的对象的属性(仔细想想资源游戏对象的区别和联系)
  • 矩形工具,和移动旋转缩放在一起的一个工具,操作UI元素或者2D对象(都是平面的)很方便,也可以操作3D游戏对象,只是可能不太好用
  • PropertyName用于将属性名Hash转换为一个数字,提高比较、传递等操作的效率和安全性,因为是Hash所以这个过程是不可逆的
  • Preferences是编辑器的偏好(和项目无关),Project Settings是项目设置
  • 为什么获取Child、Parent这样的属性,都需要从Transform中访问呢?[猜想]GameObject根本就没有维护父子关系的功能,Transform才实现了这个功能,所以每个GameObject才强制必须有一个Transform组件
  • Transform组件是不能自己手动创建的(通过new等方式),只能访问已经的GameObject的Transform
  • 设定帧率上限:Application.targetFrameRate
  • Build界面有一个Player Settings,为什么这个Settings如此特殊,这里的Player,也许并不是指「玩家」,而是「播放器」
  • 在编辑器中AddComponent,基类可以自动升级为子类,比如一个空GameObject,Add一个RectTransform,Transform就会升级为RectTransform
  • 切换场景时,保留GameObject不销毁:Object.DontDestroyOnLoad(),被标记的GameObject之后需要手动销毁。被标记的GameObject(在Runtime)都会被移动到一个叫做“DontDestroyOnLoad”的Scene下,这个Scene是Unity创建的,方便我们查看管理

Odt笔记(20221007)

/var/www/DokuWikiStick/dokuwiki/data/pages/软件/unity/unity.txt · Last modified: 2023/05/20 00:15 by zh