自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(82)
  • 收藏
  • 关注

原创 CLR via C#(三)垃圾回收

每个程序运行都需要各种资源,如文件、内存缓冲区、数据库等。要使用这些资源,就必须为代表资源的类型分配内存。

2023-09-17 22:20:44 486

原创 CLR via C#(二)线程栈与托管堆

运行时要求每个类型最终都要从Equals()ToString()GetType()thisFinalize()CLR要求所有的对象都用new操作符创建。在这期间,newnew:指非静态字段,是属于对象的。与之相对的静态字段是属于类的。:每个对象都是一个类型的实例,而每个类型都由一个Type类型的实例来表示。类型对象指针就是指向该Type实例的指针。当然,Type类型对象本身也是一个类型对象的实例,它的类型对象指针指向了它自己。:可以简单理解为一个指向“同步块”的指针,拥有这个同步块的对象可以支持线程同步。

2023-07-21 00:06:22 349

原创 CLR via C#(一)CLR的执行模型

CLR全称Common Language Runtime,即公共语言运行时。它可以为所有面向CLR的语言提供运行时的内存管理、程序集加载、安全性、异常处理和线程同步等功能。

2023-06-04 23:52:22 824

原创 计算机网络——UDP与TCP

运输层在整个网络体系结构中位于面向通信部分的最高层,同时也是用户功能中的最低层。它提供的是应用进程间的逻辑通信。所谓逻辑通信,指的是它屏蔽了下层网络的细节,使得进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道,但实际上并不存在这样一个信道。运输层有两种不同的运输协议:面向连接的TCP协议和无连接的UDP协议。当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的(只提供尽最大努力服务),但这种逻辑通信信道就相当于一条全双工的可靠信道。但当运输层采用无连接的UDP协议时,这种逻辑通信

2023-01-20 09:17:57 3464 1

原创 设计模式简要汇总

开闭原则:一个软件实体(类、模块、函数)应该对扩展开放,对修改关闭。依赖倒置原则:高层模块不应该依赖底层模块,它们都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。里氏替换原则:派生类(子类)对象可以在程序中代替其基类(超类)对象。单一职责原则:一个类或者模块只负责完成一个职责(或者功能)。接口隔离原则:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。合成复用原则:尽量使用对象组合,而不是继承来达到复用的目的。迪米特原则:每个软件单位对其他单位都具有最少知

2023-01-16 12:21:58 748

原创 C# LINQ查询

LINQ是Language-Integrated Query的缩写,它可以视为一组语言和框架特性的集合。LINQ可以对本地对象集合或远程数据源进行结构化的类型安全的查询操作。LINQ支持查询任何实现了接口的集合类型,无论是数组、列表还是XML DOM,乃至SQL Server数据库中的数据表这种远程数据源都可以查询。LINQ具有和这两大优点。

2023-01-16 09:31:44 3176

原创 C#中的多线程(一)

CPU(中央处理器)或内核/核心是实际执行程序的硬件单元。许多现代CPU都支持同时多线程(Intel称之为超线程),即使一个CPU能表现为多个「虚拟」CPU。进程(process)是某个程序当前正在执行的实例。操作系统的一项基本功能就是管理进程。每个进程都包含一个或多个线程。线程(thread)是操作系统能够进行运算调度的最小单位,也是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流。单线程程序的进程仅包含一个线程;多线程程序则包含多个。在多线程程序中运行具有正确行为的代码,就说代码是

2023-01-05 10:51:25 970

原创 Shader Graph(一)基本使用

Unity Shader Graph学习笔记

2022-12-27 10:04:12 3329 1

原创 Unity Animancer插件(三)运动

Animancer的根运动系统与原生的工作原理完全相同,但我们可以通过继承Transition类型或实现接口,来将额外的数据与动画绑定,从而更方便地控制根运动。在下面这个示例中,我们通过自定义的Transition类实现动画根运动的灵活控制。首先创建一个脚本RootMotion,并编写如下代码("是否启用根运动")接下来给角色挂载这个脚本并指定两个动画,一个动画启用根运动,另一个不启用再通过UI动态控制角色播放的动画。看下效果当然,在Animancer中我们也可以通过方法来控制根运动。

2022-12-18 09:45:17 2376

原创 Unity Animancer插件(二)精确控制

