C#中使用SHBrowseForFolder导出中文文件夹

Unity项目开发笔记(十七)

从业以来,数次踩中编码的坑, 这次又马失前蹄 , 真是事不过三此非彼白.

本来这个小问题不打算拿出来说 , 但是翻看谷歌发现若干年前也有寥寥数人遇到碰到这个问题 ,而且都并没有给出一个可行的解决方案 ,现在问题依然挂在CSDN等地方 , 似乎不会再有人去回答了, 或者其实题主们后面解决了但并没有回头来提供解决方案. 现在由我来”终结此贴”

0x00.使用SHBrowseForFolder选择文件夹

(大段代码来袭 , 不想看可直接拉到底看关键的几行)

底层接口 – 选择文件夹相关

继续阅读“C#中使用SHBrowseForFolder导出中文文件夹”

Unity中HTTP请求永远无法完成

Unity项目开发笔记(十六)

目前产品在Unity端的开发任务已经趋于平稳 , 但是依旧达不到”非常稳定”的状态 , 随着用户量的增加 , 在复杂的PC网络和设备环境下 每次迭代版本都会频频中坑,这不 这次中招的是WWW和UnityWebRequest.

0x00. 基础介绍

我们知道现在的Unity (Mono2.0 + .NET 3.5) 在不增加第三方插件的情况下 有三种HTTP请求方式:

  • WWW – 大家都知道,对于PC平台来说 底层封装了一遍Curl
  • UnityWebRequest – Unity5.0以后新出来的一种方式
  • HttpWebRequest – .net 自带的一种网络请求方式

以上三种请求方式各有优劣:

WWW 主要是封装得比较便捷 , 下载AssetBoundle Texture等比较方便 省了转换和加载的过程.
UnityWebRequest 主要是更加接近于 HttpWebRequest ,但是参数设置又比 HttpWebRequest 省事一点,适用于项目的大批量API实现 , 使用UnityWebRequest 可以比较自由的添加各种网络数据传输方式和格式.
HttpWebRequest .net框架自带 ,属于三种方式中自由度最大的 , 但是缺点也很明显 各种参数设置必须了然于胸 .

继续阅读“Unity中HTTP请求永远无法完成”

iL2CPP下iOS平台的GBK编码

项目开发笔记(十五)

我以为我早已经摸透各种编码,各种开发语言转码早就可以写得666,但是这次填坑真的把人虐得欲罢不能.这次的事情有比较苛刻的前提条件,所以不一定适用于通过搜索找到此文章的各位遇到的类似情况.

先说说项目基本情况:

