自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 IL2CPP和Mono的区别

Mono 是一种开源的跨平台 .NET 框架实现,能够执行 C# 代码。Unity 使用 Mono 来处理 C# 脚本,并通过 JIT(Just-In-Time)即时编译器将托管代码转换为本地机器代码,随后在目标平台上执行。它是一种 Unity 特有的技术,用于将 C# 的中间语言(IL,Intermediate Language)转换为 C++ 代码,然后再通过 C++ 编译器将其编译为目标平台的本地机器代码。

2024-10-07 11:57:48 364

原创 GC的算法

标记-清除(Mark-Sweep)通过标记存活对象并清除未标记对象来进行垃圾回收,适合处理较为复杂的对象引用关系。分代回收(Generational Collection)根据对象生命周期的不同,将堆分为多个代,频繁回收短命对象,减少对长期存活对象的频繁扫描,提升垃圾回收效率。C# 的垃圾回收器通过结合这两种机制,能够在保持良好性能的同时,自动管理内存的分配与回收,极大地简化了开发者的工作。

2024-09-17 11:19:56 1295

原创 AABB包围盒和OBB包围盒

2024-09-11 17:57:55 178

原创 lua长短字符串

2024-09-11 16:42:47 158

原创 虚表的结构与工作原理

每个元素都是一个指向虚函数的指针。每个含有虚函数的类都有一个与之相关联的虚函数表。如果类中有继承关系且包含虚函数,那么每个类都会有自己的虚函数表。多态的关键在于能够通过基类的指针或引用来调用派生类的函数。该指针被隐式地添加到对象的内存布局中,指向该对象所属类的虚表。虚函数表(vtable)是由编译器生成的一个数据结构,它是一个。每个包含虚函数的对象在其内存布局中会有一个指向虚表的指针,称为。

2024-09-11 00:24:54 247

原创 如何降低 Draw Call

(绘制调用)是游戏引擎向图形API(如 DirectX、OpenGL 或 Metal)发出的指令,要求 GPU 渲染一组几何体或对象。简单来说,每次需要绘制一个对象(例如模型、材质、纹理等)到屏幕上时,都会发起一次。需要 CPU 和 GPU 进行通信,CPU 准备渲染数据(例如顶点、纹理、材质等),然后交给 GPU 进行实际的绘制。:将多个小纹理合并到一个大纹理中,这样多个物体可以共享同一个材质,减少。通过合并材质、使用相同的材质或减少材质种类,可以减少。:每次不同的材质切换会导致额外的。

2024-09-10 22:25:02 488

原创 new、delete、malloc、free关系

2024-09-10 21:18:27 102

原创 C++知识

静态转换(static_cast):静态转换是最常用的一种类型转换,它可以在不同但相关的类型之间进行转换,如基本数据类型之间的转换、父类指针向子类指针的转换等。但是需要注意的是,静态转换没有运行时类型检查,因此在进行转换时需要确保类型之间是相关的,否则可能会导致错误。如果我们采用传统的new/delete来申请和释放资源,如果忘记调用delete,或者在调用delete之前程序抛出异常,都会导致内存泄漏问题,采用智能指针对资源进行管理,能够杜绝这类问题。代码区:存放代码,不允许修改,但可以执行。

2024-08-29 12:53:58 622

原创 lua知识

boolean 类型只有两个可选值:true(真)和false(假),Lua把 false和 nil看作是 false,其他的都为 true,数字0也是 true:字符串由一对双引号或单引号来表示。也可以用 2 个方括号"[[ ]]"来表示”一块"字符串。字符串连接使用的是".."在 Lua 里表的默认初始索引一般以1开始。打印时nil被忽略自定义索引。

2024-08-26 14:10:51 1042

原创 Lua热更新原理

将需要频繁更改的逻辑部分独立出来做成DLL(动态链接库(Dynamic Link Library),可以包含类,函数等资源,让其他程序动态加载使用),通过反射机制加载这些DLL,主模块代码不作修改,热更新时用新的dll替换旧的dll,主模块加载dll就起到了更新的效果。通过反射,可以在运行时通过程序集中的元数据来实例化对象、调用方法、获取和设置属性等,而不需要在编译时明确知道这些类型和成员的具体信息,主要用到Type,Assembly,Activator三个类,这里不过多赘述,详细内容可以自行学习。

2024-08-17 17:59:57 347

原创 UnityA*寻路算法