前面我们讲的都是直接通过动画片段的引用播放动画,Animancer也提供了直接通过动画名称来播放动画的方法。但这并不是推荐的使用方式,因为通过字符串播放比通过引用播放效率略低,且更难维护。首先我们需要在角色身上挂载组件。继承于,它的内部多了一个字典,可以用来映射动画名称与动画引用的对应关系。我们可以在面板上指定一个默认动画状态,这里指定为Idle,但取消自动播放选项。接下来创建一个脚本,并编写如下代码。将脚本挂载到角色身上,并对变量进行赋值。然后在场景中添加四个按钮,分别绑定脚本中的四个方法。

2022-12-09 09:18:09 2142

原创 UGUI性能优化学习笔记(三)图片和图集

虽然我们可以将JPG、PNG之类的格式导入Unity作为纹理的源文件,但实际上,在导入Unity后,会自动对其进行纹理压缩。为什么要进行纹理压缩?每像素位数 (bpp) 表示单个纹理像素所需的存储量。bpp 值越低的纹理在磁盘和内存中也越小。较低的 bpp 值也意味着 GPU 使用较少的内存带宽来读取纹理像素。GPU 内存带宽通常是帧率的瓶颈,因此纹理压缩有助于避免这一问题。既然要进行纹理压缩,JPG、PNG这类格式也拥有较高的压缩率,为什么不直接作为纹理呢?这是因为这类格式不支持。

2022-12-08 16:44:41 1066

原创 拓扑排序与关键路径

简单来讲,对于下面这张图,要想访问到B点,就必须先访问A点;要想访问E点,就必须先访问B点和C点…拓扑排序就是在保证各节点的优先级顺序不被打乱的前提下,遍历整张图的节点。拓扑排序形成的拓扑序列不一定只有一条。比如下面这张图的拓扑序列可以是:,也可以是。如果图的所有节点都遍历到了,那么这就是一张无环图;但如果有节点没有被遍历到,那么这张图一定存在环。拓扑排序的算法流程很简单:从图中找到一个入度为0的节点输出,然后删除这个顶点(包括依赖它的边)。重复此步骤,直到图中不存在入度为0的节点为止。以前面的图为例。在

2022-12-07 21:33:06 1229

原创 Unity Animancer插件(一)基本使用

Animancer是什么?资源商店主页我们来通过Animancer实现一个最基本的动画播放效果。首先创建一个脚本,编写如下代码很容易理解,就是在时播放一个指定的动画片段。接下来为角色添加、和刚刚编写的,并为字段赋值接下来运行游戏就可以看到效果了此时角色身上的组件可以看到当前动画的各项参数下面我们来实现通过按键控制角色在于之间转换。新创建一个脚本。在代码中监听Y轴上的输入。然后根据监听到的数值判断角色状态,并播放相应的动画给对应字段赋值后,启动游戏看下效果下面来实现一个开枪效果。在默认状态下,角色

2022-12-07 11:18:58 6293 7

原创 最短路径(Dijkstra算法与Floyd算法)

Dijkstra算法与之前学习过的Prim算法有些相似之处。我们直接通过一个例子来讲解假设要求的是A->E之间的最短路径。首先我们来列出顶点A到其他各顶点的路径长度:。既然是要寻找最短路径,我们当然是先在已有的路径里面挑一条最短的,也就是。将到达过的顶点用红色进行标识到达C点后,我们又可以找到两条路径:。此时我们拿这几条新的路径长度,与之前的相加,就可以得到。出现了一条比之前短的路径:。所以我们将其更新到之前的路径列表里:。接下来再从路径列表里选择一条最短的路径,也就是:。将D标记为已到达。到达D点后

2022-12-04 22:39:09 2423

原创 UGUI性能优化学习笔记(番外)一些零星的优化点

overdraw也就是过度绘制,是指在每个渲染周期内,屏幕上每个像素最理想只渲染一次,但是由于UI元素的重叠会导致像素会被渲染多次,每次渲染从CPU阶段到GPU阶段会消耗大量资源,如果这种情况比较严重,就会造成卡顿。在编译器窗口下,选择Overdraw模式,可以观察场景中UI的过度绘制情况。颜色越深说明绘制次数越多。降低Overdraw最有效的方法就是减少UI的重叠。对于多个元素构成的UI,尽量将元素整合进一张图中。对于下面这种中间透明的边框,其中间部分仍然会进行绘制。对于这种UI元素,可以采用九宫格

2022-12-03 16:52:39 927

原创 UGUI性能优化学习笔记(二)合批

合批:把渲染时使用相同材质、相同贴图的网格合并在一起,成为一个大网格,然后再调用一次Draw Call,直接渲染这一个大网格。这样做可以降低Draw Call的数量,以优化性能。Unity是如何确定哪些网格可以进行合批的呢?下面我们通过一个具体的示例加深理解在上图中,白色Image位于所有UI元素的最底层,所以Depth = 0。接下来的文本位于白色Image的上层,所以Depth = 1。这里需要注意,UI元素进行深度判断是通过网格进行的,而不是通过rect。接下来对红色Image进行判断。

