unity-记录

关于 unity 项目相关优化经验的墨迹


前篇

插件

其他


版本更新计划

Unity TECH版本每年将有三次主要更新,它们会带来最新的功能与特性。
Unity LTS版本将从TECH版本每年最后一个版本开始,持续支持二年的时间。

全新版本的发布方式
首个Unity LTS版本将是Unity 2017.4,也就是Unity 2017.3最新更新版本。版本号的改变标志着新的LTS周期的开始。所以xxxx.1、xxxx.2和xxxx.3都是TECH版本,而xxxx.4则是LTS版。


版本新功能

  • Unity 2021
    • a

内置包

内置包允许用户通过 Package Manager 启用或禁用 Unity 功能。启用或禁用某个包会减小运行时构建大小。例如,大多数项目不使用旧版粒子系统。

删除此功能的内置包时,Unity 不会在您构建最终应用程序时包含相关的代码和资源。通常,这些内置包中仅包含包清单,并与 Unity 捆绑在一起(而不是在包注册表中提供)。


Editor 日志路径

  • win
    • 查找闪退日志,在目录 C:\Users\yangxuan\AppData\Local\Unity\EditorEditor.log 文件中可以查看 Debug.Log 日志
    • 或者 C:\Users\wilker\AppData\Local\Temp\Unity\Editor\Crashes 目录下
  • mac
    • ~/Library/Logs/Unity/Editor.log

打包环境配置

android

直接解压 nas 上的 android sdk, ndk, java , 然后配置进去即可.

另外 java 需要添加环境变量中 ( JAVA_HOME )


编译宏

常用的几个宏

  • UNITY_STANDALONE : 计算机平台运行包体, 如: Mac OS X, Windows or Linux.

    • 细分: UNITY_STANDALONE_OSX, UNITY_STANDALONE_WIN, UNITY_STANDALONE_LINUX
  • UNITY_EDITOR : 计算机平台编辑器模式

    • 细分: UNITY_EDITOR_OSX, UNITY_EDITOR_WIN, UNITY_EDITOR_LINUX
  • UNITY_IOS : ios 平台 (UNITY_IPHONE 已废弃)

  • UNITY_ANDROID : android 平台


AssetBundle 打包踩坑

