unity自定义语法编译器最终实现逻辑

自定义语法的实现主要通过以下模块协作完成,涉及从文本输入到脚本编译和执行的完整流程。以下是核心逻辑的总结:

1. 文本处理与分词(Tokenizer.cs)

  • 功能:将输入的脚本文本分解为 Token,识别关键字、方法、参数、块等。
  • 实现
    • 通过 Tokenizer 类处理逐行文本,识别 Cycle(如 Now、Once、Loop)、MethodStatementComment 等 token 类型。
    • 使用正则表达式(KeywordRegex)在分词前替换全局关键字(如中文“若”替换为“if”),支持中文编程和简易语法。
    • 支持中文标点转换为英文标点(如“:”转为“:”),统一格式。
    • 处理块结构({}),支持嵌套块(如方法定义或条件语句)。
    • 跳过引号内的内容,避免误替换字符串中的关键字。
  • 关键点
    • 全局替换表(ScriptSyntax.GlobalVariables)简化了语法扩展,允许中文编程和自定义简写。

2. 语法解析(CommonParser.cs 和 UnifiedCompiler.cs)

  • 功能:将 token 解析为 CommandScriptStatement,构建 ScriptStructure
  • 实现
    • CommonParser.ParseTokens:遍历 token,识别周期类型(Now、Once、Loop、Import、Value、Method),解析方法调用和参数。
    • 支持嵌套命令(NestedCommands)和显式目标对象(target 参数)。
    • UnifiedCompiler:负责具体语句的识别,转换为 Command 对象,处理方法调用、赋值、移动等。
    • 参数以字符串形式存储,延迟类型解析到运行时,增加灵活性。
    • ScriptStructure 存储解析结果,包含各类命令(Now、Once、Loop)、导入语句、变量声明、方法定义和剩余语句。
  • 关键点
    • 解析支持简易语法(如 move up 1 转为 Move 命令)。
    • 保留未识别的语句(RemainingStatements),允许混合原生 C# 代码。
    • 方法定义(MethodDefinition)支持自定义方法,解析方法签名和体内的语句。

3. 代码生成(CodeGenerator.cs)

  • 功能:将 ScriptStructure 转换为可执行的 C# 脚本,分为 MainScript(Once 和 Loop)和 NowScript(Now)。
  • 实现
    • GenerateMainScript
      • 生成 Start 方法(Once 命令)和 Update 方法(Loop 命令)。
      • 包含导入语句(using)、变量声明(ValueStatements)和自定义方法。
      • 支持协程(IEnumerator)和普通方法调用,自动选择 StartCoroutine 或直接调用。
    • GenerateNowScript
      • 生成一次性执行的脚本,包含 ExecuteCommands 协程,依次执行 Now 命令。
      • 在执行完后销毁自身(Destroy(this))。
    • SerializeCommand:将 Command 序列化为方法调用,处理参数类型(如 Vector3、字符串等)和默认值。
    • ConvertValueToCSharp:将字符串参数转换为 C# 表达式(如 (1,2,3) 转为 new Vector3(1,2,3))。
  • 关键点
    • 区分协程和普通方法调用,避免 Loop 中重复启动协程。
    • 使用 RawParameters 保留原始参数格式,确保自定义方法调用正确。
    • 生成的脚本以唯一命名(Guid)避免冲突。

4. 脚本编译与附加(ScriptCompiler.cs)

  • 功能:将生成的 C# 代码编译为程序集并附加到 GameObject
  • 实现
    • 使用 Microsoft.CodeAnalysis 编译 C# 代码,引用 Unity 和系统程序集(cachedReferences)。
    • 异步编译(Task.Run 和协程),避免阻塞主线程。
    • 检查脚本内容是否变化,避免重复编译(lastCompiledScript)。
    • 移除旧脚本组件(GeneratedScriptTempNowScript),附加新编译的组件。
    • 缓存编译结果(compiledScripts),支持后续访问。
    • ParseScript:整合 token 解析,处理 Method 块,生成完整 ScriptStructure
  • 关键点
    • 编译优化显著(异步+缓存),无卡顿(2025/4/14 记录)。
    • 支持直接编译 C# 脚本(CompileCSharpScript),跳过原生解析。
    • 方法定义解析(ParseMethodDefinition)使用正则匹配签名,确保格式正确。

5. 运行时支持(ScriptFunctions.cs)

  • 功能:提供自定义方法库,供生成的脚本调用。
  • 实现
    • 包含移动(MoveMoveCoroutine)、旋转(Rotate)、缩放(Scale)、物理(ForceAddCollider)、事件(OnCollisionOnKeyPress)等方法。
    • 支持协程和普通版本,适应不同周期(Now 使用协程,Loop 使用普通)。
    • print 方法支持彩色输出(ScriptOutputDisplay),解析颜色字符串(如 "red"(1,0,0))。
    • 事件处理通过辅助类(CollisionHandlerKeyPressHandler 等)实现动态注册。
  • 关键点
    • 方法抽象化,减少脚本复杂度(如 Move 封装平滑移动逻辑)。
    • 物理和事件方法扩展了交互能力(如碰撞检测、鼠标点击)。

6. 用户交互(ObjectSelectionManager.cs 和 ScriptOutputDisplay.cs)

  • 功能:提供脚本编辑和输出界面,支持运行时交互。
  • 实现
    • ObjectSelectionManager
      • 允许选择场景对象(HandleSelection),高亮显示(highlightMaterial)。
      • 显示 UI 面板(ShowUI),编辑脚本(TMP_InputField)。
      • 保存脚本到 ES3,支持持久化(SaveInput)。
      • 触发编译(ProcessScriptAndSave),附加到选中对象。
    • ScriptOutputDisplay
      • 显示脚本输出(AddOutput),支持颜色和重复计数。
      • 自动清空输出(ClearOutput),确保界面干净。

7. 语法定义(ScriptSyntax.cs)

  • 功能:定义自定义语法的关键字、方法名、方向映射和替换规则。
  • 实现
    • KeywordsMethodNames:定义保留字和可调用方法。
    • DirectionMap:映射方向(如 upVector3.up)。
    • GlobalVariables:定义替换规则(如 引入 转为 Import 转为 "red")。
    • CycleTypes:支持 Now、Once、Loop、Import、Value、Method 周期。

此方悬停
相册 小说 Ai