2022-12-02 17:22:11 2445

原创 最小生成树(Prim算法与Kruskal算法)

一个连通图的生成树是一个极小的连通子图,它含有图中全部的n个顶点,但只有足以构成一棵树的n-1条边。我们把构造连通网的最小代价生成树称为最小生成树。例如下图中①、②、③都是左侧图的生成树,但③是构造连通网的最小代价,所以③是该图的最小生成树。

2022-11-29 21:17:48 2895

原创 UGUI性能优化学习笔记(一)网格重建

在UGUI中,Canvas负责将其下的子UI元素进行合批操作,也就是Batch。当子UI元素发生了变化时,Canvas就需要重新进行Batch操作。Batch操作具体到各个子元素上,就是执行它们各自的Rebuild操作,重新计算元素的布局和网格。Batch和Rebuild加起来构成了所谓的网格重建。

2022-11-29 17:21:38 1240

原创 图的存储方式

图的邻接矩阵存储方式就是用两个数组来表示图。一个一维数组存储图的顶点信息,另一个二维数组存储图中边的信息。对于无向图来说,我们可以用1表示两顶点相连,用0表示两顶点不相连。任意顶点的度为邻接矩阵中该节点的行或列的元素之和。对于有向图,任意顶点的入度为其对应列的元素之和,出度为其对应行的元素之和。对于有权图,可以将邻接矩阵中的元素存储为权值。对于不可达的顶点,可以用一个权值不可能达到的极限值表示。代码如下

2022-11-23 20:27:26 1503

原创 哈夫曼树及其应用

给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。——摘自百度百科要理解哈夫曼树,首先需要理解什么是“带权路径长度”:一棵树中一个节点到达其子孙节点之间的通路称为路径。通路中的分支数目称为路径长度。从根节点到第L层节点的路径长度为L-1。例如上面这棵树中,从17->6的路径长度为3,从14->6的路径长度为2。:从根节点到该节点之间的路径长度与该节点的权的乘积。

2022-11-15 20:00:08 2326

原创 线索二叉树与Morris遍历

对于一棵普通的二叉树,它的节点结构需要由两个指针域和一个数据域构成。而一棵树中必定存在一些指针域没有被使用到,这就造成了空间的浪费。另一方面,我们经常用到二叉树的前、中、后序遍历,如果想求某种遍历中某个节点的前驱和后继节点,那就需要重新进行遍历。这无疑会造成时间的浪费。所以为什么不把空闲的指针域利用起来,让其指向节点的前驱或后继呢?其实这就是线索二叉树的核心思想。我们以中序遍历为例进行讲解。

2022-11-09 21:41:50 709

原创 KMP模式匹配算法

给定字符串M和N,求M中是否包含N,如果包含,则返回N在M中的起始位置对于上面这道题目,我们很容易就能想到如下解法:M和N各自维护一个指针。首先P1指针向右遍历,寻找与P2指针相同的字符然后P2与P1同时向右移动,并一一比对所指字符是否相同一旦遇到不相同的字符,则停止遍历。P2回到初始位置,P1则回到此轮遍历开始时的下一个位置,然后继续前面的过程。直到找到完全匹配的位置代码如下显然这种匹配方式的效率并不高,因为每当匹配失败,都需要进行回溯并重新开始匹配。

2022-11-05 22:27:55 768

原创 Unity物理系统(一)物理系统相关组件

对于离散碰撞检测(Discrete),因为是以帧为单位进行检测,所以如果遇到高速移动的物体A,在上一帧还在B物体的外侧,而下一帧就已经穿过A到达另一侧,就会出现碰撞检测没有触发的情况。比如说采用了「Continuous」模式的物体,撞击不带刚体的物体(也就是图中的Static),最终将采用「Continuous」模式进行碰撞检测。碰撞体是物理组件中的一类,3D 物理组件和 2D 物理组件有独立的碰撞体组件,它要与刚体一起添加到游戏对象上才能触发碰撞。在物理模拟中,没有碰撞体的刚体会彼此相互穿过。

2022-11-01 15:02:07 5151

原创 Unity动画系统学习笔记(三)动画层级与反向运动学

与UI和游戏物体一样,动画状态机也可以有多个层级。层级主要用来实现不同动画的混合。比如在下半身保持奔跑的情况下,上半身进行攻击动作。在层级面板中位于下层的状态机会覆盖掉上层点击层级右侧的齿轮图标,可以对动画层进行设置。各参数作用如下。

