Unity 接入友盟SDK

友盟游戏统计 SDK 可以很方便的统计一些游戏数据。使用他们的自定义事件,来统计自己项目关心的数据。现在接入 SDK 已经比以前方便了很多,不需要再导出 Android 工程去修改 Java。下面将一步一步详细说明。 要使用友盟 SDK,一共有以下几步 在友盟后面新建应用 在友盟后面建立自定义事件 下载并导入 SDK 调用 SDK 1. 在友盟后面新建应用 首先注册账号,然后进入友盟工作台。↓ https://www.umeng.com/ 然后点击上面的产品,移动统计 ↓ 点击添加应用 ↓ 然后填写应用信息,下面是我随便填的,根据自己的应用信息填写即可(随便填也没关系)↓ 点击注册后,将跳到下面的页面,这里我们只要关注这个 AppKey 即可,其他的不用管。这个 AppKey 会在 Unity 中用到 ↓ 2. 自定义事件 建立好了应用后,就要想好我们想要统计哪些数据。例如,有多少用户点了开始游戏,有多少用户点了 观看广告,有多少用户观看广告结束,等等,这些都可以统计。 所谓的统计,也就是使用自定义的事件名,在不同的地方调用一下友盟的代码。所以接下来我们就建立自己想要统计的数据事件。 在应用页面,点击我们刚才新建的应用 ↓ 然后依次点击 设置 -> 事件 -> 手工添加 ↓ 我们下面先定义一个统计游戏开始的事件,事件 ID 是这个事件的唯一表示,会在 SDK 调用时用到,显示名称是让我们自己知道这个事件是干嘛的。然后点击确定 ↓ 添加完后的事件,会显示在事件列表中。接下来我们再添加一个统计事件,例如游戏结束。↓ 现在我们已经有了两个事件,当然,还可以添加更多,统计更多数据。这里为了演示,就只添加两个。↓ 3. 下载并导入 SDK 建立好了事件,就可以在项目中使用了,首先要将友盟的 SDK 导入工程中。去友盟的 SDK 页面下载 SDK https://developer.umeng.com/sdk/u3d,这里我们下载 Unity3D 的。 下载下来的是一个 ZIP 压缩包,解压后,依次找到里面的 Unity3D -> analytics -> analytics_unit3d_x....

August 16, 2020 · 1 min · 猫猫

简单理解光线追踪

在过去的一个周,读完了《Ray Tracing in One Weekend》并且用Rust完整地实现了文章中的效果。对于经典的光线追踪逻辑,也有了宏观上的理解。 ...

July 11, 2020 · 1 min · 猫猫

Letsencrypt Nginx HTTPS 配置

