18
HowToUseXericLibrary
李若辰 edited this page 2026-03-17 11:33:58 +08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

XericLibrary

清肃未知,编撰成库。

Xeric中使用宏 (Macro) 作为隔离用法的的单元,所有的操作都可以从MacroXX获取(XX是各个操作类模块的名称)。

特性库

  • CanFind$ 其中包含多个特性类,用于查找类,字段,属性,方法等项目。

  • ReName 重命名特性,在没有安装odin插件的旧版本引擎上可以直接替换细节面板中的参数名。
    不过由于无法和odin兼容,odin的功能会覆盖掉这个特性,同时在2018 (大概) 以上的版本中也没用。
    虽然大多数情况下不起作用,但仍可以使用配套的一系列方法来处理这个特性,如批量查找,ugui系统重命名等。

协程宏

调试宏

网格宏

电脑宏

相机宏

颜色宏

  • 随机颜色 使用RandomHueColor获取一个随机的颜色,随机数计算使用MacroMath库提供。

  • 文本转颜色 使用TryParseColorParseColorOrDefault将文本转为颜色,支持#RGB#RGBA#RRGGBB#RRGGBBAA格式,以及unitytextMeshPro的语义颜色,基本Web颜色。 这些颜色在正则宏中也可以处理。

配置文件宏

  • 网络配置文件 提供默认的异步保存和异步读取方法,通过MacroConfig.SaveUriConfigFileMacroConfig.ReadUriConfigFile访问。
    配置文件路径默认在streamAssets下的uriConfigFile里。
    注册MacroConfig.OnUriConfigFile事件来在场景加载前读取配置文件 (或自己创建一个) 。

  • 场景配置文件

常数宏 MacroConst

曲线宏 MacroCurve

日志宏 MacroDebug

提供XericLogger,通过XericLogger.CCLog可以输出一段日志,除去了追踪栈信息,并默认着色区分。

枚举宏 MacroEnum

枚举宏包含一个缓存封装器,可以通过MacroEnum\<enum\>来定义。
定义枚举结构封装将允许像列表一样访问这个枚举,或将枚举实例赋予,通过枚举封装器来操作枚举值。

方程宏

事件宏

文件宏 MacroFile

窗口宏 MacroForm

提供User32.dll中部分函数的功能。

  • 获取当前进程PIDPID
  • 通过句柄查找窗口: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>>AddTryAddAddUniqueRemoveModifyContainsIndexOfGetValueGetKeyGetKeysGetValues方法。
  • 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提供更快速的添加方法。