👋 欢迎来到 LiuYingbo Blog

记录开发、技术和思考

备忘录

虚拟手机验证:hero-sms.com 壁纸网站:https://wallhaven.cc 翻墙软件:https://www.sibker.com/ 图片压缩工具:https://pngquant.org 动漫网站:https://www.agefans.vip ppt模板:https://www.canva.com 图书(电子书):https://singlelogin.me 游戏下载(需翻墙):https://byrut.org/ Unity资源下载: https://unityassetcollection.com/ Mac谷歌跨域浏览器: open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome –args –user-data-dir="/tmp/chrome_dev_test" –disable-web-security

December 2, 2021 · 1 min · LiuYingbo

Unity 小游戏优化

Unity小游戏优化 性能优化主要的4个方向:启动速度,资源加载,内存占用,减少CPU消耗 加快游戏启动速度 构建选项中仅勾选首场景,其他场景用到时再下载 精简首场景物件,尽快渲染让玩家看到游戏首画面 减少代码包体,剔除不必要的插件 减少初始化与首帧逻辑,首场景 Awake / Start / 首次 Update 不要包含过重逻辑 减少代码包体,剔除不必要的插件 CDN 必须开启 Brotli 或 gzip 压缩 优化的目标与标准 目前普通小游戏普遍启动时间为 5~6s, 优化目标首屏启动时间控制在 5~10s 甚至更短。 启动耗时 小游戏启动主要由三部分影响: 首包资源下载 wasm代码下载和编译 引擎初始化与开发者首帧逻辑 首包资源 首包资源(webgl/Build 目录下的 data 文件)主要有以下组成: Unity default resources 文件,引擎默认资源,如 Arial 字体、默认 mesh、纹理等 il2cppmetadata,C#代码使用 il2Cpp 生成 cpp 代码时生成的类、方法等信息 unity builtin_extra,always include 的 shader BuildSettings 中所有 active 的场景 Resources 文件夹中的资源,以及其中引用到的其他资源 全局设置及引用到的资源,例如 splash 图片 wasm代码 生成的 原始代码不超过 30MB 路径:Build/webgl_package/code.unityweb 优化方法: 勾选 Strip Engine Code 设置 Managed Stripping Level 为 High 配置 link.xml 文件告诉 Unity 哪些代码必须保留 使用代码分包工具减少 wasm 首包大小 Unity 2021 以上版本可将 PlayerSettings 中 IL2CPP 选项设置为 SIZE 以减少函数数量 引擎初始化与首帧逻辑 优化建议: ...

March 11, 2026 · 1 min · LiuYingbo

Unity-水流体Shader

水流体Shader Shader "UI/WaterWave" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 // 水波参数 _WaterHeight ("Water Height", Range(0, 1)) = 0.5 _WaveSpeed ("Wave Speed", Float) = 1.0 _WaveFrequency ("Wave Frequency", Float) = 5.0 _WaveAmplitude ("Wave Amplitude", Range(0, 0.1)) = 0.02 _WaveOffset ("Wave Offset", Float) = 0.0 _WaveRange ("Wave Range", Range(0, 0.2)) = 0.05 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask [_ColorMask] Pass { Name "Default" CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" #include "UnityUI.cginc" #pragma multi_compile_local _ UNITY_UI_CLIP_RECT #pragma multi_compile_local _ UNITY_UI_ALPHACLIP struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; }; sampler2D _MainTex; fixed4 _Color; fixed4 _TextureSampleAdd; float4 _ClipRect; float4 _MainTex_ST; float _WaterHeight; float _WaveSpeed; float _WaveFrequency; float _WaveAmplitude; float _WaveOffset; float _WaveRange; v2f vert(appdata_t v) { v2f o; o.worldPosition = v.vertex; o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); o.color = v.color * _Color; return o; } fixed4 frag(v2f i) : SV_Target { // ---------- 水波计算 ---------- float distanceToSurface = abs(i.texcoord.y - _WaterHeight); float wave = 0; float2 waveUV = i.texcoord; if (distanceToSurface < _WaveRange) { float t = _Time.y * _WaveSpeed + _WaveOffset; float x = i.texcoord.x * _WaveFrequency; float w1 = sin(x + t) * _WaveAmplitude; float w2 = sin(x * 1.5 + t * 0.8) * _WaveAmplitude * 0.6; wave = w1 + w2; float influence = smoothstep(_WaveRange, 0, distanceToSurface); waveUV.y += wave * influence; } half4 col = tex2D(_MainTex, waveUV); // ---------- 水面软裁剪(无锯齿核心) ---------- float waterLevel = saturate(_WaterHeight + wave); // 自适应软边缘(跟分辨率有关) float edge = fwidth(i.texcoord.y) * 2.0; float alphaMask = smoothstep( waterLevel + edge, waterLevel - edge, i.texcoord.y ); col.a *= alphaMask; // ---------- 水面高光 ---------- float surfaceDist = abs(i.texcoord.y - waterLevel); float highlight = smoothstep(0.03, 0.0, surfaceDist); col.rgb += highlight * 0.15; // ---------- UI 标准处理 ---------- col += _TextureSampleAdd; col *= i.color; #ifdef UNITY_UI_CLIP_RECT col.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect); #endif #ifdef UNITY_UI_ALPHACLIP clip(col.a - 0.001); #endif return col; } ENDCG } } Fallback "UI/Default" }

