Class: Pindo::Unity::UnityCommandHelper
- Inherits:
-
Object
- Object
- Pindo::Unity::UnityCommandHelper
- Defined in:
- lib/pindo/module/unity/unity_command_helper.rb
Overview
Unity 命令执行助手负责执行 Unity 命令行操作所有方法均为类方法,无需实例化
Class Method Summary collapse
Class Method Details
.execute_unity_command(unity_exe_full_path, project_path, method: 'GoodUnityBuild.BuildManager.BatchBuild', additional_args: {}) ⇒ Hash
执行 Unity 命令
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/pindo/module/unity/unity_command_helper.rb', line 21 def self.execute_unity_command(unity_exe_full_path, project_path, method: 'GoodUnityBuild.BuildManager.BatchBuild', additional_args: {}) if unity_exe_full_path.nil? raise Informative, "Unity path not found!" end # 调试级别:通过环境变量或参数控制 debug_level = ENV['UNITY_BUILD_DEBUG'] || additional_args[:debug_level] || 'normal' # debug_level: 'quiet' - 只显示错误 # 'normal' - 显示错误、警告和关键进度 # 'verbose' - 显示所有输出 # 检查项目路径是否存在 unless File.directory?(project_path) raise Informative, "Unity项目路径不存在: #{project_path}" end # 检查项目是否是Unity项目 project_settings = File.join(project_path, "ProjectSettings") unless File.directory?(project_settings) raise Informative, "项目路径不是Unity项目: #{project_path}" end cmd_args = [ unity_exe_full_path, "-batchmode", "-quit", "-projectPath", project_path.to_s, "-executeMethod", method ] # Add any additional arguments additional_args.each do |key, value| cmd_args << "-#{key}" cmd_args << value.to_s if value end puts "Unity command: #{cmd_args.join(' ')}" puts "" # 使用更智能的进度检测机制 progress_thread = nil start_time = Time.now last_output_time = Time.now begin # 使用 Open3.popen3 来实时监控输出 Open3.popen3(*cmd_args) do |stdin, stdout, stderr, wait_thr| stdin.close # 启动进度显示线程 progress_thread = Thread.new do dots = 0 while wait_thr.alive? sleep(2) dots = (dots + 1) % 4 elapsed = (Time.now - start_time).to_i print "\r\e[33mUnity 构建中#{'.' * dots}#{' ' * (3 - dots)} (已用时: #{elapsed}秒)\e[0m" $stdout.flush end end # 实时读取输出 stdout_buffer = "" stderr_buffer = "" # 定义错误关键词模式(优化正则,避免重复) error_pattern = /error|exception|failed|Build completed with a result of 'Failed'/i warning_pattern = /warning|warn/i success_pattern = /Build completed successfully|Exiting batchmode successfully/i # 使用非阻塞方式读取输出 while wait_thr.alive? # 检查是否有输出可读 ready_streams = IO.select([stdout, stderr], nil, nil, 1) if ready_streams ready_streams[0].each do |stream| if line = stream.gets # 记录输出 if stream == stdout stdout_buffer += line else stderr_buffer += line end last_output_time = Time.now # 根据调试级别和内容类型显示输出 case debug_level when 'verbose' # 详细模式:显示所有输出 puts line when 'quiet' # 安静模式:只显示错误 if line.match?(error_pattern) puts "\e[31m[错误] #{line.strip}\e[0m" end else # 'normal' # 正常模式:显示错误、警告和关键进度 if line.match?(error_pattern) puts "\n\e[31m[错误] #{line.strip}\e[0m" elsif line.match?(warning_pattern) puts "\n\e[33m[警告] #{line.strip}\e[0m" elsif line.match?(success_pattern) puts "\n\e[32m[成功] #{line.strip}\e[0m" elsif line.match?(/\d+%/) || line.match?(/Building|Compiling|Processing/i) # 显示进度相关信息 print "\r\e[36m[进度] #{line.strip}\e[0m" $stdout.flush end end end end end end # 读取剩余输出 stdout_buffer += stdout.read stderr_buffer += stderr.read # 停止进度显示线程 progress_thread.kill if progress_thread # 检查构建是否真的成功 build_success = wait_thr.value.success? # 检查是否有构建错误的关键词 if stdout_buffer.match?(/Build completed with a result of 'Failed'|Build completed with a result of 'Cancelled'|BuildPlayerWindow\+BuildMethod\+Invoke|error|Error|ERROR|exception|Exception|EXCEPTION|failed|Failed|FAILED/) build_success = false # puts "\n\e[31m检测到构建错误信息,构建可能失败\e[0m" end if build_success print "\r\e[32mUnity 构建完成!\e[0m\n" # 构建完成后检查并清理可能的 Unity 进程残留 UnityProcHelper.cleanup_unity_processes_after_build(unity_exe_full_path: unity_exe_full_path, project_path: project_path) else print "\r\e[31mUnity 构建失败!\e[0m\n" puts "\e[31m构建输出:\e[0m" puts stdout_buffer if !stdout_buffer.empty? puts "\e[31m错误输出:\e[0m" puts stderr_buffer if !stderr_buffer.empty? # 构建失败时也清理可能的进程残留 UnityProcHelper.cleanup_unity_processes_after_build(unity_exe_full_path: unity_exe_full_path, project_path: project_path) end # 返回结果 { success: build_success, stdout: stdout_buffer, stderr: stderr_buffer, exit_status: wait_thr.value.exitstatus, unity_version: UnityEnvHelper.extract_version_from_path(unity_exe_full_path) } end rescue => e # 停止进度显示线程 progress_thread.kill if progress_thread print "\r\e[31mUnity 构建失败!\e[0m\n" raise e end end |