打包闪退

  • 可能是包含了导入 fbx 文件时, 导入了 里面的贴图, 及生产了一个材质球 导致的. 干掉这两个目录就ok了

  • 同一个 ab 下, 有两个 文件名 相同的资源.

    • 如果 ab 有生成 manifest 文件, 查看一下里面的资源是否有跨目录同名

      image-20220509155629253

      闪退日志里会有资源冲突的信息, 关键字 Conflict happened between Asset

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
              Building AssetBundle failed because hash collision was detected in the deterministic id generation.
      Conflict happened between Asset "Assets/Res/UI/Atlas/gg_review_1928/bg_flicker_05.png" and "Assets/Res/UI/Atlas/gg_review_1928/cards/bg_flicker_05.png".
      UnityEditor.BuildPipeline:BuildAssetBundlesWithInfoInternal(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTargetGroup, BuildTarget)
      UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTargetGroup, BuildTarget) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline.bindings.cs:471)
      UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTarget) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline.bindings.cs:457)
      PackAssetBundle:BuildArtAB(BuildTarget, String) (at Assets\Code\Editor\EditorShare\Package\PackAssetBundle.cs:272)




      ---

      #### 文件打包成 ab

      unity 的 ab 打包文件, 文件名必须以 unit支持的格式 结尾, 才可以打成 ab 中的*TextAssets* .

      unity 支持的格式为: `.txt, .html, .htm, .xml, .bytes, .json, .csv, .yaml, .fnt`

      比如: aaa.lua, 要修改为 *aaa.bytes* 或 *aaa.lua.bytes* 才能打成 ab.

      参考:

      - https://www.cnblogs.com/123ing/p/3812188.html
      - https://blog.csdn.net/sibaison/article/details/71249363



      ---

      #### 系统找不到指定的文件

      ![](https://pic04.wilker.cn/20200518162454-1.webp)

      **出现原因**:

      1. 使用Unity 打包bundle时出现弹框报错,一开始以为是沙盒的问题,后面排查发现是bundle中出现同名文件(条件是:文件名一样,放在不同目录下,打包到同一个Bundle)。
      **解决方法**:根据原因规避。
      2. prefab 引用的 prefab 丢失, 也会造成这个错误.



      参考: https://blog.csdn.net/Xymazpq/article/details/90032563



      ---

      ### 踩坑记录

      - 报错 ` The requested operation caused a stack overflow`

      > 可能有递归调用 死循环

      - 修改材质球不生效??

      > 没有 ctrl + s 保存. 修改材质球后需要 保存 才能写入 .mat 文件中

      - Unity 安装 Support-for-Editor 时出现 failed to local unity.exe

      > 在Unity中补充安装Support-for-Editor时会出现failed to local unity.exe错误,为找不到本地的unity启动程序,安装对路径的要求十分严格,要安装选择在对应版本的Editor目录的上一级目录进行安装。
      >
      > 参考: https://blog.csdn.net/lz0044/article/details/79574055

      - 切场景报错: `Some objects were not cleaned up when closing the scene`

      > 是因为在切场景的时候 实例化go.

      - ios 打包后, 程序运行闪退, xcode报错: `unity [xxx] was compiled with optimization - stepping may behave oddly variables may not be available`

      > - 如果是 *Run in Xcode as设置为Debug* , 这需要在 ios 平台下 *Other Settings* 中的 *Strip Engine Code* 取消勾选, 默认是勾选上的
      > - 如果是 *Run in Xcode as设置为Release , 未出现问题
      >
      > 参考: https://www.jianshu.com/p/26fd847f980e



      ---

      ### UnityEditor.AsyncHTTPClient:Done(State, Int32)

      - Edit -> Preferences -> Show Asset Store Search hit 取消勾选



      ---

      ### projectsettings asset 是二进制问题

      - 改为明文的text, *Edit -> Project Settings -> Editor* , *Asset Serialization* 的 *Mode* 改为 *Force Text*



      ---

      ### 打包使用图集

      - *Edit -> Project Settings -> Editor* , *Sprite Packer* 的 *Mode* 改为 *Always Enabled*



      2017之后的有新的一个选线, 不过貌似没什么乱用, 参考: [Unity2017的新版图集 & 自带图集实现TP的Polygon布局](https://zhuanlan.zhihu.com/p/32591450), 选 *always enabled(legacy sprite packer)*

      ![](https://pic04.wilker.cn/20190723204155-1.png)

      实测选项 *always enabled* 打出的包会比 *always enabled(legacy sprite packer)* 大, 所以还是使用以前的好 ( *always enabled(legacy sprite packer)* )



      查看图集 *window -> 2d -> sprite packer*

      ![](https://pic04.wilker.cn/20190723205851-1.png)



      ---

      ### 打包首场景

      - 启动游戏的第一个场景,必须在 *Resources* 中,且必是第一个

      ![这里写图片描述](https://pic01.wilker.cn/20180421_150410_323.png)



      ### UI 局部坐标 转 全局坐标

      ```csharp
      Vector3 wp = Camera.main.WorldToScreenPoint(transform.position);
      RectTransform rect = GetComponent<RectTransform>();
      Vector2 tempWorldPos;
      RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, wp, Camera.main, out tempWorldPos);
      Debug.LogFormat("--- tempWorldPos, x:{0}, y:{1}", tempWorldPos.x, tempWorldPos);

RenderTexture 不渲染部分场景物体

  • 默认的 Color FormatARGB32, 改成 ARGB Half 就没问题了. 有待探究.

断言 Assert

如果需要断言中断执行,需要 Assert.raiseExceptions = true;

参考链接: https://blog.csdn.net/u010019717/article/details/50375226


vscode没有代码提示解决

  • 可能的原因

    1. 刚check来的工程, 没有生产 解决方文件 ( xxx.sln, xxx.csproj) , 所以随便打双击项目内的 cs 文件让 vs (注意不是vscode) 打开, 生产这些解决方案. 然后再把 外部编辑器 切回 vscode.
    2. 没有对应的 .dotnet 版本, vscode 的 OmniSharp 插件 报错: The reference assemblies for framework ".NETFramework,Version=v4.7.1" were not found. 下载对应版本的 .NETFramework 安装即可
  • 解决完就能找到符号了


asset bundle 资源查看器

  1. 官方支持的资源引用查看器 及 ab 查看器 (看不到里面的资源) - https://github.com/Unity-Technologies/AssetBundles-Browser
  2. 可以查看到 ab资源的查看器 - https://www.jianshu.com/p/d396d3ca1ebd

ios 平台的 team id 设置

  1. 构建xcode工程自动配置好签名, 需要设置 ios 平台设置的 Ohter Settings 中的 Signing Team ID

  2. 这个字段的配置来自于 ios 证书上的信息. 在 mac 中打开 Keychains, 在 login -> Certificates 中找到打包ios的证书, 右键 GetInfo , Organizational Unit 字段就是需要的 Team ID, 复制粘贴到unity中.

  1. 然后构建 xcode 工程就能看到自动签名了

  2. 参考: https://blog.csdn.net/mseol/article/details/80202778


清除控制台日志

1
2
3
4
5
public static void ClearConsole() {
var logEntries = System.Type.GetType("UnityEditorInternal.LogEntries,UnityEditor.dll");
var clearMethod = logEntries.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
clearMethod.Invoke(null, null);
}

float与double精度

参考: https://www.cnblogs.com/BradMiller/archive/2010/11/25/1887945.html

float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为67位有效数字;
double:2^52 = 4503599627370496,一共16位,同理,double的精度为15
16位。


unity 与 3dmax 顶点不一致

主要是在 max 中建模时, 可以将相交面设置为相同的平滑组, 这样相交点的法线就是相交面的 均值.
如果设置为不同的平滑组, 则相交面的 相交点的地方可以就有几个顶点, 各自有用所在面的法相, 看起来就会有 硬边
顶点越多, 就越耗gpu计算性能, 毕竟每个顶点都要经过 顶点着色器
什么是平滑组? 参考 3dsmax记录 的笔记 - 平滑组

  • 平滑组相同. 6个顶点. 无硬边

  • 平滑组不同. 8个顶点. 有硬边.


一个Quad四边形mesh的 顶点 排布

所以调uv值是也应该按这个顺序调整 (纹理坐标是笛卡尔坐标系第一象限)

1
2
3
4
newUvs[index * 4 + 0] = offset; // lb
newUvs[index * 4 + 1] = offset + dt; // rt
newUvs[index * 4 + 2] = offset + new Vector2(dt.x, 0); // rb
newUvs[index * 4 + 3] = offset + new Vector2(0, dt.y); // lt

组件脚本勾选框

只要脚本中有 Start() 方法, 就可以显示除勾选框


枚举 转成 字符串数组

1
2
3
4
5
6
7
8
public enum BlendMode
{
Opaque,
Cutout,
Fade,
Transparent
}
public static readonly string[] blendNames = Enum.GetNames(typeof(BlendMode));

C# Dictionary 实现原理

和 c++11 中的 hashmap 差不多. 都是先通过 哈希函数 算出一个 哈希值, 对 bucket 数量求余 得到一个 索引值, 直接索引 bucket数组. 在哈希冲突的情况下, 在再通过 一个判定条件判断是否相等, 在桶存储的一个头指针往单链表逐个遍历判定是否相等.

Dictionary 的存储结构是 数组+单链表. 所以时间复杂度是 O(1), 最坏的情况是 O(n)


定点数 和 浮点数


timeline


修改动画参数

如果修改为循环参数,需要用 clipAnimations 判断是否 > 0,然后在重新复制新的 clipAnimations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static bool CharActionLoop(ModelImporter importer, string path) {
if (!path.Contains(kCharPath) || !path.Contains("@"))
return false;

bool isDirty = false;

if (importer.clipAnimations.Length == 0) {
if (importer.defaultClipAnimations.Length > 0) {
List<ModelImporterClipAnimation> actions = new List<ModelImporterClipAnimation>();
ModelImporterClipAnimation anim = importer.defaultClipAnimations[0];
isDirty = true;
anim.loopTime = true;
actions.Add(anim);
importer.clipAnimations = actions.ToArray();
Debug.LogFormat(importer, "<color=red>勾选动作 loop time:True</color>, {0}", path);
}
}

return isDirty;
}

应用设置

代码修改后的 apply, AssetDatabase.ImportAsset

1
2
3
4
5
6
public static void CharActionLoop(string path) {
ModelImporter importer = AssetImporter.GetAtPath(path) as ModelImporter;
if (CharActionLoop(importer, path)) {
AssetDatabase.ImportAsset(path);
}
}

OnCollision,OnTrigger失效原因

  • OnCollision:

    1. 双方必须要有Collider

    2. 其中一方必须要有刚体

    3. 有刚体的一方不能勾选Is Trigger

    PS:此情况下会有刚体的物体碰撞效果,而且无法在没有刚体物理碰撞效果下触发该函数

  • OnTrigger:

    1. 双方必须要有Collider

    2. 其中一方勾选Is Trigger

    3. 其中一方必须要有刚体

    PS:在带刚体的物体下的Colloder中勾选Is Trigger后刚体的物理碰撞效果会失效

  • 参考: https://blog.csdn.net/qq_34818497/article/details/78184790


碰撞后刚体自动旋转, 位置偏移


碰撞后不断触发 trigger的问题

被碰撞物体B, 包含 碰撞 组件, 里面的 * OnTriggerEnter,OnTriggerExit* 不断被触发.

主动碰撞物体A, 包含 碰撞,刚体 组件

实测得出有两种解决方式

  1. 靠谱. 将 主动碰撞物体A 中的 Sphere Collider 勾上 Is Trigger

  2. 不靠谱, 耗性能. 将 主动碰撞物体A 中的 RigidbodyCollision Detection 设为 Continuous. 官方文档中有指出这个是为了快速移动的物体使用的. 防止在一帧之内直接穿越碰撞框. 比较消耗性能.

    参考: https://docs.unity3d.com/ScriptReference/Rigidbody-collisionDetectionMode.html

    These two options have a big impact on physics performance


创建资源到场景(引用)

效果和拖进去的一致

1
2
3
4
5
string path = "Assets/res/Prefabs/building/b_leifengta/b_leifengta.prefab";
GameObject assetGo = AssetDatabase.LoadAssetAtPath<GameObject>(path);
GameObject go = PrefabUtility.InstantiatePrefab(assetGo) as GameObject;
go.transform.parent = sceneRootGo.transform;
Debug.LogFormat(go, "--- path: {0}", item);

判断物体是否在视锥体内

1
2
3
4
5
6
7
8
9
10
11
bool IsCanCulling(Transform tran)
{
//必要时候,摄像机的视域体的计算 放置在裁剪判断之外,避免多次坐标变换开销,保证每帧只有一次
Vector3 viewVec = Camera.main.WorldToViewportPoint(tran.position);
var far = Camera.main.farClipPlane ;
var near = Camera.main.nearClipPlane;
if (viewVec.x > 0 && viewVec.x < 1 && viewVec.y > 0 && viewVec.y < 1 && viewVec.z > near && viewVec.z < far)
return false;
else
return true;
}

GUP Instance


聚焦与场景对象

1
2
Selection.activeGameObject = rootGo;
SceneView.FrameLastActiveSceneView();

将自定义类对象显示在Unity的Inspector面板上

1
2
3
4
5
[System.Serializable] // 加上这个属性即可
public class LightmapOffset {
public int index;
public int length;
}

参考: https://blog.csdn.net/LIQIANGEASTSUN/article/details/42101989


选中 go 线框显示

修改 线框 颜色: edit -> preferences -> colors -> wire frame selected


面部表情


修改贴图打包最大值

这样可以不用重新用ps导图, 就能打出比较小的 assetbundle

1
2
3
4
5
if (importer.maxTextureSize != 256) {
importer.maxTextureSize = 256;
Debug.LogFormat(importer, "<color=red>--- 打包最大值maxTextureSize修改为 256</color>, path:{0}", path);
isDirty = true;
}

去除顶点色


灰度图 与 rbg图 的大小

pc项目上看貌似 灰度图小很多 ( rgb图的 1/3).

实际上 (多平台) 打出的 ab包 都差不多, 所以不太在意 黑白图 是否用 灰度图 还是 rgb图. 直接 rgb 就行了.

且对应所占的内存也是一样


Frame Debugger 使用


iOS平台下RGBA PVRTC4打包图集失真非常严重

Unity 5.5.1版本下,Sprite Packer在iOS平台下RGBA PVRTC4打包图集失真非常严重(对单个的Sprite设置PVRTC4是正常的),参照了4.6.7版本是正常的,我想知道为什么呢?

unity的bug, 在 Windows 下尝试用 4.7 的 pvrtextool.exe 替换了 5.x 的,暂时解决了这个问题,建议也尝试一下。


图形渲染及优化—Unity合批技术实践


资源查看器 AssetStudio


变换局部坐标到世界坐标

1
Vector3 globalPos =  transform.TransformPoint(boxCld.center); # 用当前对象的矩阵transform 将 某个子节点的 局部坐标点boxCld.center 变换为 全局坐标点globalPos

animation 中替换材质球

unity支持在 animation 中替换材质球, k上关键帧后直接赋予新材质就即可.


unity2018 shader graph

参考


编辑器点击 play 的回调

可以用于 点击 play 时清除控制台 log

1
2
3
4
5
6
7
[InitializeOnLoad]
public class EditorStartup {
static EditorStartup() { // 静态构造方法
EditorUtils.ClearConsole();
UnityEngine.Debug.LogFormat("--- EditorStartup ClearConsole");
}
}

视频录制使用插件

  • AVPro Movie Capture : 视频录制

    • 录制视频时, 选择 离线渲染 方式 才能无卡顿, 实时渲染 可能会卡顿

    • 开启抗锯齿

    • 使用压缩, 不然很大


下载插件位置

  • windows : C:\Users\AppData\Roaming\Unity\Asset Store
  • Mac OS X : ~/Library/Unity/Asset Store

安装unity支持包


第三方插件 相关

tolua 相关

关于 byte[]

让 csharp 中的 byte[] 压入 lua 中成为 lua string (lua pb 反序列化使用) 而不是数组 userdata, 可以有两种姿势

  1. 自己封装的数据结构中有 byte[] 属性, 然后加上一个 LuaByteBufferAttribute. 官方的 LuaByteBuffer 中有说明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // csharp
    public class CNetRes {
    [LuaByteBufferAttribute]
    public byte[] buff = null;
    // LuaByteBuffer buff = null; 不能讲 LuaByteBuffer 作为数据结构的成员, 否则会报 空指针调用 的错误
    }

    // lua
    local netRes = getNetRes()
    local res = PB.PayloadData()
    res:ParseFromString(netRes.buff)
  2. 在回调 lua 方法时, new LuaByteBuffer(bytes) 传给lua

    1
    2
    3
    4
    5
    6
    7
    8
    // csharp
    mOnMsgFn.Call(new LuaByteBuffer(bytes));

    // lua
    local function OnDecode(luaBuffer)
    local res = PB.PayloadData()
    res:ParseFromString(luaBuffer)
    end

besthttp 相关

回包时粘包

如: 上行 a, b 两个包, 下行时 a,b 包的返回值粘在一起, 在一个响应里回来, 那么, 另一个响应里就会出现, data 长度为 0 的情况.


踩坑

  • android 平台打包报错

    1
    Found plugins with same names and architectures, Assets/Plugins/x86/tolua.dll (ARMv7) and Assets/Plugins/x86_64/tolua.dll (ARMv7). Assign different architectures or delete the duplicate.

    修改这两个 tolua.dll 的设置, 两个都 排除掉 android 平台, 然后 Apply 即可

  • ios 平台打包报错, 和上面一样的错. 勾选上 IOS, 然后 Apply 即可


摄像机

场景中一定要有一个 透视摄像机 并且 clear flagsskybox 或者是 solid color. 不然会出现类似 残影 效果.

踩坑

  • 做ar项目时, 在 ar 场景中为了时 ar相机 和 普通相机同时渲染, 叠加上去. 将 普通相机(dont destroy)设置 clear flagsdepth only. 切回 普通场景时, 只有一个普通相机, 所以出现了餐饮.

    解决办法: 一个 全局普通相机a(dont destroy), clear flagssolid color , ar 模式下, ar 场景使用 ar相机 和 普通相机b (clear flagssolid color), 此时 相加a active 为 false.


资源加载 Resources.Load

关于这个api的调用, 资源是存放在 Resources 目录之下的, 但是 Resources 可以在任何文件夹下, 比如

1
2
if (combineMaterial == null) combineMaterial = new Material(Resources.Load<Shader>("SSR/Combine"));
if (blurMaterial == null) blurMaterial = new Material(Resources.Load<Shader>("SSR/Blur"));

这时候命名就比较重要了, 不然不同 Resources 目录下的资源容易冲突, 加载时错误

此规则同样适用于 Editor 目录下, 这样打包时如果只是编辑器工具相关的话就不会打包进去.


资源内存管理


特效 与 ui 绘制顺序问题

要修改 特效 绘制在 ui之上,只要确保 特效的 renderer.sortingOrder 大于 ui 所在 的canvas 的 Sorting Layer

参考辅助脚本 UIdepth.cs

1
2
3
4
5
6
ParticleSystem[] particles = GetComponentsInChildren<ParticleSystem>();
foreach (ParticleSystem particle in particles)
{
Renderer renderer = particle.GetComponent<Renderer>();
renderer.sortingOrder = order;
}

RawImage 在没有 RenderTexture 的时候,会出现黑块(Android)

先隐藏 rawimage ,rt加载完在让它显示出来,rt附上去


使用遮罩shader,没有效果

如果需要使用 透明度做遮罩 的 shader,被处理图 不能打图集,因为 uv 映射的是 被处理图 所在的图集


unity 自动打出的图集拉伸边沿

切单图没有预留几个 透明像素点导致的,需要预留一两个像素点

这里写图片描述


ios uv流动长时间后卡顿

使用了错误的uv流动方式,并且错误的去修改 偏移值

错误的做法

1
2
3
void Update () {
render.material.mainTextureOffset += temV2;
}

真确做法

start 中缓存好 material ,而不是 update 中去 get material


切场景后灯光丢

场景的 灯光 不要放在 prefab 中打灯,这样灯光信息是放在 prefab 上,只要 break prefab 就会造成灯光丢失,场景里面的东西就不要弄预制了吧


android,UIInput拉起输入法字都是白色的问题

参考链接:http://blog.csdn.net/linxinfa/article/details/77675757

出现这种情况,一般是因为修改了AndroidManifast.xml的主题

如果是unity5.5及以上的版本,则需要在application标签加上unity的默认主题设置

android:theme=”@style/UnityThemeSelector”

如果是unity5.5以下的版本,可以将unity工程导出成android工程看下AndroidManifast的默认主题配置


android,烘焙的光照图丢失

参考链接:http://ask.manew.com/question/38333

修改设置 Edit -> Project Settings ->Graphics ,将 Shader stripping 下的 Lightmap Modes 由 默认的 Automatic 修改为 Manual,然后 去掉 Realtime Non-DirectionalRealtime Directional 的 勾选

这里写图片描述


拖进脚本的prefab,运行时不能加载

asset bundle 打包时 不会 关联脚本上的 prefab,只会关联 prefab 之间的引用, 这个很容一踩坑

比如 虚拟列表 中, item 的关联可以采取弄一个 item prefab 到 虚拟列表 prefab 中 隐藏, 然后脚本中去给这个 item prefab,千万不要只是 cs 脚本中弄一个 public GameObject go 去关联 item prefab, 这样 ab 打包不会把 item prefab 打包进去.


Android播放音效延迟优化


Android 合并后的 AndroidManifest.xml

打包后, 在路径: %PROJECT%\Temp\gradleOut\build\intermediates\merged_manifests\release\AndroidManifest.xml 可以找到


分辨率问题,pc、ios 相同,但与Android不同

  • 设置 canvas 中 的 Canvas Scalar

UI 分辨率

当前 (2020.1) 市场上大部分的手机是 9:16 分辨率比例, 分辨率一般设计为 720x1280

目前跨高比最小的是 iPhone X, 分辨率比例为 1125x2436, 设计的图片最大高度 x = 1560

  • 16:9 分辨率
    • 1280 x 720
    • 1920 x 1080 (full hd)
    • 2560 x 1440 (2k)
    • 3840 x 2160 (4k)

安全区域 SafeArea


Ios : try disabling strip engine code 报错

参考链接:http://www.cnblogs.com/zhaoqingqing/p/6080075.html

在Player Setting – Other Setting,去掉勾选 Strip Engine


Enable Bitcode 报错

打 debug (build setting)包默认 enable bitcode 是 on的,关掉即可

相关链接:https://forum.unity.com/threads/set-enable-bitcode-default-value-when-building-for-ios.353236/

如果我们的工程需要支持bitcode,则必要要求所有的引入的第三方库都支持bitcode

http://www.cocoachina.com/ios/20150818/13078.html


粒子特效 不受深度影响需求

项目中有个需求就是 特效粒子 不需要手 深度测试 的影响, 要总是通过深度测试

默认的 透明shader 是受 深度测试 影响, 虽然不写入深度.

解决方案很简单, 深度测试 总是通过就行了

1
ZTest Always Cull Off ZWrite Off

编辑器日志

位于 C:\Users\%USER%\AppData\Local\Unity\Editor\Editor.log

也可以右键 console 打开

编辑器打开时都是不可编辑, 应该是该进程拿着文件的句柄, 必须关掉编辑器才可以 编辑 这个而文件.


去掉 Android 初次启动 授权弹窗

去掉安装 apk 后启动弹的授权 照片, 媒体内容和文件 提示. 在使用到的时候动态申请.

player settings -> other settings -> wirte permission, 选择 internal 就不会有授权提示, 选择 external 则会有授权提示.

至于为什么, 还没完全搞明白.

write permission 看出好像是在 AndroidManifest.xml 中加了 android.permission.WRITE_EXTERNAL_STORAGE 写外部存储 的权限. 但是在 选择 internal 的情况下, 在 AndroidManifest.xml 中加这个 写外部存储 的权限, 不会有授权提示. 从 apk 反编译出来的 AndroidManifest.xml 中也是有这个权限. so, 搞不懂

网上了解到的说这个授权提示是 android.permission.READ_EXTERNAL_STORAGE 读外部存储 的权限引起的. 实际测试中在 AndroidManifest.xml 去掉了这个权限, 选择了 external, 依旧会有授权提示. 从 apk 反编译出来的 AndroidManifest.xml 也是没有这个权限.

综上实测结论: 要干掉这个授权, write permission 就必须选择 internal, 至于 AndroidManifest.xml 中可以随意添加.


优化包体大小

Android

  1. 开启 Android 混淆.
  2. 开启 代码剥离. https://docs.unity3d.com/Manual/ManagedCodeStripping.html

csharp

同步锁

使用锁

1
2
3
lock(mLockTcp) {
// ...
}

锁定将被释放, lock本质上是:

1
2
3
4
5
6
Monitor.Enter(lockObj);
try {
// ...
} finally {
Monitor.Exit(lockObj);
}

所以不用担心 lock 块内异常.


mac 平台 vscode 报错 .NETFramework not found

vscode 控制台报错: .NETFramework not found, 解决办法:

参考:

  1. 下载 mono 最新版的 mono. 传送门: https://www.mono-project.com/download/stable/

  2. 配置 vscode 的 omnisharp 使用全局的 mono


mac 环境下 多开 unity

  1. 新建一个可执行 sh, 内容如下

    1
    open -n /Applications/Unity2018.4.15f1/Unity.app
    • 然后双击即可多开了.

ugui 对齐方式

三角形就是对齐标记.

  1. 上下都对齐底部, 左边对齐左边, 右边对齐右边.

    • 1 的间距是 固定的, 不会随着屏幕左右拉伸和变化, 白色图片的 宽度 会随着宽度的变化而变化, 也就是图片的 宽 是 拉伸的
    • 2 的间距是 变化的, 随着屏幕的上下拉伸而变化, 白色图片的 高度 不会随着宽度的变化而变化, 也就是图片的 高 是 固定的

预制件编辑模式

双击 prefab 可以进入 预制件编辑 模式, 使用 unity 默认的 canvas, 可以修改成自定义的 canvas, 这样编辑所见即运行时所得.

  1. 创建一个 ui 制作的场景 make_ui , 和运行时的一致

  2. make_ui 拖入 edit -> project settings -> editor -> prefab editing environments -> ui environment

  3. done. 测试一下, 先双击 预制件 进入 编辑 模式, 调整分辨率, 如果编辑模式下的 ui 没有刷新, 再双击 预制件 即可.

    • 预制件会 挂在 自定义场景里的第一个 canvas 下.

iOS 横竖屏问题

在 ios player settings 中, default orientation 要设置为 auto rotation

  • 如果 default orientation 选择 非 auto rotation 的选项, 会出现奇怪的旋转问题.

跳帧语法糖

  • 在看 EnhancedScroller 无限列表时看到的语法糖, 在一个协程方法里实现跳帧逻辑

    这样的好处是可以让一些 临时变量内聚到方法里; 如果是使用 Update 函数的话, 则需要将临时变量放到成员变量里

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
        IEnumerator TweenPosition(TweenType tweenType) {
    while (_tweenTimeLeft < time && _tweenStop == TweenStop.none) {
    case TweenType.linear: newPosition = linear(start, end, (_tweenTimeLeft / time)); break;
    ...
    yield return null;
    }
    ...
    }



    ---

    ### ui 图集 - sprite atlas

    - Sprite packer 和 Sprite Atlas 使用总结 - https://blog.csdn.net/weixin_36961960/article/details/86707085
    - Sprite Atlas使用介绍 - https://blog.csdn.net/wealupa/article/details/108216912



    ---

    ### unity hub 激活问题

    添加免费证书时报错: `There was a problem activating a new personal license. Make sure you are logged in, and have internet connection. 错误`

    解决办法, 退出 unity hub, 用管理员身份启动, 然后添加就没问题了

    参考: https://forum.unity.com/threads/there-was-a-problem-activating-a-new-personal-license-make-sure-you-are-logged-in-and-have-intern.1167806/



    ---

    ### unity 国际版下载

    国际版可以破解, 国内版加壳了破解不了

    1. 科学上网 (全局, 一般我用 日本 梯子).

    2. 打开 unity 下载网页: https://unity3d.com/get-unity/download/archive , LTS: https://unity3d.com/unity/qa/lts-releases

    查看网页上 unity hub 的 html 代码, 国际版版本

    - 2020
    - Unity 2020.3.26 - unityhub://2020.3.26f1/7298b473bc1a
    - Unity 2020.3.2 - unityhub://2020.3.2f1/8fd9074bf66c
    - 2019
    - Unity 2019.4.34 - unityhub://2019.4.34f1/6a9faed444f2
    - Unity 2019.4.22 - unityhub://2019.4.22f1/9fdda2fe27ad



    ---

    ### 编辑器失去焦点后停止渲染

    默认时不再后台运行, 修改方法

    ![](https://pic05.wilker.cn/20220201172301-307.webp)



    ---

    ### prefab 的脚本参数修改不能保存到本地

    - 执行一下这个代码即可: `EditorUtility.SetDirty(xxx);`



    ---

    ### Android 环境配置

    - Android environment setup - https://docs.unity3d.com/Manual/android-sdksetup.html



    ---

    #### Android 构建

    - Gradle for Android https://docs.unity3d.com/cn/2019.4/Manual/android-gradle-overview.html



    ---

    #### 更详细的构建日志

    方便查看哪里错误

    - https://blog.csdn.net/u012416928/article/details/47356887

    - 在 gradle 中加入编译参数

    ```json
    allprojects {
    // 加入编译参数
    gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
    options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
    }
    }
    }



    ---

    ### 升级到 2019.4

    1. JDK 8 (OpenJDK version 1.8)
    2. NDK LTS r19
    3. gradle 升级, 创建个原生工程, 导出 Android Studio 工程查看即可



    ---

    ### 价格

    - 选择适合您的方案 - https://store.unity.com/cn/compare-plans



    ---

    ### 解决 预览包问题

    升级引擎后, 在编辑器顶部出现 `PREVIEW PACKAGES IN USE` 的字眼.

    原因是因为旧引擎中使用了某个包是 预览版 的, 在新引擎中已经转为 正式版, 解决办法: *window -> package manager -> advanced*, 点击 *reset packages to defaults*

    ![image-20220427100031477](https://pic05.wilker.cn/20220427100035-604.webp)

    - https://answers.unity.com/questions/1632351/what-is-preview-packages-in-use.html



    ---

    ### UI Toolkit

    - [Unity]浅尝UI Toolkit Runtime - https://zhuanlan.zhihu.com/p/313321005
    - 槽点满满的UIElements/UIToolkit - https://zhuanlan.zhihu.com/p/416575768
    - Unity新的UI系统已经改成传统模式了 - https://www.toutiao.com/w/1733808796898371



    总结: 还是 UGUI 最好用



    ---

    ### unity 文件管理器屏蔽文件夹

    命名文件夹时加上 `~` 结尾即可, 如:

    ![image-20220710131608162](https://pic05.wilker.cn/20220710131611-776.webp)



    ---

    ### csharp 编译器版本

    - https://docs.unity3d.com/2019.4/Documentation/Manual/CSharpCompiler.html

    | **Scripting Runtime Version** | **C# compiler** | **C# language version** |
    | :---------------------------- | :----------------------------------------- | :----------------------------------------------------------- |
    | .NET 4.6 equivalent | [Roslyn](https://github.com/dotnet/roslyn) | [C# 7.3](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-3) |



    ---

    ### 坐标系

    坐标系区分

    ![image-20220730114356372](https://pic05.wilker.cn/20220730114401-945.webp)

    - 拇指指向 x 轴正方形, 食指指向 y 轴正方形, 中指指向 z 轴正方形



    unity 是 左手坐标系, 3ds max 是 右手坐标系

    ![image-20220730114759458](https://pic05.wilker.cn/20220730114803-534.webp)



    ---

    ### 为什么 Android 默认不开硬件加速

    - https://forum.unity.com/threads/android-hardwareaccelerated-is-forced-false-in-all-activities.532786/



    官方解释是 unity 所有的 activity 都不开硬件加速. 如果 packages and webviews 最好是在一个新的 activity 中打开, 并自由开启硬件加速



    ---

    ### 代码修改贴图格式报错

    错误: `Selected texture format 'Unsupported' for platform 'iPhone' is not valid with the current texture type 'Default'.`

    TextureImporterFormat格式指定有问题,ASTC整合了带A的格式。所以代码里都统一成 *ASTC_6x6*了。在新的2020版本里已经没有ASTC_RGBA与ASTC_RGB的区分,都统一到一个接口里了ASTC_*x*,应该是版本过度的问题,unity2019有很多的过渡问题。在2020上面就好很多了

    参考:https://answer.uwa4d.com/question/61f11918d8413e18eb9613cd



    ---

    ### Android 构建工具报错

    错误: `Installed Build Tools revision 33.0.0 is corrupted`

    原因是构建工具使用的最高版本 33.0.0 里面, 没有去修改 d8 为 dx 文件

    (不修改这个将会报错: `android Installed Build Tools revision 32.0.0 is corrupted`)

    1. 将 `%ANDROID_SDK%\build-tools\32.0.0` 目录下的 d8.bat 改成 dx.bat
    2. 将 `%ANDROID_SDK%\build-tools\32.0.0\lib` 目录下的 d8.jar 改成 dx.jar



    ---

    ### 批量打包失败

    - 报错日志

    ```json
    ***Player size statistics***
    Level 0 'Assets/Res/Scenes/scene_main.unity' uses 33.3 KB compressed / 128.8 KB uncompressed.
    Total compressed size 33.4 KB. Total uncompressed size 128.8 KB.
    Opening scene 'Assets/Res/Scenes/scene_room.unity'
    Load scene 'Assets/Res/Scenes/scene_room.unity' time: 0.009500 ms
    Unloading 29 Unused Serialized files (Serialized files now loaded: 0)
    System memory in use before: 232.6 MB.
    System memory in use after: 232.6 MB.

    Unloading 47 unused Assets to reduce memory usage. Loaded Objects now: 3835.
    Total: 10.203400 ms (FindLiveObjects: 0.528900 ms CreateObjectMapping: 0.049000 ms MarkObjects: 9.348000 ms DeleteObjects: 0.276300 ms)

    [00:00:00] Enlighten: Precompute started.
    [00:00:00] Enlighten: Finished 1 Layout Systems job (0.00s execute, 0.00s integrate, 0.00s wallclock)
    [00:00:00] Enlighten: Finished 1 Tetrahedralize Probes job (0.00s execute, 0.00s integrate, 0.01s wallclock)
    [00:00:00] Enlighten: Precompute took 0.015188 seconds.
    Enlighten scene contents: 0 geometries. 0 instances. 0 systems. 0 probe groups. 0 cube maps. Scene is up-to-date.
    [00:00:00] Enlighten: Bake started.
    [PathTracer] Updated environment lighting, hash 2ffa242b7d049f5ac4b5bc7aa18135c6.
    [PathTracer] Common reset.
    [PathTracer] Lightmap reset.
    [PathTracer][LP] Light probes reset.
    [PathTracer] building lightmap data asset.
    [PathTracer] m_Clear = false;
    [PathTracer] building lightmap data asset.
    [00:00:00] Enlighten: Finished 1 Bake Ambient Probe job (0.00s execute, 0.00s integrate, 0.02s wallclock)
    [00:00:00] Enlighten: Finished 1 Reflection System job (0.00s execute, 0.00s integrate, 0.01s wallclock)
    [00:00:00] Enlighten: Finished 1 Bake Runtime job (0.74s execute, 0.00s integrate, 0.76s wallclock)
    [00:00:00] Enlighten: Bake took 0.755905 seconds.
    [PathTracer] building lightmap data asset.
    [PathTracer] Fetching lightmaps for lightmap data asset started.
    [PathTracer] Fetching lightmaps for lightmap data asset finished.
    > Collecting Enlighten data

    Error while rolling data back after failed file move operation from 'E:/a_its/rummy_itc-v5/Temp/UnityTempFile-773f970dc55d51e4e82ca71f63cbc770' to 'C:/Users/its-packer02/AppData/LocalLow/Unity/Caches/GiCache/1c/1caa9e6aaa50a08e21bcf8e4fdc12c2f.LightingData.asset'. Backup is located at 'C:/Users/its-packer02/AppData/LocalLow/Unity/Caches/GiCache/1c/1caa9e6aaa50a08e21bcf8e4fdc12c2f.LightingData.asset.bak'


    Fatal Error! Error while rolling data back after failed file move operation from 'E:/a_its/rummy_itc-v5/Temp/UnityTempFile-773f970dc55d51e4e82ca71f63cbc770' to 'C:/Users/its-packer02/AppData/LocalLow/Unity/Caches/GiCache/1c/1caa9e6aaa50a08e21bcf8e4fdc12c2f.LightingData.asset'. Backup is located at 'C:/Users/its-packer02/AppData/LocalLow/Unity/Caches/GiCache/1c/1caa9e6aaa50a08e21bcf8e4fdc12c2f.LightingData.asset.bak'
    UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTarget)


    Exiting without the bug reporter. Application will terminate with return code 1
  • 可能是因为开了灯光, 导致 batch 模式下打包报错


锯齿问题

官方的后处理插件PostProcessing抗锯齿用法:

  1. 在Package Manager中找到Post Processing并安装
  2. 给相机添加 Post-process Layer
  • TAA

    TAA据说(未考证)是目前业内游戏大厂使用最多,最广泛的抗锯齿。使用运动矢量组合两帧,以确定在何处对前一帧进行采样。在每一帧对屏幕区域内的像素进行一个抖动操作,这样当连续的多个帧的数据混合起来以后,就相当于对每个像素进行了多次采样,他将采样点从单帧分布到多个帧上,使得每一帧并不需要多次采样增加计算量,但TAA往往会盲目地跟随移动物体的运动矢量,从而造成屏幕上的细节模糊不清。
    据说(未考证)大厂基本会自己根据自己的项目写TAA的效果。如果物体运动过快会导致画面糊、残影,性能方面好像各有说辞,3个DrawCalls,这里如果是小团队,建议这几个方案都试试根据项目需求录取吧。

    Post Processing除了抗锯齿之外还提供了很多其他的后处理效果,小伙伴们可以自行百度试试(这应该是TA的事情)。

TAA是一种更先进的抗锯齿技术,它可以将过去的几帧存储在历史缓冲区中,用于更有效的平滑边缘。这种技术可以很有效的在运动中平滑边缘,但是需要开启运动模糊,并且比FXAA更消耗性能。因此建议使用在主机和PC平台使用

注意事项 不支持GLES2平台
要求支持 Shader Model3 Motion Vectors Depth texture

动画制作

  • animator 中的动画触发条件设置时, 默认是会平滑上一个动作和目的动作, 这个会导致不能完整播放目的动作, 需要将这个过渡去掉

    image-20221217113155873


粒子大小缩放

  • 问题描述
    在Unity中调整粒子系统的Scale,怎么改都不起作用,希望达到调整父Particle System的Scale,整个粒子系统做出相应尺寸调整的变化。

  • 解决方法
    粒子系统中有一个属性叫Scaling Mode,

    Scaling Mode:缩放模式,Hierarchy(同时受自己与父节点的缩放影响),Local(自受自己影响),Shape(天塌下来也不缩放)。
    particle system默认设置为Local,并且不允许通过transform修改Scale。

参考: https://blog.csdn.net/qq_41452267/article/details/111571416


平台判断