买了一个域名,一个 VPS,安装好 Nginx,配置了一个博客,或者一个Web服务。在Chrome中访问后,地址栏 不安全 三个字,很是让人不舒服。今天这篇博客,就记录一下如何配置 Nginx 的 HTTPS 重定向。整个过程很简单,一共有三步,域名配置,HTTPS 证书申请,配置 Nginx,下面将详细说明。 域名配置 首先,将自己的域名配置A记录,指向自己的服务器。并且在服务器上装好 Nginx。 安装 Nginx 使用命令 apt-get install nginx HTTPS 证书申请 Ping 一下自己的域名,确定域名已经被解析到自己的VPS。 执行命令 apt-get install letsencrypt 安装 letsencrypt 执行命令 service nginx stop 先将 Nginx 停掉 执行命令 letsencrypt certonly --standalone 进行获取证书流程,根据提示,输入信息,域名,邮箱等 获取证书流程结束后,会生成两个文件,在接下来的的 Nginx 配置中会用到 /etc/letsencrypt/live/imoegirl.com/fullchain.pem /etc/letsencrypt/live/imoegirl.com/privkey.pem 上面的 imoegirl.com 只是举例,这里是你输入的域名 Nginx 配置 执行命令 cd /etc/nginx/conf.d 使用你喜欢的编辑器创建并编辑文件 my.conf (命名无所谓,只要扩展名是.conf) 输入以下内容 server { listen 80; listen [::]:80; server_name imoegirl.com; return 301 https://imoegirl.com$request_uri; } server { listen 443 ssl http2; server_name imoegirl....

July 11, 2020 · 1 min · 猫猫

对比 Rust 和 Python 图片缩放速度

写博客时经常会用到 tinypng 这个网站进行图片压缩,所以今天就想用 Rust 试一下关于图片处理的东西。首先对比了一个 Rust 和 Python 的缩放速度,Rust 使用了 image-rs,Python 使用了 Image 中的 PIL,速度结果如下图。 原图是一张 2.9M,4800x2500 的图片,缩小为 500x260。电脑CPU型号是 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz。使用 release 编译。 > 点击这里查看大图 注意下图中每个图片文件的文件名,标注了 image-rs 中使用的 FilterType 可以发现,除了 image-rs 中的 Nearest 模式比较快之外,其他模式均比 Python 的 PIL 慢,因为 PIL 是C写的。 代码如下 [dependencies] image = "0.23.4" stopwatch = "0.0.7" extern crate image; extern crate stopwatch; use image::RgbImage; use image::DynamicImage; use image::imageops::FilterType; use stopwatch::{Stopwatch}; fn resize_image(){ let origin_image = "1....

April 26, 2020 · 1 min · 猫猫

游戏项目资源管理

在游戏开发的过程中,整个项目的资源管理是很重要的一部分。涉及到与美术、策划等同事的协作,以及资源的打包,和后续运行时资源的更新,加载,卸载,内存管理等方面。规划好资源的的各个目录存放,以及资源的分类,会为后续的开发工作节省不少时间。这一篇博客主要来聊一下到资源的存放问题,而 AssetBundle 打包,以及运行时的更新和资源管理,将在后面的博客中详细说明。 资源类型 一个游戏项目,涉及到的资源主要有 配置数据、图片、模型、材质、Shader、字体、音频、视频、动画Clip、Prefab、Animator Controller、Timeline、场景文件、Lua脚本 等。 关于协作 首先说一下协作问题。在游戏开发的过程中,美术的同学需要将资源直接提交到建立好的项目中的指定目录中,一般来说,提交到哪个目录,是由程序的同学来决定,具体哪个目录,要根据后续的资源打包以及管理等方面决定。美术的同学提交的资源一般就是模型、动画、贴图等。 而配置数据,则通常由策划同学来提交。配置数据的方式有很多种,常用的例如 Excel,有的项目是直接将原始的 Excel 文件放到工程中,而有的是将 Excel 数据转成其他格式再放到项目中。改表由策划同学来着手操作,在配表的过程中,除了数值,可能也会涉及到一些资源路径,例如有一些图片,是要动态加载的,那么路径也就配在某个模块的相关配置表中。而这些路径配在表中的资源,通常也由策划同学根据不同的系统来操作资源的位置。当然,首先会有一个父目录,在这个父目录下,策划的同学可以自由操作资源的位置,然后将资源的路径配置在数据表中。 还有一个很重要的部分是UI,对于UI来说,如果不打图集,放入项目目录中的都是一个一个的散图,则可以由UI部分的同学直接将UI的图提交到指定的UI父目录下,父目录下的子目录,根据不同的模块来划分,共用的同可以放到一个公用的目录中。对于图的移动操作,都要在 Unity 中进行操作,防止 Prefab 上的图片引用丢失。如果UI使用 TexturePacker 这类工具打成一张图集,则可以由程序同学来做,在开发某个模块时,顺便将对应UI的图打成一张图集,原始的UI图就不必放到工程中,放在外部的一个美术的资源目录即可。 资源存放 接下来,就说一下各个资源怎么去划分。在运行时,需要手动加载的资源,一般有下面这些,Prefab、图片、音频、视频、动画Clip、Animator Controller、配置数据 等,Prefab 这个不用多说。而图片,主要是UI上的一些动态的图,例如头像,或者其他一些需要根据数值,来显示不同的图。动画Clip 可以做成动态加载,也可以直接放到动画状态机中,根据实际情况决定。Animator Controller 也要根据情况决定。配置数据一般需要动态加载。而像 Prefab中用到的材质,贴图等,一般不需要我们手动加载,我们只需要加载 Prefab 即可。 这些需要动态加载的资源,我们可以放在一个父目录下,例如这个目录就叫 Prefabs,然后在 Prefabs 下面建立各个子目录,或者多级子目录来存放不同的资源。如下图 上面的图中只是大概划分了一下,每一个目录下,都可以再次建立子目录,子目录下还可以再细分子目录,具体还需要根据实际项目来划分。 上面图中的目录,是用于存放那些我们需要动态加载的资源,还有一些不需要我们动态加载的资源,例如美术同学上传的原始FBX,以及模型使用到的材质,贴图等等。对于这些资源,我们可以再建立一个目录,例如叫做 RawResources。在这个目录下,我们也需要清晰地去划分子目录,要清楚地知道哪一个目录放了什么资源,哪一些 Prefab 会引用这些资源,后面写 Bundle 打包模块时,可能会用得到。 关于 AssetBundle 问题 在打包 AssetBundle 时,Unity是可以自己处理依赖关系,例如我们可以不用管 RawResources 中的东西,只把 Prefabs 目录下的资源打包,而Prefab引用的原始资源,例如贴图,材质等,会自动打进Bundle,不需要我们手动管理。但是这样有一个问题是,对于共用的资源,会造成重复包含。看下面的图 上面的图中,两个 Prefab 引用了同一个材质,而材质,引用了一张贴图。如果我们将 PrefabA 和 PrefabB 分别打成一个Bundle,而让 Unity 自己处理依赖打包关系,那么就会出现 PrefabA 所在的 Bundle 中包含了材质和贴图,而 PrefabB 所在的 Bundle 中,也包含了材质和贴图。这样就造成了 Bundle 文件占用空间变大,在运行时,占用内存变大。...

April 25, 2020 · 1 min · 猫猫

Rust 基础 | 常用集合数据类型

之前用到的 String 类型,并没有那么简单,接下来会聊一下关于 String 更多的一些应用。在说 String 前,需要先学习一下 Vec 这种数据类型,类似于一个动态的数组。然后是 HashMap,一个键对值的数据类型,与其他编程语言中的字典很类似。 Vec Vec<T> 和数组一样,用于存储一系列相同类型的值。但是 Vec 可以动态地插入,删除。首先,是创建一个 Vec,可以使用 Vec::new(),或者使用宏 vec!。要注意的是,只有使用 mut,才能使 Vec 可变,也就是可以插入和删除值。 fn main() { // 在定义时就标明数据类型为 i32 的 Vec let v1: Vec<i32> = Vec::new(); // 在定义时不标明类型,而在首次插入值时,由Rust自动推断 let mut v2 = Vec::new(); // 这里插入了一个 i32 的值,所以Rust推断 v2 为存放 i32 的 Vec v2.push(2); let v3 = vec![1,2,3,4,5]; let v4 = vec!["hello", "rust"]; let mut v5: Vec<String> = vec!["hello".to_string(), "rust".to_string()]; } 向 Vec 有两个操作函数,一个是 push,往里插入值,一个是 pop,往外弹出值,Pop返回的是最后插入的值。看下面的代码...

April 12, 2020 · 3 min · 猫猫

nginx 配置 https 及重定向

将博客放在自己的VPS上,免不了配置 nginx 及 https,如果不配置 https,浏览器上**不安全**那三个字,实在是太刺眼。所以这篇博客,将记录整个折腾过程。 nginx 的安装 https 的证书配置 http 重定向到 https www 重定向到非不带 www 的域名 接下来的操作,都是在 Ubuntu 18.04 版本上进行的。 域名解析的配置 首先要先自己的域名解析到自己的 VPS,需要配置两条A记录,一条是 @,一条是 www,都是指向自己的 VPS IP。 安装 nginx apt install nginx 申请 ssl 证书 这里,我们使用腾讯云免费的证书,访问 https://console.qcloud.com/ssl,然后点击页面上的 申请免费证书,然后填写信息,注意在域名身份认证时,选择 手动DNS验证,然后点击确认申请,根据给出的提示,在自己的域名上配置TXT解析,等待一段时间,解析成功后,下载证书。 下载下来的是一个压缩包,里面有一个 Nginx 目录,这个目录里有两个文件,xxx.crt 和 xxx.key。需要将这两个文件上传到自己的 VPS。放在 /etc/nginx/ssl 这个目录下,如果 ssl 这个目录不存在,就使用命令 mkdir /etc/nginx/ssl 创建目录。 创建网站资源目录 首先创建我们的网站资源目录,假设我们放在 /var/www/imoegirl.com 这个目录下。注意 imoegirl.com 是一个目录,如果不存在,就先使用 mkdir 创建。imoegirl.com 可以换其他名字。 为了测试,我们在 imoegirl.com 这个目录下新建一个 index.html,内容如下 <h1>Hello iMoegirl</h1> 配置 nginx 接下来就是配置 nginx,按下面的步骤进行...

April 12, 2020 · 2 min · 猫猫

Rust 基础 | 枚举、匹配

这篇博客涉及到的知识点有 枚举的定义、Option 枚举、match 语法、if let 语法。 ...

April 5, 2020 · 3 min · 猫猫

Rust 基础 | 结构体

在有类的编程语言中,组织数据的方式可以定义一个类,而在 Rust 中,组织数据的方式,使用 struct。struct 可以定义三种不同的类型,一种是带有字段名字的结构体,一种是没有字段名字的元组结构体,一种是没有任何字段的单元结构体。 定义 struct 带有字段名字的结构体 #[derive(Debug)] struct User { username: String, email: String, active: bool, } fn main() { let user1 = User { username: String::from("fred"), email: String::from("fred@outlook.com"), active: false, }; println!("{:?}", user1); } 注意上面的代码中 #[derive(Debug)],简单理解就是加上这个,可以给我们自定义的结构体添加上可打印的功能,后面就可以使用 println! 来打印出结构体。 上面的代码中定义了一个 User 结构体,里面的每一个字段,前面是字段名,后面是字段的数据类型。在 main 函数中的代码,是创建一个 User 实例。 元组结构体 #[derive(Debug)] struct Color(u8, u8, u8, u8); fn main() { let color = Color(255,255,255,255); println!("{:?}", color); } 上面的代码中,定义了一个元组结构体,用来存储颜色值。 单元结构体 #[derive(Debug)] struct Unit; fn main() { let unit = Unit; println!...

April 2, 2020 · 2 min · 猫猫

Rust 基础 | 引用、切片

在阅读Rust官方教程时,会看到两个词,引用和借用,也就是 References and Borrowing。这里很容易让人混乱,如果了解C/C++这类有指针的语言,则引用很容易理解,但是 Rust 中的借用这个词是什么意思呢?我觉得,在初学 Rust 时,可以忽略这个词,或者就简单理解为,它所涉及到的东西,就是引用,就是一个指针,就可以了,避免陷入进去。所以,接下来我就就聊一聊引用。 什么是引用 简单来说,引用就是一个指针,这个指针指向了某个内存地址。在说所有权时,我们知道,当把一个 String 当作参数传到函数时,它的所有权也就会被移动到函数的参数上,如果在调用完函数时,我们依旧想使用这个 String,则需要将所有权再返回,这样就很麻烦,所以用引用,会方便很多,因为引用,并不会获得这个 String 的所有权。看下面的代码 fn main() { let s1 = String::from("Hello"); print_name(s1); // 下面这一句再访问 s1 就会编译出错,因为 s1 的所有权已经没了 //println!("s1 again: {}", s1); } fn print_string(s: String) { println!("{}", s); } 下面是用引用作为参数 fn main() { let s1 = String::from("Hello"); print_name(s1); println!("s1 again: {}", s1); } fn print_name(s: &String) { println!("{}", s); } 在上面的代码中,我们将参数从 String 改为 &String,这样函数的参数需要的就不是 String 的所有权,而是 String 的引用,所以在函数 print_name 结束时,main 函数中依然可以使用 name。下图是使用引用时的数据状态。...

April 1, 2020 · 2 min · 猫猫