王小兵 2021-09-24T14:46:54+08:00 spencer.wong@hotmail.com Unity 构建 Android Custom Gradle 2021-08-02T00:00:00+08:00 王小兵 https://peakcoder.com/unity/2021/08/02/unity-gradle Unity 2019.3之后的 Gradle Project 包含两个module
1] UnityLibrary
包含Unity runtime 和工程数据,是个 Library moudle,可以嵌入到其他android工程
2] Launcher
包含应用名称icon,是application moudle 启动Unity

Unity Custom 配置
1) baseProjectTemplate.gradle => root/build.gradle
顶层的 build.gradle 用于定义适用于项目中所有模块的构建配置

2) launcherTemplate.gradle => root/launcher/build.gradle
模块级build文件,包含有关如何构建 Android 应用程序(bundling、签名、分包)的说明,依赖于 unityLibrary 项目,输出.apk或者.aab

3) mainTemplate.gradle => root/unityLibrary/build.gradle
模块级build文件,输出.aar文件,一般性操作覆盖这个文件就好

4) gradleTemplate.properties => gradle.properties
gradle 属性文件. 可以在其中配置项目全局 Gradle 设置,如 Gradle 守护程序的最大堆大小

5) proguard-user.txt => proguard-unity.txt
构建系统会应用一组适当的规则以使用其内置的缩减工具(如 R8)

6) LauncherManifest.xml => root/launcher/src/main/AndroidManifest.xml

ant maven gradle 都是 java 的构建工具
ant maven 使用 xml
ant 无法管理依赖,maven 使用xml不够简洁
gradle 使用 groovy 或者 kotlin 语言

]]>
UE4入门Roadmap 2021-06-13T00:00:00+08:00 王小兵 https://peakcoder.com/ue4/2021/06/13/ue4-roadmap 1.UE4介绍

UE4介绍 UE4和Unity对比

2.模板介绍和工程创建

安装UE4 创建工程 模块选择, 编辑器介绍

3.Actor操作

Actor介绍(放置,变换,分组,合并) 常见放置Actor 静态网格物体 BSP画刷模式 Landscape地形系统 草地工具

4.蓝图

蓝图介绍 蓝图快速入门指南(Launchpad) 案例-横版游戏 案例-第一人称控制

5.UMG基础+案例

UI创建和显示 UI组件事件绑定 UMG UI设计快速入门指南

6.物理系统和射线

碰撞事件和触发事件 射线检测系统 APEX可破坏网格 第一人称射击游戏

7.动画系统

时间轴 Matinee Sequencer Composure

8.行为树

行为树介绍 行为树节点 行为树快速入门指南

9.材质系统+案例

材质编辑器 基本材质概念 特殊效果(法线贴图,菲涅尔,自发光,彩色半透明阴影 等) 自定义材质函数

10.Paper2D系统

创建Flipbooks 2D物理和动画 2D图集

11.C++脚本基础

C++与蓝图 标签介绍 案例:第一人称射击教程

–EOF–

]]>
URP Tilt-Shift Effect 2021-05-24T00:00:00+08:00 王小兵 https://peakcoder.com/unity3d/2021/05/24/tilt-shift 使用URP + RenderFeature 实现的 Tilt-Shift 移轴摄影效果。github

以上.

–EOF–

]]>
SSD 移动硬盘格式的坑 2021-04-13T00:00:00+08:00 王小兵 https://peakcoder.com/ssd/2021/04/13/ssd 因为穷,个人 MBP 的硬盘只有256G,故狗东买了一块闪迪 1TSSD 移动硬盘作为辅助存储.

公司用PC,回家 MacBook,初衷是两种OS可以读写. 以下是我在选择硬盘格式时候遇到的一些坑.

1] 一开始使用的 exFAT 格式

因为这格式倆 OS 都可直接读写.但在拷贝一个Unity工程到硬盘的时候,发现在 NTFS 60G 到移动硬盘里变 400 多G了,靠北!我可只有1个T而已啊. 一番google之后发现:32G 以上的 exFAT 格式硬盘默认簇大小128K,即使大小不到1K的文件也要占128K. 又Unity工程文件全是细碎小文件,故膨胀至此.

2] 使用 NTFS

NTFS簇只有4K,应该就不会浪费空间了.在使用Mounty啊之类的软件之后Mac也能写硬盘.似乎..完美了. 但当老夫发现无法在硬盘打开创建Unity工程!提示The project is on case sensitive file system.Case sensitive file systems are not supported at the moment.Please move the project folder to a case insensitive file system. 又一番google,好吧,NTFS是大小写敏感的,只是Win默认关闭了. 在Mac上大小写敏感,而且还关不掉,汗,只能放弃这格式了.

3] 再使用的 exFAT 格式

算了还是使用exFAT吧,因为之前检索发现 exFAT 直接使用4K簇大小,只要容量不超过16T也是可以的.但默认格式化的时候最小簇只能设 64K 微软太恶意了! 能不能把簇改小呢?又双叒叕一番google发现对于系统自带的format命令行格式化程序则没有对exFAT文件系统施加任何人为限制,那么解决方案自然就是:先以管理员身份运行CMD命令提示符,注意空格输入:Format X: /FS:exFAT /Q /A:4096 /Y 即可将任意类型的盘快速格式化为exFAT-4K簇,其中X:为要格式化卷的盘符,/A:参数为自行指定一个簇大小.或者直接使用DiskGenius等第三方软件来格式化为exFAT也是可以的.

似乎又完美了,都可读写,速度也没有太影响.

但天不遂人愿,又有新的问题,因为只能在 NTFS 格式硬盘上创建软连接,所以在 exFAT 格式的盘上,Unity2019package 全都会拷一份到项目内. 这也还好了,因为用Mac APFS 也一直如此,但只会拷贝一次,第二次打开就很快了.但是 WinexFAT 的硬盘,Unity每次都会拷贝!很慢啊,这绝对 Unity bug,太恶心了,但也只能 file a bugUnity 解决了,没啥办法,哎.