February 8, 2026 · 2 min · LiuYingbo

Unity-Dots

Dots前置 Dots简介 DOTS是什么 Data-Oriented Technology Stack(面向数据的技术栈) The C# job system The Burst compiler Unity Mathematics Unity Collections Entities ( Entity-Component System) Entities.Graphics ( Hybird Renderer ) Netcode Physics Animation (WIP) Audio(WIP) DOTS可以应用到哪些地方? 具有大世界流式加载的游戏 具有复杂的大规模模拟的游戏 具有多种网络类型的多人联线游戏 具有需要客户端模拟预测的网络游戏,如射击游戏 为什么我们需要DOTS? CPU与Memory的速度发展不均衡以及带宽限制 添加高速的缓存Cache内存层级结构去弥补 摩尔定律的延续与现代CPU设计。 越来越好的工艺 越来越多的核 分工越来越细的处理单元与存储 SIMD/SIMT 3.并行编程的发展 OpenMP TBB—-Intel Threading Building Blocks CUDA–Compute Unified Divice Architecture OpencL-—Open Computing Language MPI/OpenMPI-—Message Passing Interface OOD ==>DOD 面向数据设计(ODO) 程序设计方法 Instructional Programming 指令化编程 Functional Programming 函数化编程 ...

April 10, 2023 · 1 min · LiuYingbo

Unity-性能优化

一个B站UP主的教程,后半部分涉及到很多urp源码修改暂时还看不懂,只记录了前半部的内容 视频地址:https://www.bilibili.com/video/BV1AL4y1b75c/?spm_id_from=333.999.0.0&vd_source=4c7b49a270731b8ec068bfb156c5af6a 资源优化 Unity资源检测工具 Asset Checker 用于本地资源检测,帮助开发者尽早发现资源文件中存在的问题 支持所有版本的Unity项目 不依赖Unity Editor,无需安装绿色运行 检测速度极快,可在UPR中查阅检测结果 支持命令行模式,可与CI/CD工具轻松集成,实现自动化检测 规则库持续更新 支持AssetBundle冗余检测 支持静态代码分析 Asset Checker 官方教程地址(包含工具下载地址) Audio导入设置检查与优化 根据平台选择合理的音频设置,原始音频资源尽量采用未压缩WAV格式 移动平台对音乐音效统一采用单通道设置(Force to Mono),并将音乐采样频率设置为22050Hz 一般勾选了强制单声道之后也要勾选Normalize选项,这样引擎内部会选择最合适的方式来强行转换单声道。 移动平台大多数声音尽量采用Vorbis压缩设置,IOS平台或不打算循环的声音可以选择MP3格式,对于简短、常用的音效,可以采用解码速度快的ADPCM格式(PCM为未压缩格式) 音频片段加载类型说明 简短音效导入后小于200kb,采用Decompress on Load模式 对于复杂音效,大小大于200kb,长度超过5秒的音效采用Compressed In Memory模式 对于长度较长的音效或背景音乐则采用Streaming模式,虽然会有CPU额外开销,但节省内存并且加载不卡顿 当实现静音功能时,不要简单的将音量设置为0,应销毁音频(AudioSource)组件,将音频从内存中卸载。 优化前后真机对比(Android) Apk包体由原来的560.7M下降到544.6M Audio部分的内存由76.1M下降到6.9M CPU开销由2.5%左右上升到5%左右,这是由于部分音频资源才用了Streaming模式加载 Model导入设置检查与优化 DCC中模型导出 Unity 支持多种标准和专有模型文件格式(DCC)。Unity 内部使用 .fbx 文件格式作为其导入链。最佳做法尽可能使用 .fbx 文件格式,并且不应在生产中使用专有文件格式。 优化原始导入模型文件,删除不需要的数据 统一单位 导出的网格必须是多边形拓扑网格,不能是贝塞尔曲线、样条曲线、NURBS、NURMS、细分曲面等 烘培Deformers,在导出之前,确保变形体被烘培到网格模型上,如骨骼形变烘培到蒙皮权重上 不建议模型使用到的纹理随模型导出 如果你需要导入blend shape normals,必须要指定光滑组smooth groups DCC导出面板设置, 不建议携带场景信息导出,如不建议导出摄像机、灯光、材质等信息,因为这些的信息与Unity内默认都不同。除非你自己为某DCC做过自定义导出插件。 Unity模型导入流程 原始模型文件对性能的影响点 最小化面数,不要使用微三角形,分布尽量均匀 合理的网络拓扑和平滑组 尽量少的使用材质个数 尽可能少的使用蒙皮网格 尽可能少的骨骼数量 FK与IK节点没分离,IK节点没删除 模型优化 尽可能的将网格合并到一起,() 尽可能使用共享材质 不要使用网格碰撞体 不必要不要开启网格读写 使用合理的LOD级别 Skin Weights受骨骼影响个过多 合理压缩网格 不需要rigs和BlendShapes尽量关闭 如果可能,禁用法线或切线 多套模型 资源检查报告 FBX部分问题解读 ...