2022-10-11 14:50:56 1480

原创 Unity动画系统学习笔记(二)根运动、动画事件与状态机行为

在学习根运动前需要了解两个名词:身体变换:身体变换是角色的质心。它用于 Mecanim 的重定向引擎,并提供最稳定的移位模型。身体方向是相对于 Avatar T 形姿势的下身和上身方向的平均值。身体变换和方向存储在动画剪辑中(使用 Avatar 中设置的肌肉定义)。它们是动画剪辑中存储的唯一世界空间曲线。所有其他:肌肉曲线和 IK(反向动力学)目标(手和脚)都是相对于身体变换进行存储的。根变换:根变换是身体变换在 Y 平面上的投影,并在运行时计算。在每一帧都会计算根变换的变化。变换的此变化随后应用于游

2022-10-08 20:01:11 4740

原创 Unity动画系统学习笔记(一)动画剪辑与状态机

一个完整的动画系统工作流包含如下几个部分:动画剪辑(Animation Clips):包含某些对象如何随时间更改其位置、旋转或其他属性的信息。状态机(Animator Controller):跟踪当前正在播放的动画剪辑,以及当动画剪辑应该改变或混合在一起时的状态信息。骨骼(Avatar):用来映射人形角色的一种通用内部格式。通过骨骼可以将外部的人形动画重定向到我们自己的角色模型中。动画组件(Animator):动画剪辑、状态机、骨骼一同通过动画组件附加到某个游戏物体上。

2022-10-06 10:41:13 4770 2

原创 二叉树的遍历

提到二叉树的遍历,最常见的有以下几种方式:前序遍历:根->左->右中序遍历:左->根->右后序遍历:左->右->根层序遍历:从左到右,从上到下遍历根节点在开始讲解前,我们先定义好树节点的结构

2022-10-05 22:03:19 624

原创 Unity编辑器扩展(一)编辑器扩展基础

MenuItem可以向主菜单和Inspector面板上下文菜单中添加菜单项。它具有如下三个参数:itemName:菜单路径isValidateFunction:是否为校验函数priority:优先级itemName这个参数是必传的,它用于指定菜单的路径。注意使用「MenuItem」特性的方法都必须是静态方法。

2022-10-01 17:56:28 2519

原创 xLua热更新(二)实现热更新

要实现热更新功能,我们首先需要开启热更新的宏。操作方法是在「File->Build Settings->Player Settings->Player->Other Settings->Scripting Define Symbols」选项中添加开启后,在xLua的菜单中就出现了「Hotfix Inject In Editor」选项。

2022-10-01 15:34:07 2611 1

原创 xLua热更新(一)xLua基本使用

xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。xLua是用来实现Lua代码与C#代码相互调用的插件。们可以借助这个插件来实现热更新方案。那么为什么要选择Lua实现热更新呢?这是因为Lua具有轻量、灵活的特点,可以在几乎任何平台上编译、运行。Unity一般使用C#代码编写游戏逻辑。在打包时,C#会先编译成IL(中间语言),存储到dll(动态链接库)中。在游戏运行时,需要通过JIT(即时编译)将IL解释为机器码

2022-09-29 20:50:36 6206 1

原创 UnityShader(七)卡通着色

首先新建一个Shader,同步创建对应的材质球。使用新的材质替换掉模型原有的材质。接下来开始着手编写基本的漫反射Shader声明纹理和漫反射颜色属性,并在CG中声明对应的变量引入「UnityCG」和「Lighting」两个Shader库定义输出结构体在顶点着色器中计算世界空间下的法线坐标、顶点坐标在片元着色器中计算漫反射代码很简单,都是之前学过的内容。我们直接来看效果。

2022-09-22 17:05:42 653

原创 UnityShader(六)透明效果

在Unity中实现透明效果的方式有两种,其一是透明度测试,其二是透明度混合。透明度测试:这种方式不需要关闭深度写入,且实现机制非常简单粗暴。只要一个片元的透明度不满足条件(比如小于某个值),则该片元会被直接舍弃,否则就按照不透明物体的处理方式来处理。它产生的效果要么是完全不透明,要么是完全透明,并不是真正的半透明效果。透明度混合:这种方式会使用当前片元的透明度作为混合因子,与颜色缓冲中的颜色进行混合。这就需要关闭深度写入。而关闭深度写入意味着我们需要非常小心物体的渲染顺序,否则可能出现渲染问题。

2022-09-21 11:28:18 3112

原创 UnityShader(五)纹理采样

