Image和RawImage的区别
RawImage核心代码比Image少很多,Raw Image不支持交互,可用于显示任何图片而不仅仅是Sprite,一般用在背景、图标上,支持UV Rect(用来设置只显示图片的某一部分),而Image不支持UV Rect
unity3d打印日志
Debug.Log("This is debug");
//也可以直接使用print
print("hello world");
场景管理器
using UnityEngine.SceneManagement;
SceneManager.LoadScene("2048");
SceneManager.GetAllScenes();
SceneManager.GetSceneByName();
SceneManager.GetSceneByPath();
SceneManager.MoveGameObjectToScene();
Debug.Log(SceneManager.getscene)
unity的so的易错点
- 如果so中出现segment fault等崩溃性错误,则unity整个都会崩溃。
- unity editor在打开的整个过程中,so只会加载一次。因此如果so发生变化,只能重启unity editor。
动态加载资源的方式?
- Resources.Load();
- AssetBundle:Unity5.1版本后可以选择使用Git: https://github.com/applexiaohao/LOAssetFramework.git
使用text存储日志存在的问题
如果使用UI中的text存储日志并展示日志,存在一个巨大的问题。当text长度过长之后,unity就会报错,说渲染的数据量过大。
让一个MonoBehavior汇集多个MonoBehavior的功能
[RequireComponent (typeof(XXXX))]
其中XXXX为依赖的脚本,或者Unity组件(理论上都算作脚本),这样,当你挂这个脚本时,XXXX脚本也被挂上去了
activeSelf、activeInHierarchy
- activeSelf:只读字段,物体本身的active状态,对应它在inspector中的checkbox是否被勾选。
- activeInHierarchy:只读字段,物体在层次中是否是active的,也就是说只有当这个物体及其祖先物体都是active时这个值才为true。
一个物体如果是activeSelf状态,那么这个物体不一定可见,因为它的父物体可能是inactive状态。在Unity中,一个物体要想处于可见状态,activeHierachy必须为true。
改变物体active状态的两个函数:
- SetActive():设置物体自身的activeSelf状态。
- SetActiveRecursively()(obsolete):改变物体及其所有子物体的active状态。
使当前物体朝向目标物体,修改目标物体的朝向
Vector3 dir = m_chooseTarget.transform.position - transform.position;
dir.y = 0;
transform.forward = dir.normalized;
取消关联prefab
选中GameObject,右键菜单选择prefab/unpack prefab completely.
如果A prefab里面包含着B prefab,则需要编辑A prefab,把B的prefab去掉。
2d的spriteRenderer,3d的meshRenderer
SpriteRenderer是干什么的?简单来说就是一个renderer,这个renderer的输入是一堆资源文件(例如图片、动画等),输出就是一个二维图像。
unity中以GameObject作为基本对象,因此渲染的时候渲染顺序就很重要,它直接决定了物体的可见性。
unity中与sprite有关的组件
- 提供占位的SpriteCreator
- 内置的SpriteEditor
- SpriteRenderer
Unity的最佳实践
使用容器盛装的时候,尽量使用具体的MonoBehaviour类而不是GameObject,因为GameObject本质上就相当于是一种void*
,它里面包含什么东西是不太确定的。
游戏框架
GameObject,把游戏中的很多东西看做是一个物体。
过去我编写的小游戏,没有GameObject+不停渲染的过程,大部分是基于事件进行刷新的过程。
GUI框架与游戏框架的最重要的区别就在于,GUI框架基本上都是需要用户操作来触发UI的变化,而游戏框架则包含一个游戏主循环,即便用户不执行任何操作,游戏状态也在不停地改变。
Editor
要查看 Editor 日志,请在 Unity 的 Console 窗口中选择 Open Editor Log。
操作系统 日志文件
macOS ~/Library/Logs/Unity/Editor.log
Windows C:\Users\username\AppData\Local\Unity\Editor\Editor.log
Unity的Editor跟正在播放的游戏是同一个线程,游戏崩了,可能需要查看日志才能看出来。
SpriteRenderer中的DrawMode
SpriteRenderer是精灵渲染器,一个精灵渲染器接受一个精灵对象。一个精灵对象其实就是一个图片。
SpriteRenderer决定了如何渲染一个精灵。
DrawMode有三个取值:
- simple:直接把精灵画上去
- sliced:把精灵的一部分画上去
- tiled:把精灵重复地画出来
Texture2d
Sprite是Texture2d的一种,精灵是Texture2d的一种特殊情况。
Material
默认材质是不可编辑的。
材质可以指定一个shader,unlit/texture是最常用的一种材质shader。
用户自己创建的材质有用可编辑的属性。
材质是一个全局对象,所以默认材质是不可编辑的。如果把同一个材质赋给两个不同的GameObject,在编辑器中,当其中一个的材质的Offset发生变化的时候,另一个GameObject的材质的Offset也会发生变化;在代码中,当其中一个材质的Offset发生变化的时候,另一个GameObject的材质的Offset并不会发生变化,这表明运行时每个GameObject持有的材质是不相同的。
Material不是Component,GameObject无法直接持有一个Material,GameObject其实并不直接拥有Material,而是拥有SpriteRenderer,SpriteRenderer又拥有Material。在Unity中,GameObject的Inspector面板之所以展示Material,是unity为了方便直接编辑Material。获取材质的时候:material = GetComponent<Renderer>().material;
MainTexture是最常用的Texture,为此unity提供了直接访问mainTexture的一些属性。
private static readonly int MainTex = Shader.PropertyToID("_MainTex");
void Update()
{
//直接使用mainTextureXXX属性
var m = GetComponent<SpriteRenderer>().material;
var p = m.mainTextureOffset;
p.x += v * Time.deltaTime;
m.mainTextureOffset = p;
}
void update1()
{
//获取Texture然后更新属性
var m = GetComponent<SpriteRenderer>().material;
var p = m.GetTextureOffset(MainTex);
p.x += v * Time.deltaTime;
m.SetTextureOffset(MainTex, p);
}
三角面
三维物体的渲染依赖3D建模,3D建模就是构建三角面片。
为什么使用三角面片而不是四边形? 因为三角形是二维空间中最简单的封闭形状,具备足够高的灵活性,任意一个四边形面片都可以用两个三角形面片来表示。
移动端GPU算力较低,通常面数低于10w面。
与游戏性能相关的参数:
- 帧率
- DrawCall
- 面数
Unity设置程序在后台始终运行
默认情况下,Unity程序在失去焦点之后渲染随之停止。 设置Application在背景运行,避免UI停止之后不在运行 Application.runInBackground=true
UnityEngine的Object.cs
Object.CurrentthreadIsMainThread():当前线程是否是主线程 DontDestroyOnLoad:在切换场景的时候不要销毁对象。
Unity中有两个最关键的类:MonoBehavior和GameObject,它们共同继承了Object这个类。 MonoBehavior=>Behavior=>Component=>Object GameObject=>Object