March 5, 2023 · 9 min · LiuYingbo

Unity-移动端打包记录(持续更新)

Android Gradle版本问题 本地打包的大部分错误都是因为这个问题,这是因为笔者接入的SDK自定义了gradle的插件版本,这个再unity本身其实已经定义过了,但是自己是可以通过修改build.gradle进行修改的。查看unity本身gradel的插件版本的路径是:Editor\Data\PlaybackEngines\AndroidPlayer\Tools\GradleTemplates\baseProjectTemplate.gradle,以2019.4.28版本为例,里面代码为: allprojects { buildscript { *** dependencies { *** classpath 'com.android.tools.build:gradle:3.4.0' **BUILD_SCRIPT_DEPS** } } *** } *** 如上图,可以看到插件版本为3.4.0,如果unity里本身修改了baseProjectTemplate.gradle就按照修改后的来,这个文件夹内所有的gradle和properties都是默认的,如果程序里修改就按照程序里的来。修改的方法在Editor–>ProjectSettings–>Player–>Publishing Settings,如下图所示: 如上图,其实就是对应编辑器文件夹下的gradle文件,如果打勾就会在pluging/Android文件夹下生成对应的文件,就可以直接修改,不再按照unity默认的来,就可以修改配置了。 经过上面的介绍已经知道如何查看并修改unity的gradle插件版本,下面就是修改对应的gradle版本。首先打开Editor–>Preference–>External Tools就可以看到Android的打包环境配置。 2020版本以后的Unity是默认路径下就自己配置好环境,选择默认就可以,但是依旧可能会存在环境不存在或者版本不对,所以可以自己配置,这样修改也方便。这里有需要特别关注的一点也是大部分打包失败的原因,就是gradle的版本和对应的插件版本是有对照关系的,必须对照上才能正常打包。对应关系如下图: 只要配置好对应的关系就行了。 APK+obb分包无法运行问题 因为Google商店对上传的apk有内存限制,要求是100M以内,这里推荐使用的是APk+OBB进行分包,根据最新的要求是要求使用AAB包,这里先介绍APK+OBB的分包遇到的问题。 分开打包的方法是Editor–>ProjectSettings–>Player–>Publishing Settings里,勾选上最下面的Split Application Binary。 这个是可以代码控制的: PlayerSettings.Android.useAPKExpansionFiles = true; 分包后如何在手机上运行呢,这里只需要安装分包后的APK,然后在手机上运行,发现第一次运行不成功,这是因为资源都在OBB中,所以无法正常运行,这里只需要吧自己的OBB改好名字放在对应的文件夹就行了。然后再运行就可以了。 文件夹地址:手机目录\Android\obb"APP的包名” OBB文件的名字: main.安卓内部版本号.APP包名.obb (举例:main.102.com.XXX.XXX.XXX.obb) 华为手机出现水滴屏无法适配的问题 笔者的项目要求手机在遇到水滴屏或者刘海屏的时候,上面显示黑条不进行渲染就可以,笔者查了一下unity的设置方法,发现只需要不勾选Editor–>ProjectSettings–>Resolution and Presentation里的Render outside safe area即可。 但是笔者发现APP在某个测试的华为手机上依旧渲染了,最后发现是接入的SDK里设置了华为手机的屏幕渲染。在华为手机Android8.0的适配方案是在AndroidManfiest里面添加下面的话即可,笔者发现接入的SDK设置了这个,于是去掉就没有问题了。 <meta-data android:name="android.notch_support" android:value="true"/> 这里列举一下小米手机的适配方案是: <meta-data android:name="notch.config" android:value="portrait|landscape"/> 华为荣耀系列闪退 2023-02-22 14:34:08.234 12494-12494 AndroidRuntime pid-12494 E FATAL EXCEPTION: main Process: com.xg.legendofliqi, PID: 12494 java.lang.Error: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Version '2021.3.1f1c1 (0cb3bd085a01)', Build type 'Release', Scripting Backend 'il2cpp', CPU 'arm64-v8a' Build fingerprint: 'HONOR/FNE-AN00/HNFNE:12/HONORFNE-AN00/6.1.0.178C00:user/release-keys' Revision: '0' ABI: 'arm64' Timestamp: 2023-02-22 14:34:03+0800 pid: 12494, tid: 12580, name: Thread-9 >>> com.xg.legendofliqi <<< uid: 10052 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x100000071 x0 0000000000000000 x1 0000000000000001 x2 00000075508123b8 x3 0000000000000001 x4 ffffffffffffffff x5 00000075b0c07208 x6 0000000000000000 x7 0000000000000000 x8 0000000000000000 x9 0000000000010cc0 x10 0000000000000000 x11 0000000000000000 x12 0000000000000a80 x13 0000000000000000 x14 431bde82d7b634db x15 0000000100000001 x16 00000076512d3bb8 x17 00000079a4bec168 x18 000000753f646000 x19 0000000000000000 x20 ffffffffffffffff x21 000000777bdb99b0 x22 00000075b0bf2400 x23 00000075508123f8 x24 00000075b0bf2278 x25 0000007550812740 x26 00000075b0be3c10 x27 00000075508128d8 x28 000000761018e900 x29 0000007550812360 sp 0000007550812360 lr 0000007650856d54 pc 00000075513c0730 backtrace: #00 pc 00000000000a9730 /vendor/lib64/hw/vulkan.adreno.so (qglinternal::vkWaitForFences(VkDevice_T*, unsigned int, VkFence_T* const*, unsigned int, unsigned long)+184) (BuildId: 5839fbcc06912e00a12c12db16914158) #01 pc 0000000000781d50 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #02 pc 000000000075f864 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #03 pc 0000000000781260 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #04 pc 0000000000760a08 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #05 pc 000000000076ec38 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #06 pc 0000000000758714 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #07 pc 0000000000750994 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #08 pc 000000000075a9f4 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #09 pc 00000000006a71d4 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #10 pc 00000000007508fc /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #11 pc 00000000006a8f00 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #12 pc 00000000008a5e50 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #13 pc 00000000008a7c18 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) 2023-02-22 14:34:08.234 12494-12494 AndroidRuntime pid-12494 E #14 pc 000000000089f4a8 /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #15 pc 000000000033070c /data/app/~~WnZeyO9JhYbG9GbePcBSVg==/com.xg.legendofliqi-qTxoOJYDPp2KJv3Yr8KuPA==/lib/arm64/libunity.so (BuildId: 73ee1682c58347912d029a798789df982330b7d9) #16 pc 00000000000b3ea0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264) (BuildId: 82e5b2ff86b193c94139353a92c4af29) #17 pc 0000000000053880 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 82e5b2ff86b193c94139353a92c4af29) at vulkan.qglinternal::vkWaitForFences(VkDevice_T*, unsigned int, VkFence_T* const*, unsigned int, unsigned long)(vkWaitForFences:184) at libunity.0x781d50(Native Method) at libunity.0x75f864(Native Method) at libunity.0x781260(Native Method) at libunity.0x760a08(Native Method) at libunity.0x76ec38(Native Method) at libunity.0x758714(Native Method) at libunity.0x750994(Native Method) at libunity.0x75a9f4(Native Method) at libunity.0x6a71d4(Native Method) at libunity.0x7508fc(Native Method) at libunity.0x6a8f00(Native Method) at libunity.0x8a5e50(Native Method) at libunity.0x8a7c18(Native Method) at libunity.0x89f4a8(Native Method) at libunity.0x33070c(Native Method) at libc.__pthread_start(void*)(__pthread_start:264) at libc.__start_thread(__start_thread:64) 打包版本是Unity 2021.3.1f1c1,有使用最新版Unity打包但还是一样的空包一样会闪退 ...