纹理最初的目的就是使用一张图片控制模型的外观。使用技术,我们可以将一张图片黏在模型表面,逐纹素地控制模型的颜色。在美术人员建模时,通常会在建模软件中利用纹理展开技术把存储在每个顶点上。纹理映射坐标定义了该顶点在纹理中对应的2D坐标。通常,这些坐标使用一个二维向量(u,v)表示,其中u是横向坐标,v是纵向坐标。因此纹理映射坐标也被称为。

2022-09-19 14:55:30 1485

原创 UnityShader(四)基础光照

光线从光源中发射出来后,与物体表面相交,结果通常有两个:「散射」和「吸收」。。光线在物体表面散射后,一种会散射到物体外部,也就是「反射」;另一种会散射到物体内部,也就是「折射」。对于不透明的物体,折射入内部的光线还会继续与物体内部颗粒相交,一部分最后又会重新发射出表面。另一部分则被物体吸收。我们在光照模型中使用「高光反射」表示物体表面如何反射光线;使用「漫反射」表示有多少光线被折射、吸收、散射出表面。

2022-09-17 12:19:59 707

原创 剑指 Offer 22-链表中倒数第k个节点

剑指 Offer 22-链表中倒数第k个节点

2022-09-15 08:49:41 140

原创 UGUI学习笔记(十二)自制血条控件

首先在场景中使用「Image」创建如下结构并命名为「LifeBar」。需要注意的是内部的「Image」都需要将锚点设置到最左侧,高度设置为自适应。在父元素上挂载同名脚本,将「LifeBar」制作为预制体。之所以创建了「OuterBar」和「InnerBar」两个血条,是为了做出多层血条的效果。然后在场景中随便创建一个敌人(需要有「MeshRenderer」),然后挂载一个控制脚本。我这里的脚本命名为「KeLiController」

2022-09-13 15:00:53 1499

原创 UGUI学习笔记(十一)自制优化版滚动视图

为了让「Scroll View」组件实现内容框自适应大小,我们可以在「Content」上挂载「Vertical Layout Group」组件和「Content Size Fitter」组件。效果如下但这种实现方式有诸多问题。一方面,「Vertical Layout Group」这类排序组件可能会增加性能消耗;另一方面,「Content Size Fitter」必须靠子项才能撑开,当子项数量较多但又只需要展示少数几条时,会造成内存的浪费。因此我们需要自己实现一个优化版的滚动视图。

2022-09-12 16:38:46 364

原创 UGUI学习笔记(十)自制雷达图

首先导入一张雷达图的背景图,将其挂载到「Image」上添加到场景中,命名为「RadarBg」。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R10nIh9G-1662875993217)(https://lvwrpic-1259267089.cos.ap-shanghai.myqcloud.com/pictures/%E9%9B%B7%E8%BE%BE%E5%9B%BE.png)]在「RadarBg」下添加一个空的子物体,命名为「RadarChart」并挂载同名脚本。

2022-09-11 14:01:00 557

原创 UGUI学习笔记(九)自制3D轮播图

首先在Canvas下创建一个空物体,将其命名为「SlideShow」,并设置好其大小。它将作为轮播图的父容器。在「SlideShow」身上挂载一个脚本,命名为「SlideShow3D」。声明一个Vector2成员用来设定每张图片的大小,一个Sprite数组用来存储需要展示的图片新创建一个脚本命名为「SlideShowItem」,作为子物体身上挂载的脚本。

2022-09-10 18:31:16 847

原创 UGUI学习笔记(八)UGUI不规则响应区域

在上一篇文章中我们了解到,UI的默认响应区域是UI元素所在的矩形框线内的区域。这也就意味着,当UI的图形为不规则形状时,点击图形的外部也可能会触发事件。但其实Unity自带了一种不规则区域点击策略。要想使用它,我们首先要将精灵的「Read/Write」属性设置为开启状态然后在代码中将「Image」组件中的「alphaHitTestMinimumThreshold」属性设置为0.1。

2022-09-09 12:10:04 962

UGUI学习笔记(十二)自制血条控件

UGUI学习笔记(十二)自制血条控件

2022-09-13

UGUI学习笔记(九)自制3D轮播图

UGUI学习笔记(九)自制3D轮播图

2022-09-12

UGUI学习笔记(十)自制雷达图

UGUI学习笔记(十)自制雷达图

2022-09-12

UGUI学习笔记(七)自己实现圆形图片组件

UGUI学习笔记(七)自己实现圆形图片组件

2022-09-12

UGUI学习笔记(十一)自制优化版滚动视图

UGUI学习笔记(十一)自制优化版滚动视图

2022-09-12

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除