Class: Pindo::Unity::UnityEnvHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/pindo/module/unity/unity_env_helper.rb

Overview

Unity 环境管理助手负责 Unity 版本查找、路径管理等环境相关功能所有方法均为类方法,无需实例化

Constant Summary collapse

UNITY_MAC_PATHS =

macOS Unity 安装路径

[
  "/Applications/Unity/Unity.app/Contents/MacOS/Unity",
  "/Applications/Unity/Hub/Editor/*/Unity.app/Contents/MacOS/Unity",
  "/Applications/Unity/*/Unity.app/Contents/MacOS/Unity"
]
UNITY_WINDOWS_PATHS =

Windows Unity 安装路径

[
  "C:/Program Files/Unity/Editor/Unity.exe",
  "C:/Program Files/Unity/Hub/Editor/*/Unity.exe",
  "C:/Program Files/Unity/*/Editor/Unity.exe"
]

Class Method Summary collapse

Class Method Details

.extract_version_from_path(path) ⇒ String?

从路径中提取 Unity 版本号

Parameters:

  • path (String)

    Unity 可执行文件路径

Returns:

  • (String, nil)

    版本号或 nil



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
# File 'lib/pindo/module/unity/unity_env_helper.rb', line 114

def self.extract_version_from_path(path)
  # macOS路径格式: /Applications/Unity/Hub/Editor/2021.3.45f1/Unity.app/Contents/MacOS/Unity
  # macOS路径格式(变体): /Applications/Unity/Hub/Editor/2021.3.45f1c1/Unity.app/Contents/MacOS/Unity
  # macOS路径格式(旧版): /Applications/Unity/Unity.app/Contents/MacOS/Unity
  # Windows路径格式: C:/Program Files/Unity/Hub/Editor/2021.3.45f1/Editor/Unity.exe
  # Windows路径格式(变体): C:/Program Files/Unity/Hub/Editor/2021.3.45f1c1/Editor/Unity.exe
  # Windows路径格式(旧版): C:/Program Files/Unity/Editor/Unity.exe

  # 尝试匹配 macOS Hub 路径格式
  if match = path.match(/Editor\/([\d.]+[a-zA-Z]\d+(?:c\d+)?)\//)
    return match[1]
  end

  # 尝试匹配 Windows Hub 路径格式
  if match = path.match(/([\d.]+[a-zA-Z]\d+(?:c\d+)?)\/Editor\//)
    return match[1]
  end

  # 尝试匹配 macOS 旧版路径格式 (从Info.plist提取版本)
  if match = path.match(/Unity\.app\/Contents\/MacOS\/Unity$/)
    info_plist_path = File.join(File.dirname(File.dirname(path)), "Info.plist")
    if File.exist?(info_plist_path)
      begin
        content = File.read(info_plist_path)
        if content =~ /<key>CFBundleVersion<\/key>\s*<string>([^<]+)<\/string>/
          return $1.strip
        elsif content =~ /<key>CFBundleShortVersionString<\/key>\s*<string>Unity version ([^<]+)<\/string>/
          return $1.strip
        end
      rescue => e
        puts "警告: 无法读取Info.plist文件: #{e.message}"
      end
    end
  end

  # 尝试匹配 Windows 旧版路径格式
  if match = path.match(/Unity\.exe$/)
    # 对于旧版Unity,尝试从父目录获取版本信息
    parent_dir = File.dirname(path)
    if File.basename(parent_dir) =~ /^([\d.]+[a-zA-Z]\d+(?:c\d+)?)$/
      return $1
    end
  end

  nil
end

.find_unity_path(project_unity_version: nil, force_change_version: false) ⇒ String

查找 Unity 路径

Parameters:

  • project_unity_version (String) (defaults to: nil)

    项目所需的 Unity 版本

  • force_change_version (Boolean) (defaults to: false)

    是否强制使用最新版本

Returns:

  • (String)

    Unity 可执行文件的完整路径



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
# File 'lib/pindo/module/unity/unity_env_helper.rb', line 25

def self.find_unity_path(project_unity_version: nil, force_change_version: false)
  if project_unity_version.nil? || project_unity_version.empty?
    raise "Project Unity version is nil or empty"
  end

  unity_major_version = project_unity_version.split('.')[0..1].join('.')
  paths = case RUBY_PLATFORM
          when /darwin/
            UNITY_MAC_PATHS
          when /mswin|mingw|windows/
            UNITY_WINDOWS_PATHS
          else
            raise "Unsupported platform: #{RUBY_PLATFORM}"
          end

  unity_versions = []

  paths.each do |path|
    if path.include?("*")
      Dir.glob(path).each do |expanded_path|
        version = extract_version_from_path(expanded_path)
        if version
          major_version = version.split('.')[0..1].join('.')
          unity_versions << {
            path: expanded_path,
            version: version,
            major_version: major_version
          }
        end
      end
    elsif File.exist?(path)
      version = extract_version_from_path(path)
      if version
        major_version = version.split('.')[0..1].join('.')
        unity_versions << {
          path: path,
          version: version,
          major_version: major_version
        }
      end
    end
  end

  if unity_versions.empty?
    puts "调试信息: 搜索的Unity路径:"
    paths.each do |path|
      puts "  - #{path}"
      if path.include?("*")
        Dir.glob(path).each do |expanded_path|
          puts "    展开: #{expanded_path}"
        end
      elsif File.exist?(path)
        puts "    存在: #{path}"
      else
        puts "    不存在: #{path}"
      end
    end
    raise Informative, "未找到任何Unity版本,请检查Unity是否正确安装"
  end

  # 精确匹配项目版本
  select_unity_versions = unity_versions.select { |v| v[:version] == project_unity_version } || []
  if !select_unity_versions.nil? && !select_unity_versions.empty? && select_unity_versions.length >= 1
    return select_unity_versions.first[:path]
  end

  # 按主版本匹配
  unity_versions.sort_by! { |v| v[:major_version] }
  select_unity_versions = unity_versions.select { |v| v[:major_version] == unity_major_version } if unity_major_version
  if select_unity_versions.nil? || select_unity_versions.empty?
    if force_change_version
      puts "强制使用最新版本: #{unity_versions.last[:version]}"
      return unity_versions.last[:path]
    else
      puts "调试信息: 项目Unity版本: #{project_unity_version}"
      puts "调试信息: 可用的Unity版本:"
      unity_versions.each do |v|
        puts "  - #{v[:version]} (#{v[:major_version]})"
      end
      raise Informative, "未找到匹配的Unity版本 #{project_unity_version},可用的版本: #{unity_versions.map { |v| v[:version] }.join(', ')}"
    end
  else
    return select_unity_versions.first[:path]
  end
end

.get_unity_version(project_path) ⇒ String

获取项目的 Unity 版本

Parameters:

  • project_path (String)

    Unity 项目路径

Returns:

  • (String)

    Unity 版本号



177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/pindo/module/unity/unity_env_helper.rb', line 177

def self.get_unity_version(project_path)
  version_path = File.join(project_path, "ProjectSettings", "ProjectVersion.txt")
  if File.exist?(version_path)
    content = File.read(version_path)
    if content =~ /m_EditorVersion: (.*)/
      version = $1.strip
      version
    else
      raise "Could not parse Unity version from #{version_path}"
    end
  else
    raise "Project version file not found at #{version_path}"
  end
end

.unity_project?(project_path) ⇒ Boolean

检查是否为有效的 Unity 项目

Parameters:

  • project_path (String)

    项目路径

Returns:

  • (Boolean)

    true 如果是有效的 Unity 项目



195
196
197
198
199
200
201
202
203
204
205
# File 'lib/pindo/module/unity/unity_env_helper.rb', line 195

def self.unity_project?(project_path)
  # 检查关键Unity工程文件和目录是否存在
  project_settings_path = File.join(project_path, "ProjectSettings")
  assets_path = File.join(project_path, "Assets")
  packages_path = File.join(project_path, "Packages")

  File.directory?(project_settings_path) &&
  File.directory?(assets_path) &&
  File.directory?(packages_path) &&
  File.exist?(File.join(project_settings_path, "ProjectSettings.asset"))
end

.version_less_than?(v1, v2) ⇒ Boolean

比较版本号 (语义化版本比较)

Parameters:

  • v1 (String)

    版本1

  • v2 (String)

    版本2

Returns:

  • (Boolean)

    true 如果 v1 < v2, false 否则



165
166
167
168
169
170
171
172
# File 'lib/pindo/module/unity/unity_env_helper.rb', line 165

def self.version_less_than?(v1, v2)
  return false if v1.nil? || v2.nil?

  Gem::Version.new(v1) < Gem::Version.new(v2)
rescue ArgumentError
  # 版本格式无效时的降级处理
  v1.to_s < v2.to_s
end