March 5, 2023 · 3 min · LiuYingbo

C# LINQ

LINQ 是 Language INtegrated Query 单词的首字母缩写,翻译过来是语言集成查询。它为查询跨各种数据源和格式的数据提供了一致的模型,所以叫集成查询。由于这种查询并没有制造新的语言而只是在现有的语言基础上来实现,所以叫语言集成查询。 基础 在 C# 中,从功能上 LINQ 可分为两类:LINQ to Object 和 LINQ to XML;从语法上 LINQ 可以分为 LINQ to Object 和 LINQ 扩展方法 纠正: 从功能上 LINQ 可分为两类: LINQ to Object,查询内存集合,直接把查询编译成 .NET 代码执行。 LINQ to Provider,查询自定义数据源,由开发者提供相应数据源的 Provider 并翻译和执行自定义查询,如 XML、JSON 等都可以作为 Provider 对应的数据源,数据源对应的 LINQ 查询叫 LINQ to <数据源>,比如:LINQ to XML。 从语法上 LINQ 可以分为: SQL风格:语法和 SQL 相似,部分复杂查询用 SQL 风格语义会更清晰明了,比如 SelectMany 和 Join 查询。SQL 风格的可读性有绝对优势,但不支持全部标准 LINQ 函数,不支持自定义函数。纯粹的语法糖。 函数风格:以 C# 扩展方法的方式实现,扩展方法即可以是标准库提供的也可以是自己实现的,完全的原生编程风格,编译后的代码都是函数调用。支持全部标准 LINQ 函数和任何自定义函数。随着查询复杂度的提高,可读性不如 SQL 风格。 感谢 @coredx 的纠正。 ...