如果m不在关闭列表中,计算从起始节点到m的实际代价g(m)(g(m) = g(n)+n到m的代价)和启发式代价h(m)。如果m的代价小于其之前的代价,或者m尚未设置父节点,则将m的父节点设置为n,并更新m的代价g(m)。将m添加到开放列表中。如果节点m是目标节点,则找到了最短路径,结束算法。输出最短路径:从目标节点回溯到起始节点,按照父节点指针依次访问节点,得到最短路径。a. 从开放列表中选择具有最小代价的节点n,并将其从开放列表中移除。初始化:设置起始节点和目标节点,将起始节点添加到开放列表中。

2024-08-14 15:13:56 145

原创 二叉堆建立过程

建立堆的过程:按数组顺序建立一个完全二叉树,然后从把每个非叶子节点(n/2-1)进行下沉操作(如果小于子节点就和子节点中的最大值交换)

2024-08-14 12:53:33 125

原创 多态的构成条件

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。1.必须通过基类的指针或者引用调用虚函数。

2024-08-11 20:29:53 365

原创 八种排序算法

比较好的,因为他的读取次数会比较少(在数据挖掘的理论里面,读取次数越少,排序方法越快),同时是稳定的;但是如果内存空间不足,就自然要减少次数了,所以也可以用快速排序,快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;也可以利用堆排序,当N很大时,并且有序程度低时,堆排序最快(当N很大时,并且有序程度高时,快速排序最快 )。,归并排序需要一个与原数组相同长度的数组做辅助来排序。对于内存足够大的大量数据排序,一般来说用。对于一个基本排好序的数组,使用。

2024-08-11 19:46:53 294

原创 Unity单例模式

在程序一开始的时候就创建了单例对象。但这样一来,这些对象就会在程序一开始时就存在于内存之中,占据着一定的内存。在用到单例对象的时候才会创建单例对象。

2024-08-11 16:04:16 207

原创 面向对象的七大设计原则

接口的依赖(继承)原则:如果一个接口a继承另一个接口b,则接口a相当于继承了接口b的方法,那么继承了接口b后的接口a也应该遵循上述原则:不应该包含用户不使用的方法。接口的设计原则:接口的设计应该遵循最小接口原则,不要把用户不使用的方法塞进同一个接口里。修改关闭:某模块被其他模块调用,如果该模块的源代码不允许修改,则该模块修改关闭的。为了满足开闭原则的对修改关闭原则以及扩展开放原则,应该对软件系统中的不变的部分加以抽象,在面向对象的设计中,扩展开放:某模块的功能是可扩展的,则该模块是扩展开放的。

2024-08-10 23:54:54 1133

原创 Unity工厂模式

工厂是一种创建型设计模式。通俗来讲就是提供一种封装对象创建的方式,将对象的创建和使用区分开。就是Unity里面通常用到的创建和管理对象。

2024-08-08 17:27:19 1232

原创 三种热更新方式的比较

原理:特点:使用场景:原理:特点:使用场景:原理:特点:使用场景:

2024-08-08 16:19:48 612

原创 序列化与反序列化

就是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区(如硬盘)。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。将数据结构或是对象 转换为 二进制串(字节序列)的过程。将二进制串(字节序列)转换为 数据结构或者对象 的过程。

2024-08-08 16:09:37 122

原创 什么是内存碎片

