CLR Via C# - 委托
委托委托实际上利用Delegate和MulticastDelegate类来实现。
123456789101112131415161718public abstract class Delegate : ICloneable, ISerializable { ... //实例对象。 委托对象包装静态方法时,此字段为null。委托包装实例方法时,此字段为实例对象。 internal Object _target; //函数指针 internal IntPtr _methodPtr; ...}public abstract class MulticastDelegate : Delegate{ ... //单个委托此字段为null,构造委托链时它引用一个委托数组。 private Object _invocationList; private IntPtr _invocationCount; ...}
定义和绑定定义委托实际生成了一个继承自Multicast ...
CLR Via C# - 类型基础
类型基础在C#中,所有的类都继承自System.Object。Equals、GetHashCode、ToString、
公共方法:
Equals,默认用于比较两个对象是否是同一对象(指针是否指向同一对象);
GetHashCode,默认返回一个哈希值,但这个并不是不变的,可能会因.NET版本变更而变更,所以不能用来序列化保存;
ToString,默认返回对象的类的全名;
GetType,是一个非虚方法,返回对象的类型对象指针,非虚保证了类型安全;
newnew一个对象时,虚拟机做了以下几件事:
计算对象每个字段所需的内存之和,并加上类对象指针(type object pointer)和同步块索引(sync block pointer)
在堆上申请对象所需内存,并将其全部置为0;
设置类型对象指针和同步块索引;
调用构造函数和基类构造函数,传递实参;
返回对象指针到线程栈;
类型转换隐式转换和显示转换
派生类对象可以隐式转换为基类对象;
基类对象只能显示转换为派生类对象,并且在转换时会进行类型检查;
is和asis和as都不会报错,is是进行一次类型检查,as则是进行一次类型检 ...
CLR Via C# - List
ListList的构造1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283//继承了IList<T>接口public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>{ //默认大小为4 private const int _defaultCapacity = 4; //泛型数组,数据实际存储在这里 private T[] _items; //当前List中的元素个数,即Count [ContractPublicPropertyName("Count")] private ...
Unity 架构
Unity架构Unity 引擎是用原生 C/C++ 在内部构建的,不过它有一个 C# 封装器可用来与之交互,Unity使用Roslyn编译器编译C#代码,Unity使用开源.NET平台来确保使用Unity制作的应用程序可以在各种不同的硬件配置上运行,.NET平台支持一系列语言和API库。
后端编译
Unity 具有两个脚本后端 Mono 和 IL2CPP (Intermediate Language To C++),它们各自使用不同的编译技术:
Mono 使用即时 (JIT) 编译,在运行时按需编译代码。
IL2CPP 使用提前 (AOT) 编译,在运行之前编译整个应用程序。
使用IL2CPP开始构建时,Unity 会自动执行以下步骤:
1.将 Unity Scripting API 代码编译为常规 .NET DLL(托管程序集)。
2.应用托管字节码剥离。此步骤可显著减小构建的游戏大小。
3.将所有托管程序集转换为标准 C++ 代码。
4.使用本机平台编译器编译生成的 C++ 代码和 IL2CPP 的运行时部分。
5.将代码链接到可执行文件或 DLL,具体取决于目标平台。
...
Unity打ab包工具
Unity打ab包工具如何设计一个Unity打ab包的工具?
提出工具所需的功能
设计工具架构
AB打包工具功能
图形化的分包窗口,可以为指定目录/文件资源设置分包规则
依据设置的分包规则,生成bundle列表,打包后可以输出filelist和manifest
增量ab模式,打整包输出完整filelist,打patch可以输出增量filelist列表
version管理,每次打包对资源version进行更新,与filelist保持一致
可动态调整的ab拷贝输出目录,用于资源上传
支持资源上传oss配置等配置
支持多线程写入的日志系统
关于以上功能,我们需要进一步拆分怎么做
流程图
图形化的分包窗口图形化界面设计TODO:可以方便的预览资源/目录 是否被指定ab名及其ab名,可以预览ab中包含的资源清单(包括显式和隐式),支持分类和分包
指定目录/文件资源设置分包规则
文件:为某个文件单独指定ab名
文件夹:为某个文件夹指定ab名,或文件夹中的文件单独打ab(支持类型筛选)
支持隐式依赖进包,但common部分可以自动提取为单独ab
ab名应该为文件相对路径拼接而成
依据设置的分 ...
Unity打包前后处理
Unity打包前后处理在Unity打包前后我们需要做一些事情,一般来讲,我们会先打AB资源,再打包,此时,我们可能需要:
清除streamingAssetsPath目录下原有的资源;
将需要进包的资源拷贝到streamingAssetsPath目录下;
保存GameConfig文件,保存FileList文件,保存资源Version文件;
这个步骤我们可以放在打包前处理中,好处是不需要关心平台差异,Unity自行处理SteamingAssets资源进包,缺点就是会拖累打包速度,因为我们需要在打包前处理做一次拷贝,此时还会触发一次Unity的资源导入,如果需要删除原资源,则还会触发一次资源删除和资源导入。
因此,我们选择在打包后处理过程中进行拷贝,此时,我们需要关心平台差异。
在打包后处理中,我们可能还需要关注:
Android中,修改gradle.properties、AndroidManifest等
IOS中,修改project.pbxproj等
打包前处理接口12345678910111213using UnityEditor.Build.Reporting;namespac ...
Unity的IMGUI(一)
Unity的编辑器(一)Unity中实现多套UI方式,其中最常见的包括 IMGUI、UGUI、UIToolkit(UIElement)等:
IMGUI是一套面向程序代码的UI方案,通常用于Unity编辑器以及游戏运行时的调试面板;
UGUI,通常是我们用于游戏运行时的UI方案;
而UIToolkit则是Unity推出的新一代UI方案,用于取代UGUI和IMGUI,采用了类似网页设计的uxml+uss方案,但多年过去,UIToolkit依然是preview阶段,其使用起来也非常不便,因此目前尚无法成为主流方案。由于其性能相对IMGUI更优异,在部分编辑器场景可以使用。
本文仅对IMGUI做一定的梳理。
IMGUI的执行流程对于使用者来说,IMGUI核心就两件事情,OnGUI的回调,以及此时的Event。在帧与帧之间IMGUI几乎不保存任何的GUI信息,每一帧都会依据OnGUI的代码执行相应的计算和绘制。
通常一帧里Unity至少会调用两次OnGUI的回调,Event事件发生变动时也会调用OnGUI的回调。在OnGUI的回调里,我们既要处理数据的变更,也要处理组件的绘制,那怎么样组织代 ...
3d数学 矩阵、坐标系与变换
矩阵如何表示变换举例假设存在向量$\vec{a}$,在坐标系A中,其坐标为(x,y,z),坐标系A的基向量为$\vec{i}(1,0,0),\vec{j}(0,1,0),\vec{k}(0,0,1)$,那么向量$\vec{a}$,可以描述为:
\vec{a}=x*\vec{i} + y*\vec{j} + z*\vec{k}即:
\vec{a} = (x,y,z)*
\left[
\begin{matrix}
\vec{i} \\
\vec{j} \\
\vec{k}
\end{matrix}
\right]
=(x,y,z)*
\left[
\begin{matrix}
1&0&0 \\
0&1&0 \\
0&0&1
\end{matrix}
\right]那么,当基向量变换之后,例如将$\vec{i}、\vec{j}、\vec{k}$进行变换操作,得到$\vec{i^1}、\vec{j^1}、\vec{k^1}$,此时依然有:
\vec{a^1} = x * \vec{i^1} + y * \vec{j^1} + z * \vec{k^1} = ( ...
设计模式-命令模式
命令模式
命令就是一个对象化(实例化)的方法调用。——《游戏编程模式》
我对于这句话的理解是这样的,命令模式实际上还是要去做一件事的,而做事情本身就是一个方法调用。相比于直接的调用方法,命令模式封装了一个对象,或者说闭包来做这件事。这样,任意时刻想做某件事的时候,不去直接调用函数,而是抽象成一个命令,这样我们可以将实际逻辑处理和命令的生成解耦。
我们可以完成复用逻辑、记录命令、撤销命令等;
例如对于Actor来说,不论是玩家的操作指令,还是AI生成的命令队列,还是服务器发来的命令队列,都可以让Actor完成某些“动作”。
因为命令记录了实际操作的内容,支持撤销和重做,我们还可以生成命令列表来完成多次撤销和重做。