Client: Unity 5.3.4 (C#开发逻辑,Java OC原生开发支持,iOS下iL2CPP编译模式)
Server: 纯C++开发的服务器,PHP辅助

0x01. 引发的GBK编码问题

这个项目的网络数据的全部中文都是走GBK格式,数据到了客户端在iOS下所有中文均显示乱码.在 PC和Android下正常

关于编码问题有一篇经典文章 – 字符编码笔记:ASCII,Unicode和UTF-8

这个项目是一个超过十年的老项目(我主要负责移动客户端的实现),服务端使用纯c++开发,服务端底层架构和所有模块已经正常运行十年以上.导致遇到很多问题只能是客户端去适应服务端.所以不可能让协调服务端直接修改数据格式.

0x02. 使用I18N.CJK.DLL库

一个被提及最多的GBK格式数据在iOS iL2CPP模式下的转换方案是: 在link.xml中添加配置防止I18N.CJK.DLL被裁剪.配置方式为:

需从Unity安装目录 Editor\Data\Mono\lib\mono\unity 或 Editor\Data\Mono\lib\mono\2.0 两个目录中,拷贝I18N.DLL 和I18N.CJK.DLL到项目目录Asset文件夹下,在Assets根目录下添加link.xml文件,其内容如下:

但是我反复测试,这种方式在我当前的环境下(Unity 5.3.4,iOS,iL2CPP,Mac Pro,iPhone7P)一直是失败的.

继续阅读“iL2CPP下iOS平台的GBK编码”

Unity中如何向Shader传数组

项目开发笔记(十三)

最近使用Shader的时候需要给Shader传递参数,后面发现参数过多(30+个颜色值和10+个纹理),Shader在PC上运行得好好的,但是到某些移动设备上就尿崩,突然发现:

  1. 为什么shader无法往其传递数组呢?
  2. 为什么使用了多个纹理后(例如三星T560),在设备上无法运行正常?

Unity允许通过Material往Shader里传递int,Texture,Color, Vector4等参数,而且不同的移动设备可能支持不同的 Shader Model(SM 1 2 3 4 5),不同的SM版本会限制纹理指令和算术指令的数量使用。参考:High-Level_Shading_Languag。经过测试设备三星T560只能传入8个纹理指令,再增加就会工作不正常。我们不能改变设备显卡对SM的支持,只能通过减少纹理指令和算术指令的方式来兼容它。顺带把如何传入数组的问题也解决了。那怎么做呢?

继续阅读“Unity中如何向Shader传数组”

Unity中实现纹理色块替换

项目开发笔记(十二)

哈,又一年了。在小时候过年总是非常有感觉,也满心期待。长大一点到了17 18岁的阶段,慢慢感觉过年失去味道 慢慢变成形式化,觉得过年传统做的节目都太无聊。又长大一点 到了25 26岁,过着常年背井离乡的生活 反而小时候对过年的期待又回来了,这几年我甚至非常热忱的参与到 杀猪 贴门神 拜天地等活动中…说回正题,我最近遇到一个需求.

一个小需求

对纹理中的指定色块,使用另一个纹理替换,如下图,这个图我们叫它原纹理

继续阅读“Unity中实现纹理色块替换”

Unity项目DLL代码保护方案概述

项目开发笔记(十)

最近真是繁忙,公司项目 业余项目都同步推进中

公司的项目最近略有松散,但是感觉自己也应该做到了称职。按照公司目前的项目开发模式,可以预见未来很长一段时间都会处在一种 改 改 改 改 的节奏中。在这种节奏下 很容易把代码写烂,在很多次产品改需求 催进度的时候 我都时刻暗示自己 不要因为时间紧迫,而生产垃圾代码,不要因为功能变动,而产生过多硬编码,从这种角度来看 可能这种开发模式可以磨练人呢。

业余项目最近也处在最关键的一个阶段,业余项目的一个好处就是 我可以把任意一个地方模块 写成我自己想要的样子,我不用担心任何人破坏我原本的代码思路,我可以无限次重构 直到自己觉得优雅为止。可喜可贺的是,业余的项目终于可以产生收益了 Orz,之前的独立游戏 也有国外渠道愿意推广(太有眼光了),虽然对独立游戏的收益不抱希望。不管这些事情结果如何 都感谢大家的赏识。

好了,我们接下来扯今天要分享的技术内容。针对Unity使用c#脚本编写逻辑的项目,逻辑代码的保护也就是DLL文件的防反编译(Anti-Decompile) 目前市面上还没有一套完整的方案。

一般的防破解思路

在软件保护中 一般分为 客户端软件的保护 和 web软件的保护。客户端软件一般的防破解思路基本都一致,无论是win/OSX/Linux/Android/iOS 还是其他单片机上的软件程序。防破解的做法都是从 静态保护动态保护 两个方面着手。有可能很多其他地方管着两种方式的命名不一样。通俗的叫法应该是 防止静态反编译 防止动态反编译。

静态反编译(Static decompile)

所谓的静态反编译,就是在不调试的情况下根据软件的本体去查看实现逻辑或者原理(Q.普通没代码的软件也可以调试? A.一般无论是什么系统 Win Linux Android OSX iOS,其核心库 – Kernel层中都会带有调试功能的API,即使是在发行版本的操作系统中 这些调试接口也会被保留,而这些调试接口可以调试任意User层的软件,而我们开发的大多都是属于User层的软件。)

举几个例子:

使用Dex2jar工具对安卓安装文件APK进行导出jar,就属于一种针对安卓软件的静态反编译技术,
使用IDA OD等工具对 .exe .dll进行反编译 也算是一种针对win平台软件的静态反编译的行为。
使用JDgui工具对jar进行查看代码,也算是针对Java软件的一种静态反编译行为

继续阅读“Unity项目DLL代码保护方案概述”

Unity中根据资源搜索其在prefab中的引用

项目开发笔记 (九)

今天第二款业余独立游戏终于成功在GooglePlay上发布了,共计花了约1个月多的业余时间(每天下班后)。代码行数刚好1W出头。第一次以付费下载的模式上线,不管能不能卖出去但整个过程都非常有趣 每天都非常高效,思绪缠绕。对比公司的项目,真是效率低下。查看我最近三月的日志 关于公司项目的每天就2-3条信息,真是忍无可忍啊。废话说到这里,最近写了一个Unity中根据资源反查在prefab中引用的工具,今天我扯扯其中的原理。

prefab

预设,类似各种UI编辑器编辑后的输出文件,Unity中几乎任何事物都可以打包成预设,然后通过外部文件的形式再加载进程序里。不过是PNG/JPG等图片图集资源; GameObject Chartater之类的对象资源。

Unity中提供的搜索选项

Unity本身提供了一个资源引用搜索的选项,不过是针对当前Scene进行逐个资源搜索的,使用如图

这个选项并不能满足我们的需求,除了搜索某个资源在那个prefab被引用之外,在项目后期 我们还可能需要删除尚未被引用过的资源。

继续阅读“Unity中根据资源搜索其在prefab中的引用”

Unity中使用Shader裁剪图片

项目开发笔记 (八) – 依旧是一个重复的轮子

之前说我参与了一个比较 “不一样” 的应用开发,我主要负责其中很多涉及Unity调用原生功能的部分,例如个人用户头像需要调用手机相册摄像头获取,GPS,指南针,内嵌浏览器,包括一些流氓功能(天呀)等等。偶尔还会写几个Unity小模块,其中个人用户头像在显示上,产品要求与各种社交软件一样显示为圆形图片。之前已经实现了如何类似很多社交软件一样获取手机照片 – 传送门

Unity加载显示一张图片,然后使用Shader显示为圆形,这是一个重复的轮子了,但是看了大家的分享之后 发现不是在 Android无法正常裁剪 就是在iOS上显示为白板。所以决定把目前项目中用的分享出来。主要原理就是计算指定范围的像素,然后把像素点的alpha设置为0 (每个像素点都有 RGBA 四个属性值)

如图所示,左下角为UV原点,当纹理uv在 1 区域的时候,也就是满足

uv.x < _Radius && uv.y < _Radius

的时候,当点距离中点的长度大于设定的半径的时候,设置像素透明度为0.其他三个小块以此类推。

继续阅读“Unity中使用Shader裁剪图片”

Unity项目中的网络封装

项目开发笔记 (六)

Unity中的网络组件难用得要死,于是我自己使用C#自带的socket封装后实现了一个,代码几乎没有用任何C#的高级特性。所以可读性上应该没任何难度的。这个代码本来是项目中不可对外的,不过现在也无所谓了。刚好之前在群里看到有很多朋友找现成的封装,这个就是了哟。

代码结构

简略说明

数据包头设计成6字节,压缩到最小了,其实可以4字节都OK,不过前面两个标识字节感觉还是有点用的,数据包结构如下:

0 1 2,3 4,5 6,buffLenght
8D 8H 数据包长度信息 消息id 具体消息数据

数据包长度只给了2字节,也就是 0~65535byte,我觉得数据包这个范围已经足够,消息ID也给了两个字节,也就是 ID号的范围为 0~65535 一般中型的网络游戏 不会多到有6W种不同的消息吧?

收发数据我使用了两个子线程去处理(也可以把收发数据全部放到一个子线程中)

剩下的和其他语言的网络封装没任何实际性的差别,大家看代码即懂

代码传送门:https://github.com/recter/Unity-Net

Unity项目中字符过滤

射击游戏项目开发笔记 (五)

字符屏蔽似乎是在我朝才有的东西.这屏蔽那屏蔽的,干脆彻底把Internet变成Local Area Network得了(虽然现在对大部分人来说已经是Local Area Network了).如果说我有什么职业梦想的话,The Great Wall崩塌估计是我唯一的梦想了.

在目前国内游戏的字符屏蔽中,主要是分为:聊天屏蔽(过滤词语) 和 命名屏蔽(过滤词语+过滤特殊标点符号)

过滤词语

首先看以下趣图:

继续阅读“Unity项目中字符过滤”