内存碎片化是一个性能问题,它出现在动态内存分配调用(如C#中的new操作符)过程中。内存碎片是指由于频繁分配和释放内存,导致内存中出现许多不连续的小块空闲内存,从而无法有。这种情况下,你可能有足够的总空闲内存来满足一个新的内存请求,但没有一个单独的空闲块。内存块在被频繁分配和释放后,可能导致剩余的空闲内存块被分散在一整块内存中,这就是碎片。能够满足这个请求,最终导致内存分配失败。4.使用大对象堆(LOH)5.使用ArrayPool。3.能用值类型就用值类型。

2024-08-08 15:59:02 252

原创 面向报文和字节流 短连接和长连接

当字节流太短时,TCP会等待缓冲区中的字节流达到一定程度时再构成报文发送出去,TCP发给对方的数据,对方在收到数据时必须给矛确认,只有在收到对方的确认时,本方TCP才会把TCP发送缓冲区中的数据删除。问题 而UDP传输报文的方式是由应用程序控制的,应用层交给UDP多长的报文,UDP照样发送,既不拆分,也不合并,而是保留这些报文的边界,即一次发送一个报文。长连接是指在一次请求-响应之后,不立即关闭连接,而是保持连接的持续开放,允许多次请求和响应在同一连接上进行。TCP无界,UDP有界;

2024-08-02 09:46:22 344

原创 C#杂项知识点

Tuple<T> 元组是一种包含不同数据类型的元素序列的数据结构。它可以用于需要数据结构来保存具有属性的对象,但又不想为其创建单独类型的情况。方法中统一处理这些增删操作,可以保证所有的增删操作都会在一个更新周期内完成,避免了部分增删操作未完成的情况。发生改变时,除了更新自身的值,还会标记其父节点为脏节点。然后在update中更新所有脏节点的值。必须有一个公共的无参数构造函数。此外,它还允许字符串跨越多行。是一个类型约束,这个约束指定类型参数。将所有的添加的计时器放到。使字符串中的转义字符(

2024-08-02 09:46:09 225

原创 Unitask相关知识

为 Unity 提供有效的无GC async/await集成 类似于 Unity 的 这一帧到此暂停,下一帧再从暂停处继续执行后续的代码,常用于循环中。 等待某个条件: 在某些情况下,需要等到某个条件满足后再继续执行协程。可以使用 在等待过程中进行循环检查。IEnumerator WaitForCondition(){ while (!ConditionIsMet()) { yield return null;}}(1000) 会在指定的时间间隔后继续执行任务(20) 会在指定的帧数后继续执

2024-08-02 09:45:58 743

原创 C#Static和Const

不同线程下访问的静态属性总是同一属性,如果某一线程更改了属性值,将造成其他线程访问属性值错误。因此方法中访问同一静态属性就需要使用lock关键字,或创建互斥对象来保持静态属性在同一时间只能被某一对象的属性或方法访问。包括静态字段、属性、方法和构造函数。用于声明常量,常量是不可变的值,必须在声明时初始化,并且在整个程序生命周期中不能改变。常量在编译时被确定,并且其值在编译时就内嵌到使用它的代码中。: 当你需要一个在运行时确定的常量,或者需要表示复杂类型的常量时,例如从配置文件读取的值、基于运行时计算的值等。

2024-08-02 09:45:47 311

原创 C#中闭包的概念和注意事项

从本质上说,闭包是一段可以在晚些时候执行的代码块,但是这段代码块依然维护着它第一个被创建时环境(执行上下文)- 即它仍可以使用创建它的方法中局部变量,即使那个方法已经执行完了。C#中通常通过匿名函数和lamada表达式来实现闭包。然而,当在循环中使用闭包时,需要小心变量捕获的问题。这是因为闭包捕获的是变量的引用,而不是变量的当前值。要解决这个问题,可以在循环内部创建一个新的变量,使得每个闭包捕获的是不同的变量。期望上面的代码输出:01234 但实际输出是55555。

2024-08-02 09:45:36 197

原创 Unity进程 线程 协程

进程:是系统进行资源分配的基本单位,进程是线程的容器。打开unity的程序就是开始了一个进程,每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大。进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;

2024-08-01 13:47:32 408

原创 YooAsset和AB包

是一个用于 Unity 的高效资源管理和加载库,它旨在简化资源的加载、管理和更新过程。AssetBundle(简称AB包)是一个资源压缩包,包含模型、贴图、预制体、声音、甚至整个场景,可以在游戏运行的时候被加载;AssetBundles 是 Unity 提供的一种打包资源的格式,可以包含多个资源文件,并支持资源的依赖管理。但是需要指出的是,引擎启动时会创建一个Resource索引表,Resource文件夹下文件越多,其索引表也就越大,这个是会占用内存的。资源加载:支持异步加载资源,减少加载时的卡顿。

2024-08-01 13:40:50 703

原创 C#lock关键字和死锁

Pn等待P1占有的资源,形成一个进程等待环路,环路中每一个进程所占有的资源同时被另一个申请,也就是前一个进程占有后一个进程所深情地资源。事实上循环等待的成立蕴含了前三个条件的成立,似乎没有必要列出然而考虑这些条件对死锁的预防是有利的,因为可以通过破坏四个条件中的任何一个来预防死锁的发生。互斥条件:资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。锁的粒度:选择合适的锁粒度。

2024-08-01 13:36:53 655

原创 C#中StringBuilder

维护一个字符数组(缓冲区),并根据需要动态调整数组大小。通过这种方式,可以在进行字符串拼接时避免频繁的内存分配和字符串复制操作。适合频繁字符串操作和拼接。由于每次对字符串进行拼接操作时,都会创建一个新的字符串对象,这会导致频繁的内存分配和垃圾回收。通过维护一个可变的字符缓冲区来避免这些问题。

2024-08-01 11:14:46 359

原创 Unity中是如何调用MonoBehaviour生命周期方法的

打开MonoBehaviour类会发现并没有Awake、Start等方法,而继承MonoBehaviour的类也没有重写这些方法,就算是私有的也可以被调用。Unity内部运用了反射去调用这些生命周期函数,运行时通过反射将所有继承MonoBehaviour的类中的生命周期函数找出来,维护一套列表。

2024-08-01 11:14:04 443

原创 C# ^索引操作符

用于从集合或数组的末尾开始进行索引操作。这是 C# 8.0 引入的一种语法糖,称为索引操作。表示从集合或数组的末尾开始的第一个元素。表示倒数第二个元素,以此类推。表示倒数第一个元素,

2024-08-01 10:05:52 694

原创 C# sealed关键字

密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写。当应用于方法或属性时,sealed 修饰符必须始终与 override一起使用。如果希望基类的方法或属性不被继承,可以将基类用组合/内聚的方式实现。sealed 修饰符可以应用于类、实例方法和属性。基类不能使用sealed关键字。

2024-08-01 10:04:58 241

原创 什么时候用异步和多线程

更高效的资源利用:异步编程通常依赖于任务调度和线程池,避免了不必要的线程创建和上下文切换。直接控制线程:多线程编程提供了对线程的直接控制,可以精细地管理线程的生命周期和优先级。保持 UI 响应性:在 GUI 应用程序中,异步编程是保持界面响应的最佳选择。更适合 I/O 绑定任务:如网络请求、文件读写等。更适合 CPU 绑定任务:如计算密集型任务。适用于需要实时响应和高性能的场景。

2024-08-01 10:03:04 334

原创 Unity 使用自定义程序集的好处

在大型项目中使用程序集可以提高编译效率,在代码编译时Unity会将工程中的所有代码编译到 Assembly-CSharp.dll 程序集中去。当项目庞大代码量多的时候,代码的每一次修改都会消耗大量的时间进行编译,使用程序集则可以减少编译时间。当某一功能模块需要在多个项目中重复使用时,可以将代码编译成程序集,将程序集放入工程中即可。在代码维护时,也只需重新编译程序集替换即可。我们常用到的第三方插件就是如此。使用程序集也可以更好的模块化组织和管理代码。使用程序集也可以避免源代码的暴露。

2024-08-01 10:02:27 274

原创 FGUI在unity中进行坐标转换(将一个物体放在另一个物体处)

当我们想把一个物体移动到另一个物体的位置,如果不进行坐标转换,通过GObject里的x/y/position属性只能得到本地坐标,由于FGUI的组件都是放在GRoot这个根节点下的,所以我们要把本地坐标转换成逻辑坐标,即GRoot坐标系下,再使用FGUI提供的SetXY()方法来设置位置。这里aObject.TransformPoint(new Vector2(10,10), bObject)的作用是获取A里面的坐标(10,10)在B里面的位置。Local本地坐标:物体相对于父节点的坐标。

2024-08-01 10:01:01 981

原创 C#中class和struct的区别

实例化时,class要使用new关键字;而struct可以不使用new关键字,struct在声明时就进行了初始化过程,所有的成员变量均默认为0或null。struct没有继承性,struct不能从class继承,也不能作为class的基类,但struct支持接口继承。class表现为行为;而struct常用于存储数据。类没有默认无参构造函数,struct有默认无参构造函数。class是引用类型;struct是值类型,

2024-08-01 09:59:40 409

原创 C#深拷贝

这时需要用到深拷贝,指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。这样进行深拷贝后的拷贝对象就和源对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。对引用类型变量赋值的时候,只保留了一个引用,因为两个变量都指向了一块内存地址,所以对两个变量中任何一个变量的操作都会影响到另外一个。如List1.AddRange(List2);如List1=List2;

2024-08-01 09:58:27 467

原创 C#中ref和out的区别

参数的变量在调用方法之前不需要初始化,但在方法内部必须被初始化。参数的值可以被修改,并且这些修改会反映到调用方法的外部。参数赋值,保证方法返回后变量有一个定义明确的值。参数的变量必须在调用方法之前初始化。必须在方法内部初始化:传递给。必须被赋值:方法内部必须为。必须在使用前初始化:传递给。可能被修改:在方法内部,

2024-08-01 09:57:27 284

原创 C# default(T)关键字

返回该类型的默认值。引用类型: 对于引用类型(例如。用于返回泛型类型T的默认值。值类型: 对于值类型(例如。

2024-08-01 09:55:53 342

原创 Unity中的垃圾回收机制GC

定期调用GC.Collect来手动释放不再使用的资源,以减少内存占用和垃圾回收的频率。避免在循环中(尤其是像Update这种每帧执行的方法)创建对象。对于频繁拼接的字符串操作使用StringBuilder。使用值类型更优的情况下选择使用值类型存储数据。手动调用GC.Collect()方法。unity自动调用,如场景切换时。

2024-08-01 09:54:06 618

空空如也

空空如也

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

TA关注的人

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