November 24, 2022 · 12 min · LiuYingbo

Unity-移动平台相关Java语法

简单了解Java语法 环境 Java环境:www.baidu.com 写Java编辑器推荐是IDEA 但是我们是Unity导出的Android项目所以还是用AndroidStudio 变量 Java中的有符号整型 //1.byte(1个字节,8位,-2^7 ~ 2^7 - 1,-128 ~ 127) System.out.println("byte位数" + Byte.SIZE); System.out.println("byte最大值" + Byte.MAX_VALUE); System.out.println("byte最小值" + Byte.MIN_VALUE); //2.short(2个字节,16位,-2^15 ~ 2^15 - 1,-32768 ~ 32767) System.out.println("short位数" + Short.SIZE); System.out.println("short最大值" + Short.MAX_VALUE); System.out.println("short最小值" + Short.MIN_VALUE); //3.int(4个字节,32位,-2^31 ~ 2^31 - 1,-2,147,483,648 ~ 2,147,483,647) System.out.println("int位数" + Integer.SIZE); System.out.println("int最大值" + Integer.MAX_VALUE); System.out.println("int最小值" + Integer.MIN_VALUE); //4.long(8个字节,64位,-2^63 ~ 2^63 - 1,9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807) System.out.println("long位数" + Long.SIZE); System.out.println("long最大值" + Long.MAX_VALUE); System.out.println("long最小值" + Long.MIN_VALUE); //注意:Java最初设计中没有无符号类型 //Java 8中添加了一些和无符号类型有关的一些方法(但是一般使用较少) Java中的浮点型 //1.float(4个字节,32位) System.out.println("float位数" + Float.SIZE); System.out.println("float最大值" + Float.MAX_VALUE); System.out.println("float最小值" + Float.MIN_VALUE); float f = .5f; System.out.println(f); f = 1.f; System.out.println(f); //2.double(8个字节,64位) System.out.println("double位数" + Double.SIZE); System.out.println("double最大值" + Double.MAX_VALUE); System.out.println("double最小值" + Double.MIN_VALUE); double d = 1.5; Java中的其它类型 //1.boolean(单个boolean在编译时使用int类型,这时4个字节;boolean数组时,编译时用字节数组,所以占1个字节) //默认值是false boolean b0 = true; boolean[] bs; //2.char(2个字节,16位) System.out.println("char位数" + Character.SIZE); char c = 'A'; System.out.println(c); //3.String(根据字符串长度而定) String str = "123"; System.out.println(str); Java中的常量 关键字:final ...

November 24, 2022 · 6 min · LiuYingbo

Unity-移动平台相关Android