以上.

–EOF–

]]>
新应用「晴书」发布 2020-12-24T00:00:00+08:00 王小兵 https://peakcoder.com/%E7%8B%AC%E7%AB%8B%E5%BC%80%E5%8F%91/2020/12/24/new-app

虽说苹果爸爸圣诞放假暂停审核,但还是在平安夜approve了,ready for sale. 欢迎大家下载。

PS: 开发此App的动机之一是为了泡姑娘,估计追不到了…

–EOF–

]]>
Unity3d gradle 编译后处理 2020-12-14T00:00:00+08:00 王小兵 https://peakcoder.com/android/2020/12/14/gradle-copy-file Unity 可以在 Android 目录直接放置 java 源文件,加上自定义 gradle 配置文件,使得接入第三方的 SDK 变得十分优雅。 Unity 使用 gradle 编译,直接导出 apk ,会在 tmp 文件下面先导出名为 gradleOut 的 android studio 工程。 在 as 工程导出后、编译前,可以做一些文件拷贝处理等工作,例如在接入 Firebase SDK 时需要拷贝 json文件到 launcher 目录。 代码入下:

using UnityEditor;
using UnityEditor.Android;
using UnityEngine;
using System.IO;
public class AndroidPostBuildProcessor : IPostGenerateGradleAndroidProject
{
    public int callbackOrder
    {
        get
        {
            return 0;
        }
    }
    void IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject(string path)
    {
        Debug.Log("Bulid path : " + path);
        path = path.Replace("unityLibrary", "launcher");
        var json = path + "/google-services.json";
        File.Copy("Assets/Plugins/Android/google-services.json", json);
    }
}

–EOF–

]]>
Android ANR 2020-10-14T00:00:00+08:00 王小兵 https://peakcoder.com/android/2020/10/14/android-anr ANR全称:Application Not Responding,也就是应用程序无响应。 logcat 定位不到具体哪个线程导致 ANR,可以通过 ANR 日志分析来定位问题。

当app出现ANR时会在data/anr/目录下生成traces.txt日志文件。每次发生ANR时都会删除旧的traces文件,重新创建新文件。Android只保留最后一次发生ANR时的信息。 可以使用adb命令导出traces文件:

adb pull /data/anr/traces.txt

默认导出文件路径在 adb 命令行运行的当前的目录。

一般trace文件顶部的线程即为ANR的原因。

–EOF–

]]>
NavMeshAgent SetDestination Error 2020-06-18T00:00:00+08:00 王小兵 https://peakcoder.com/unity3d/2020/06/18/navmesh-bug 使用 NavMeshAgentSetDestination函数,一直报错 "SetDestination" can only be called on an active agent that has been placed on a NavMesh. 导致寻路失败。

导航网格生成完好,Destination的点使用 NavMesh.SamplePosition 验证过,也定会在可行走区域内。

Debug许久未果,后在Unity Forum找到答案。

If you create a NavMeshAgent and set its position via transform.position=... and then try to SetDestination, it fails because the NavMeshAgent did not recognize the position change and does not know that it already is on the NavMesh. Use NavMeshAgent.Warp instead of transform.position to initialize the position before calling SetDestination.

开始时直接使用transfrom.poistion赋值,agent未识别位置变化,不知道自己已在导航网格之上,可在初始时调用Wrap函数来初始化agent的位置。

示例代码如下:

agent.Warp(tank.BornPosition);

–EOF–

]]>
Unity Tips (#2) 2020-06-08T00:00:00+08:00 王小兵 https://peakcoder.com/unity3d%20tips/2020/06/08/unity-tips-2 使用 ContextMenu Attribute 不运行 Unity, 执行 MonoBehavior 函数 示例代码如下:

[ContextMenu("ResizeDialogueText")]
private void ResizeDialogueTextHeight()
{
	var height = dialogueText.preferredHeight;
	var size = dialogueBgRect.sizeDelta;
	size.y = height + 60f;
	dialogueBgRect.sizeDelta = size;

	var pos = dialogueText.transform.localPosition;
	pos.y = height + 30f;
	dialogueText.transform.localPosition = pos;
}

Diagram

–EOF–

]]>
使用 MaterialPropertyBlock 2020-05-28T00:00:00+08:00 王小兵 https://peakcoder.com/unity3d/2020/05/28/material-property-block 前些天做性能优化使用 Frame Debugger 发现坦克凭空多了很多dc,每一个负重轮都需一个dc,一下多了十几个,同一材质却不能合批,这不合理。 后发现坦克涂装做decal贴图,抓出material设置贴图导致 (在材质上读取设置任何参数都会导致Instanced) 虽然是同一材质,参数也完全相同,只要Instance了,就无法合批。

嗯,使用 MaterailPropertyBlock 可以阻止材质Instance,继而能够合批,有效降低dc数目。

示例代码如下:

private MaterialPropertyBlock decalMPB;

void Start()
{
	decalMPB = new MaterialPropertyBlock();
}

public void SetExclusiveDecoration(string path)
{
	if (allRenderTexDic.Count == 0) 
		InitializeMaterialDic();

	var tankKeyname = tank.ProtoKeyname;
	foreach (var k in allRenderTexDic.Keys.ToList())
	{
		var tex = Resources.Load(path) as Texture;
		if (tex == null) continue;
		
		k.GetPropertyBlock(decalMPB);
		decalMPB.SetTexture("_CMap", tex);
		k.SetPropertyBlock(decalMPB);
		allRenderTexDic[k] = tex;
	}
}

–EOF–

]]>