Table of Contents
- XericLibrary
- 特性库
- 协程宏
- 调试宏
- 网格宏
- 电脑宏
- 相机宏
- 颜色宏
- 配置文件宏
- 常数宏 MacroConst
- 曲线宏 MacroCurve
- 日志宏 MacroDebug
- 枚举宏 MacroEnum
- 方程宏
- 事件宏
- 文件宏 MacroFile
- 窗口宏 MacroForm
- 步进宏
- 按键宏 MacroKey
- 数学宏 MacroMath
- 列表宏 MacroMath
- 消息库 MacroMessage
- 对象宏
- PID宏
- 对象池宏
- 矩形变换宏
- 超驰宏
- 正则宏
- 仓库宏
- 材质宏
- 平滑宏
- 排序宏
- 文本宏 MacroMath
- [时间宏]
- [轴变换宏]
- [类型扩展]
- [矢量扩展]
- [导航宏]
- [安全宏]
- [转换宏]
- [事件触发宏]
XericLibrary
清肃未知,编撰成库。
Xeric中使用宏 (Macro) 作为隔离用法的的单元,所有的操作都可以从MacroXX获取(XX是各个操作类模块的名称)。
特性库
-
CanFind$ 其中包含多个特性类,用于查找类,字段,属性,方法等项目。
-
ReName 重命名特性,在没有安装odin插件的旧版本引擎上可以直接替换细节面板中的参数名。
不过由于无法和odin兼容,odin的功能会覆盖掉这个特性,同时在2018 (大概) 以上的版本中也没用。
虽然大多数情况下不起作用,但仍可以使用配套的一系列方法来处理这个特性,如批量查找,ugui系统重命名等。
协程宏
调试宏
网格宏
电脑宏
相机宏
颜色宏
-
随机颜色 使用
RandomHueColor获取一个随机的颜色,随机数计算使用MacroMath库提供。 -
文本转颜色 使用
TryParseColor或ParseColorOrDefault将文本转为颜色,支持#RGB,#RGBA,#RRGGBB,#RRGGBBAA格式,以及unity,textMeshPro的语义颜色,基本Web颜色。 这些颜色在正则宏中也可以处理。
配置文件宏
-
网络配置文件 提供默认的异步保存和异步读取方法,通过
MacroConfig.SaveUriConfigFile或MacroConfig.ReadUriConfigFile访问。
配置文件路径默认在streamAssets下的uriConfigFile里。
注册MacroConfig.OnUriConfigFile事件来在场景加载前读取配置文件 (或自己创建一个) 。 -
场景配置文件
常数宏 MacroConst
曲线宏 MacroCurve
日志宏 MacroDebug
提供XericLogger,通过XericLogger.CCLog可以输出一段日志,除去了追踪栈信息,并默认着色区分。
枚举宏 MacroEnum
枚举宏包含一个缓存封装器,可以通过MacroEnum\<enum\>来定义。
定义枚举结构封装将允许像列表一样访问这个枚举,或将枚举实例赋予,通过枚举封装器来操作枚举值。
方程宏
事件宏
文件宏 MacroFile
窗口宏 MacroForm
提供User32.dll中部分函数的功能。
- 获取当前进程PID:
PID - 通过句柄查找窗口:
FindWindow - 控制窗口化状态:
ShowWindow - 枚举显示器信息:
GetDisplayMonitorsInfo
步进宏
按键宏 MacroKey
预设了一些判断较复杂按键状态的逻辑。
对于外部的常规逻辑,可以使用扩展的InsertKey逻辑。
为了使用这些逻辑,需要定义一个KeyFlippingStampSheetStyle(简称KfsStyle)。
KeyCode.A.AsKfsStyle();
将这个作为按键索引,传入扩展的状态检查事件一同执行更新,即可做出判断。 这会返回一个KeyFlippingStampSheet,里面包含当前按键状态的布尔值,以及按键判断时触发的委托事件。
-
交叉动作与延迟触发长按
var keySheet = Input.GetMouseButtonDown(0).InsertKeyStateCmet(KeyCode.A.AsKfsStyle());使用IsPressed判断是否单击按下,如果是双击,第一次点击时当前帧还是会返回单击事件。
使用IsReleased判断刚刚的单击是否释放,如果上一次是长按状态,那么这个释放事件不会触发。 使用IsDoubleClick判断是否双击,双击事件会出现在第二次点击间隔小于KfsStyle中设置的双击间隔时。
使用IsFirstLongPressed判断是否长按,当一次按下后不释放时间大于KfsStyle中设置的长按间隔时出现一次。 使用IsLongPressedState判断是否长按,当一次按下后不释放时间大于KfsStyle中设置的长按间隔时出现。 使用IsLongReleased判断刚刚长按是否释放。 -
坐标保持触发
var keySheet = Input.GetMouseButtonDown(0).InsertKeyStatePt(KeyCode.A.AsKfsStyle());与上述功能一致,但可以使用拖拽事件: 使用IsChangeDraggingFromLongPressed判断长按事件是否转为拖拽事件。 使用IsBeginDragging判断当前是否开始拖拽。 使用IsDragging判断当前是否正在拖拽。 使用IsDropping判断当前是否正在丢弃。
在拖拽期间,长按状态将继续触发,但长按事件将转为拖拽事件,长按事件。 拖拽结束后,如果以拖拽结束,但以长按开始,那么长按结束事件也会触发。
-
光标坐标计算: 提供诸如类似
GetRectangleRelativelyPoint的扩展方法,将传入的光标坐标计算为相对坐标。
数学宏 MacroMath
注意数学库包含多个子模块,包括数学常量,枚举,列表算法(不包括排序算法),基础数学扩展,矩形范围计算,区域与文本扩展,时间扩展,单位转换等。 这里仅对源码中MacroMath文件内的方法进行说明。
- RandomFloat/Vector/Matrix:通过一个随机生成器快速获得随机值。
- Pmod:在正数空间上对值取余,负数情况下仍然会保持与正数相同的曲线形状。
- RoundToAny:将一个矢量四舍五入到任意的倍数,比如4.8舍入3.5得到3.5,6.2则得到7
- MinPositive:获取正数空间上的最小值。
- SmoothStep:获取t在(a,b)之间的埃尔米特过度
- LinearStep:获取t在(a,b)之间的线性过度
- RoundBasedOnMinimumDifference:将一个值根据最小的差值进行四舍五入
- DiscardLeastSignificantDecimal:舍弃不重要的小数位
- ClampWrapAngle:钳制角度
- GetNumberOfDecimalsForMinimumDifference:获取最小插值的小数个数
- CosineSimilarity:余弦相似度
- FibonacciRecursive:斐波那契迭代方式计算 (会产生大量循环)
- FastInvSqrt:快速平方根倒数
- IsPrimeNumberRw:检查一个数是否是质数 (这是一个娱乐用法,利用正则表达式判断是否为质数,性能消耗较高)
- GetCirclePoints:获取圆上的点
- GetRayIntersectionCircle:获取切于圆的线两点坐标
- GetHeightOfRoundArch:获取圆拱高度
- GetListFormAToB:获取从A到B的列表
- LerpTransform:创建lerp矩阵
列表宏 MacroMath
- FisherYatesShuffle: 洗牌算法,返回一个索引映射数组,同时也提供一个线程安全的蓄水池洗牌算法。
- GetRandom: 从列表中随机获得1个或多个对象 (洗牌算法) 。
- MakeIEnumberable: 将一个对象制作成枚举器。
- LandedIndex: 从迭代器中抽出索引下的成员。
- SelectConvert: 从非泛型迭代器转为泛型迭代器。
- ForEachDo: 迭代器执行。
- Adjoint: 迭代器拼接一个索引。
- SubSegment: 仅迭代开始索引后一段数量范围内的成员。
- Startup: 在当前迭代器之前拼接一个或多个成员 (迭代器)
- Endeavor: 在当前迭代器之后拼接一个或多个成员 (迭代器)
- Join: 将当前迭代器加入到字符串,可以设置如何开头,结尾,成员分割符。
- Merge: 将当前迭代器合并,可以实现类似sum的操作。
- EqualitySet: 比较两个迭代器里的成员是否相等。
- Shift: 偏移列表,也可以使用
RingShift,CyclicShift循环偏移。 - 包含针对
IList<KeyValuePair<TKey, TValue>>的Add,TryAdd,AddUnique,Remove,Modify,Contains,IndexOf,GetValue,GetKey,GetKeys,GetValues方法。 - BinarySearch: 二分法遍历
- FindClosestIndexByBinarySearch: 基于浮点数的二分法查找方法。
- IsIndexGreaterZeroLessCount:
- AddByIndex: 在索引处添加目标,如果索引不存在,则用default填充;如果目标已经存在,就替换。
- TryDoAtIndex: 尝试在索引处执行些什么,如果索引不存在,则什么都不做。
- ReplaceList: 使用一个列表替换另一个列表,允许通过自定义增删改方法修改 (和DiscrepancyOrder作用几乎一致,不过这个会因为条件不满足而产生报错) 。
- DiscrepancyOrder: 列表顺序差异,从源到目标列表的差异会通过委托开放,允许自定义删除,增加,替换来完成修改。
- TryGetAtIndex: 尝试读取索引处的成员。
- ForceDoAtIndex: 强制在索引处执行些什么,如果执行处的对象不存在或为空,则委托目标是null。
- ForceGetAtIndex: 强制在索引处获取成员,如果执行处的对象不存在或为空,则返回目标是defualt。
消息库 MacroMessage
预设一些消息处理流程。
-
全局业务分发器,消息入口Entry。
特点是需要通过指定消息入口(
RedirectReceiverMessage)和出口(RedirectReceiver)来中转消息。
完成后消息发送时会被进行一次包装,将带有入口名称的内容一同发送;而在消息处理的另一端,也需要用相同的逻辑处理这个包,就能获得这个包来自哪,并自动定位到对应的预定义委托上进行处理。 下面是一个接收示例:// 声名一个消息处理器委托 // 接收器形参可以是任何可以序列化的结构,或是无形参接收器。 public MacroMessage.ReceiverObject<int> myFunc; public void Awake() { // 初始化函数中注册这个委托,并赋予一个名称用于标识 myFunc.RedirectReceiver(nameof(myFunc)); myFunc += Func; } // 处理消息 public void Func(int number) { // 消息处理 }下面是一个发送示例:
// 在收到文本消息后,立刻发送给重定向器 void OnMessage(string message) { MacroMessage.RedirectReceiverMessage(message); }最后,需要定义何时处理消息:
// 比如放在帧更新事件中,消息会作为队列加入,然后逐个处理。 void Update() { MacroMessage.MainThreadProcessingMessage(); } -
方法封装器 提供一个方法软引用封装器,首先需要将一个可执行流程转换为
CallableTarget对象。然后通过AddCallableFunction添加到全局字典中,随后可以通过TryEvocation或者Evocation调用。 方法封装器默认可以搜索所有静态,实例,私有,公共的方法
对象宏
在gameobject或transform上快速迭代的操作库。
- 场景迭代
- 获取当前场景中的所有根对象:
GetActiveSceneRootGameObjects。 - 在所有已激活场景中查找组件:
GetAllSceneComponents。
- 获取当前场景中的所有根对象:
- 节点迭代
- 获取父级迭代器:
GetParents。 - 获取子级迭代器:
GetChildren。 - 获取广度优先的子级迭代器:
GetChildrenBFS。(带有黑白名单,可以屏蔽迭代过程中的节点) - 获取深度优先的子级迭代器:
GetChildrenRecursion。(不要使用 GetChildrenDFS,存在严重性能缺陷)
- 获取父级迭代器:
- 组件迭代
- 在当前位置无论如何都获取一个组件,如果没有就创建:
GetComponentAnyway。 - 在节点迭代器中找一个组件:
GetComponent。 - 将节点迭代器转为一一对应的组件迭代器:
GetComponentsOTO。 - 将节点迭代器转为组件迭代器:
GetComponentsOTOD。 - 在当前节点的所有子成员 (包含子成员的子成员) 内查找多个组件:
GetComponentsInRecursionChildren。 - 按照给定的组件顺序在节点迭代器中逐一查找:
GetFavoriteComponent。
- 在当前位置无论如何都获取一个组件,如果没有就创建:
- 家族迭代
- 获取当前节点的家族名称:
GetFamilyName。 - 使用家族名称搜索节点:
FindFamilyMember。(支持一次重定向,以及逐级名称模糊查找)
- 获取当前节点的家族名称:
以上仅包含大致用法,实际上包含更多的重载用法。
PID宏
提供一个PID计算器,具有基本的pid计算,同时带有基本安全计算。
对象池宏
预设快速设置的对象池 (CreatSimplePool) 与顺序对象池 (CreatObjectInOrderPool) ,传入预制体与父级,将直接返回一个预设的对象池。
提供一个联合对象池 (预设的) MacroPool.UnionSet,支持开放预制体目标与父级目标参数到inspector。
联合对象池需要手动调用Init函数进行初始化。
矩形变换宏
超驰宏
- 签名转换:通过GetFieldsRename 获取给定名称的字段在自定义的重命名特性上的名称。
- 软接口:
SoftInterface通过名称直接设置或获取值, 支持在一个对象上获取一系列名称的值,或在一系列对象上获取同一个名称的值,或是反过来设置他们。 - 实例化:通过
OverridingInstance创建给定类的实例,支持通过全名
正则宏
提供了常用的正则匹配模式。
- GeneralVector:多维矢量文本匹配
- ObjMesh:obj模型参数匹配 (匹配的同时会转换坐标系到unity)
- RegexReplace: 直接使用编辑器常用语法进行替换,比如"$1"获取第一个匹配项并输出。
仓库宏
材质宏
平滑宏
包含28个常用插值函数,可以使用SwitchEasing对一个数值计算插值,返回重新映射插值位置的数值。
插值函数可以单独调用,或使用枚举切换。
排序宏
c#自带的排序很好用,但是选择何种排序模式是根据数据类型自动切换的。
在这里,排序宏中提供了一些可以手动选择的排序算法。
注:没有猴子排序。
文本宏 MacroMath
提供:
-
StringBuilderPool: 文本构建池
-
join: 文本序列拼接。
List<object> objects = new List<object>(); objects.Join(obj => obj.ToString(), ) -
文本判断:空判断,空格判断,相等判断,字符集判断
-
格式包裹:支持TMP的26个富文本标签,或者自行扩展更多包裹器。
包裹器可以依靠多态模型来构建文本,而不依赖字面量构建。下面是一个示例:_blockBuilder = new TextBlockBuilder( new ColorBlock(Color.white, "重量"), new DelegateBlock(() => value.ToString()), new SizeBlock(20, "kg")));TextBlockBuilder 是所有blocker的基类,使用它包裹所有文本将起到单纯拼接文本的作用;TextBlockBuilder 里的三个block的作用是使用相应的富文本标签包裹,根据标签的类型,包裹器会自动决定标签格式。
DelegateBlock的作用是通过委托来实时获取一个变量,示例中直接获取value的文本值,拼接到结果中。
TextBlockBuilder 可以不依靠如DelegateBlock这样的包裹器,可以直接将返回字符串类型的方法委托传入,blocker 会自动识别;前提是开启对应 blocker 里的compatibility兼容性检查,但这会带来额外的性能开销,如果没有特别的需求,建议还是使用DelegateBlock进行多态封装,这样也会更安全。在新的更新中,包裹器支持域写法,同时可以省略部分参数:
_blockBuilder = new TextBlockBuilder() { new ColorBlock() // 默认值就是白色 { "重量" }, new DelegateBlock(() => value.ToString()), new SizeBlock(20) // 默认单位为像素 { "kg" } };这里的作用与上面的示例完全一致,更新的包裹器中支持自动填入更多的默认值了,比如颜色默认为白色。 虽然看起来更长了,但是对于较复杂的格式来说可以有更强的可读性,建议这样写。
同时,委托包裹器并不是唯一设置动态参数的方式:
SetParamters:在根包裹器上使用赋值方法,可以将一系列值一一对应地填入到后续一系列包裹器中。RefernceBlock:反射包裹器允许传入一个对象,以及成员名称来访问属性 (字段,访问器,方法均可) 。ValueBlock:值包裹器,搭配SetParamters来设置值,目标需要实现Tostring方法。NumberValueBlock数值类型包裹器,搭配SetParamters来设置值,设置值会自动限制在最大最小范围内,如果给定的参数是字符串类型,将尝试通过默认的格式化方法转为数值。
在实际使用时,只有
ValueBlock默认会从SetParamters参数列表中获取值, 其他包裹器需要手动通过SetParameterization参数化包裹器,否则不会响应参数列表。值得时刻注意的是,
SetParamters传递的值需要按深度优先的顺序逐一匹对,基本上可以认为是blockBuilder定义时的block先后顺序。
如果SetParamters中参数数量少于需求,在匹配时将会提前退出,导致后续值保持不变; 如果遇到强制类型检查的block且值无法匹配,block不会处理这个值,而是丢给下一个,只有遇到这种情况时,索引才有可能不是一一对应的形式。(默认认为是这么处理的,具体行为可以由block自己定义)关于性能:这种做法绝对不是省油的灯,绝对不要在运行时重复创建,而是声名在当前作用域的全局用作静态,或保持实例唯一。
-
文本转换:自动值转换为文本。
-
NumberToChinese:将数值转为中文大写。
-
沃格纳费舍尔拼写检查器:检查一对或多对文本是否相似,返回最相似的文本序列,及相似度。
-
ListToString:打印数组
文本构建池 (StringBuilderPool)
提供一个全局的文本构建对象池,可以通过MacroMath.StringBuilderPool访问这个对象池,下面是用例:
public string GetString()
{
StringBuilder sb = MacroMath.GetStrBuilder();
sb.Append("something...");
return MacroMath.ReleaseStrBuilder(sb);
}
可以看到,在对象池上释放这个构建器对象可以立刻获得里面的内容,可以省略部分内容。
另外提供了一个单线程上的文本拼接器单例:
MacroMath.CleanString(); // 先清空,避免有污染
MacroMath.AppendString("some"); // 拼接单个文本
MacroMath.BuildString("thing", "..."); // 拼接多个文本
MacroMath.GetStringAndClear(); // 返回 something...
文本序列拼接 (Join)
提供join方法,可以快速将一个枚举对象构建为类似(1,2,3,4)这样的文本。
List<object> objects = new List<object>();
objects.Join(obj => obj.ToString(), "(", ")", ",") // 可以指定开头,结尾,分隔符。
文本判断
空判断,空格判断,相等判断,字符集判断
格式包裹:
支持TMP的26个富文本标签,也可以通过自定义扩展。
包裹器可以依靠多态模型来构建文本,而不依赖字面量构建。下面是一个示例:
_blockBuilder = new TextBlockBuilder(
new ColorBlock(Color.white, "重量"),
new NumberValueBlock(1.23),
new SizeBlock(20, "kg")));
_blockBuilder.ToString(); // <color=white>重量</color>1.23<size=20>kg</size>
文本转换:
自动值转换为文本。
NumberToChinese
将数值转为中文大写。
沃格纳费舍尔拼写检查器
检查一对或多对文本是否相似,返回最相似的文本序列,及相似度。
ListToString
打印数组
[时间宏]
[轴变换宏]
[类型扩展]
[矢量扩展]
[导航宏]
提供寻路算法核,寻路几何体构造器 (未实装) 。
- AStart寻路算法核
通过AStart2提供,算法核只包含计算过程,需要被计算的对象上实现接口IAstartNavNeighborNode。
接口中需要定义当前“可寻路对象”的距离模式,相邻代价,以及所有邻居。 如果需要定义管理器,可使用AStartNode进行快速封装。
[安全宏]
提供ProgramFlowSecurity类,以及相关的扩展和符属类型。
安全宏用于,当一个方法中需要通过委托等方法动态调用其他一个或多个方法时,如果其中的某个方法报错,会导致后续所有方法不可用,且调用这些方法的方法也会因为错误抛出而停止,且如果运行在unity关键阶段,比如awake时,可能还会导致脚本被disable。
使用安全宏封装要调用的委托,并指定调用时的标识位,当产生错误时,安全宏会捕获这个错误,并转为抛出错误信息,如果选择默认解决,那么这个错误将不会影响后续运行。
但当下次调用时,安全宏将再次抛出一个错误信息,表示已经发生错误的委托被再次调用。
[转换宏]
[事件触发宏]
针对EventTrigger提供更快速的添加方法。