Android发布流程 Unity2019及以上 发布Android准备工作 通过UnityHub安装Android平台相关工具 1.Android构建支持 2.Android SDK(安卓软件开发工具包)、NDKTools(本地开发工具包) 3.OpenJDK(Java开发工具包) 注意:Unity支持Android 5.1及以上版本 Unity2019以下版本 1.Android构建支持工具安装(Unity提供下载,安装时需要关闭Unity) 2.JDK(Java开发工具包)(网络下载) JDK 必须是版本 8 https://www.oracle.com/java/technologies/downloads/#jdk18-windows 3.NDK (本地开发工具包)(网络下载)NDK 版本必须是 Unity2018——r16b, Unity2017——r13d 注意:NDK是可选的工具,如果之后要发il2cpp的应用程序,那么NDK是必须的,如果是Mono可以不使用它 https://blog.csdn.net/momo0853/article/details/73898066 https://developer.android.google.cn/ndk/downloads/#lts-downloads 4.Android SDK(安卓软件开发工具包)(网络下载或通过AndroidStudio下载) 建议通过AndroidStudio下载 https://developer.android.com/studio 安装AndroidStudio后 通过它来安装AndroidSDK 5.Java环境变量配置 我的电脑——>系统属性——>查找——>系统环境变量——>环境变量 5-1:JAVA_HOME: 变量值为JDK在你电脑上的安装路径 安装好后可以利用%JAVA_HOME%作为JDK安装目录的统一引用路径 5-2:Path: 编辑Path属性,在原变量后追加 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin 5-3:CLASSPATH: 变量值为 .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar 发布前必修改的设置 在File —— Build Setting —— Player Setting中修改 1.公司名 2.游戏项目名 3.版本号 4.默认图标 5.Other Settings —— Package Name(必须修改设置) 6.Other Settings —— Minimum APILevel Unity发布参数 Build Settings 参数 Texture Compression 纹理压缩 设置发布后的纹理压缩格式 ...

September 1, 2022 · 9 min · LiuYingbo

Unity-网络开发(三)

大小端模式 什么是大小端模式 大端模式 是指数据的高字节保存在内存的低地址中 而数据的低字节保存在内存的高地址中 这样的存储模式有点儿类似于把数据当作字符串顺序处理 地址由小向大增加,数据从高位往低位放 符合人类的阅读习惯 小端模式 是指数据的高字节保存在内存的高地址中 而数据的低字节保存在内存的低地址中 举例说明 十六进制数据0x11223344 大端模式存储 11 22 33 44 0 1 2 3 低地址——>高地址 小端模式存储 44 33 22 11 0 1 2 3 低地址——>高地址 为什么有大小端模式 大小端模式其实是计算机硬件的两种存储数据的方式 我们也可以称大小端模式为 大小端字节序 对于我们来说,大端字节序阅读起来更加方便,为什么还要有小端字节序呢? 原因是,计算机电路先处理低位字节,效率比较高 计算机处理字节序的时候,不知道什么是高位字节,什么是低位字节 它只知道按顺序读取字节,先读第一个字节,再读第二个字节 如果是大端字节序,先读到的就是高位字节,后读到的就是低位字节 小端字节序正好相反 因为计算机都是从低位开始的 所以,计算机的内部处理都是小端字节序 但是,我们人类的读写习惯还是大端字节序 所以,除了计算机的内部处理 其它场合几乎都是大端字节序,比如网络传输和文件存储 一般情况下,操作系统都是小端模式,而通讯协议都是大端模式 但是具体的模式,还是要根据硬件平台,开发语言来决定 主机不同,开发语言不同 可能采用的大小端模式也会不一致 大小端模式对于我们的影响 只有读取的时候,才必须区分大小端字节序,其它情况都不用考虑 因此对于我们来说,在网络传输当中我们传输的是字节数组 那么我们在收到字节数组进行解析时,就需要考虑大小端的问题 虽然TCP/IP协议规定了在网络上必须采用网络字节顺序(大端模式) 但是具体传输时采用哪种模式,都是根据前后端语言、设备决定的 在进行网络通讯时,前后端语言不同时,可能会造成大小端不统一 一般情况下 C# 和 Java/Erlang/AS3 通讯需要进行大小端转换 因为C#是小端模式 Java/Erlang/AS3是大端模式 C# 与 C++通信不需要特殊处理 他们都是小端模式 大小端转换 判断是大小端哪种模式 print(“是否是小端模式:” + BitConverter.IsLittleEndian); ...

August 14, 2022 · 3 min · LiuYingbo