1use crate::io::read_file;
2use crate::paths::join_path;
3
4pub fn generate_version_defines(version: &str) -> Vec<String> {
7 let parts: Vec<&str> = version.split('.').collect();
8 if parts.len() < 3 {
9 return Vec::new();
10 }
11 let Ok(major) = parts[0].parse::<i32>() else {
12 return Vec::new();
13 };
14 let Ok(minor) = parts[1].parse::<i32>() else {
15 return Vec::new();
16 };
17 let mut patch_str = String::new();
18 for ch in parts[2].chars() {
19 if !ch.is_ascii_digit() {
20 break;
21 }
22 patch_str.push(ch);
23 }
24 let Ok(patch) = patch_str.parse::<i32>() else {
25 return Vec::new();
26 };
27
28 let mut defines = vec![
29 format!("UNITY_{}_{}_{}", major, minor, patch),
30 format!("UNITY_{}_{}", major, minor),
31 format!("UNITY_{}", major),
32 ];
33
34 const VERSION_POINTS: &[(i32, i32)] = &[
35 (5, 3), (5, 4), (5, 5), (5, 6),
36 (2017, 1), (2017, 2), (2017, 3), (2017, 4),
37 (2018, 1), (2018, 2), (2018, 3), (2018, 4),
38 (2019, 1), (2019, 2), (2019, 3), (2019, 4),
39 (2020, 1), (2020, 2), (2020, 3),
40 (2021, 1), (2021, 2), (2021, 3),
41 (2022, 1), (2022, 2), (2022, 3),
42 (2023, 1), (2023, 2), (2023, 3),
43 (2024, 1), (2024, 2), (2024, 3),
44 (2025, 1), (2025, 2), (2025, 3),
45 ];
46 for &(maj, min) in VERSION_POINTS {
47 if major > maj || (major == maj && minor >= min) {
48 defines.push(format!("UNITY_{}_{}_OR_NEWER", maj, min));
49 }
50 }
51 if major >= 6000 {
52 for m in 0..=minor {
53 defines.push(format!("UNITY_6000_{}_OR_NEWER", m));
54 }
55 }
56 defines
57}
58
59pub const DEFAULT_FEATURE_DEFINES: &[&str] = &[
62 "UNITY_INCLUDE_TESTS",
63 "ENABLE_AR", "ENABLE_AUDIO", "ENABLE_CACHING", "ENABLE_CLOTH",
64 "ENABLE_EVENT_QUEUE", "ENABLE_MICROPHONE", "ENABLE_MULTIPLE_DISPLAYS",
65 "ENABLE_PHYSICS", "ENABLE_TEXTURE_STREAMING", "ENABLE_LZMA",
66 "ENABLE_UNITYEVENTS", "ENABLE_VR", "ENABLE_WEBCAM",
67 "ENABLE_UNITYWEBREQUEST", "ENABLE_WWW",
68 "ENABLE_CLOUD_SERVICES", "ENABLE_CLOUD_SERVICES_ADS",
69 "ENABLE_CLOUD_SERVICES_USE_WEBREQUEST", "ENABLE_UNITY_CONSENT",
70 "ENABLE_UNITY_CLOUD_IDENTIFIERS",
71 "ENABLE_CLOUD_SERVICES_CRASH_REPORTING",
72 "ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING",
73 "ENABLE_CLOUD_SERVICES_PURCHASING",
74 "ENABLE_CLOUD_SERVICES_ANALYTICS", "ENABLE_CLOUD_SERVICES_BUILD",
75 "ENABLE_EDITOR_GAME_SERVICES",
76 "ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT",
77 "ENABLE_CLOUD_LICENSE", "ENABLE_EDITOR_HUB_LICENSE",
78 "ENABLE_CLOUD_SERVICES_ENGINE_DIAGNOSTICS",
79 "ENABLE_WEBSOCKET_CLIENT",
80 "ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API",
81 "ENABLE_DIRECTOR_AUDIO", "ENABLE_DIRECTOR_TEXTURE",
82 "ENABLE_MANAGED_JOBS", "ENABLE_MANAGED_TRANSFORM_JOBS",
83 "ENABLE_MANAGED_ANIMATION_JOBS", "ENABLE_MANAGED_AUDIO_JOBS",
84 "ENABLE_ENGINE_CODE_STRIPPING", "ENABLE_ONSCREEN_KEYBOARD",
85 "ENABLE_MANAGED_UNITYTLS", "INCLUDE_DYNAMIC_GI",
86 "ENABLE_SCRIPTING_GC_WBARRIERS", "PLATFORM_SUPPORTS_MONO",
87 "ENABLE_MARSHALLING_TESTS", "ENABLE_VIDEO",
88 "ENABLE_NAVIGATION_OFFMESHLINK_TO_NAVMESHLINK",
89 "ENABLE_ACCELERATOR_CLIENT_DEBUGGING", "ENABLE_ACCESSIBILITY",
90 "TEXTCORE_1_0_OR_NEWER",
91 "TEXTCORE_FONT_ENGINE_1_5_OR_NEWER", "TEXTCORE_TEXT_ENGINE_1_5_OR_NEWER",
92 "EDITOR_ONLY_NAVMESH_BUILDER_DEPRECATED",
93 "ENABLE_EGL", "ENABLE_NETWORK", "ENABLE_RUNTIME_GI",
94 "ENABLE_CRUNCH_TEXTURE_COMPRESSION", "ENABLE_FIREBASE_IDENTIFIERS",
95 "UNITY_CAN_SHOW_SPLASH_SCREEN",
96 "UNITY_HAS_GOOGLEVR", "UNITY_HAS_TANGO",
97 "ENABLE_SPATIALTRACKING", "ENABLE_ETC_COMPRESSION",
98 "PLATFORM_EXTENDS_VULKAN_DEVICE", "PLATFORM_HAS_MULTIPLE_SWAPCHAINS",
99 "PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP",
100 "PLATFORM_EXTENDS_VULKAN_PIPELINE_CACHE",
101 "PLATFORM_SUPPORTS_SPLIT_GRAPHICS_JOBS",
102 "PLATFORM_HAS_ADDITIONAL_API_CHECKS",
103 "PLATFORM_HAS_GRAPHICS_JOBS_SUPPORT_CHECK_OVERRIDE",
104 "PLATFORM_IMPLEMENTS_INSIGHTS_ANR",
105 "PLATFORM_SUPPORTS_INSIGHTS_DEVICE_INFO",
106 "ENABLE_ANDROID_ADVERTISING_IDS",
107 "PLATFORM_HAS_BUGGY_MSAA_RESOLVE",
108 "ENABLE_ANDROID_APP_SET_ID",
109 "ENABLE_INSIGHTS_PLATFORM_SPECIFIC_RESOURCES",
110 "ENABLE_UNITYADS_RUNTIME", "UNITY_UNITYADS_API",
111 "ENABLE_MONO", "NET_STANDARD_2_0", "NET_STANDARD", "NET_STANDARD_2_1",
112 "NETSTANDARD", "NETSTANDARD2_1",
113 "ENABLE_PROFILER", "ENABLE_UNITY_COLLECTIONS_CHECKS", "ENABLE_BURST_AOT",
114 "UNITY_TEAM_LICENSE", "UNITY_PRO_LICENSE",
115 "ENABLE_CUSTOM_RENDER_TEXTURE", "ENABLE_DIRECTOR",
116 "ENABLE_LOCALIZATION", "ENABLE_SPRITES", "ENABLE_TERRAIN",
117 "ENABLE_TILEMAP", "ENABLE_TIMELINE",
118 "ENABLE_LEGACY_INPUT_MANAGER",
119 "CSHARP_7_OR_LATER", "CSHARP_7_3_OR_NEWER",
120];
121
122pub fn parse_scripting_defines(project_root: &str) -> Vec<String> {
125 let path = join_path(project_root, "ProjectSettings/ProjectSettings.asset");
126 let Ok(content) = read_file(&path) else {
127 return Vec::new();
128 };
129
130 let mut in_section = false;
131 let mut all = std::collections::BTreeSet::new();
132
133 for line in content.split('\n') {
134 if line.starts_with(" scriptingDefineSymbols:") {
135 in_section = true;
136 continue;
137 }
138 if !in_section {
139 continue;
140 }
141 if !line.starts_with(" ") {
142 break;
143 }
144 if let Some(colon) = line.find(':') {
145 let value = line[colon + 1..].trim();
146 if !value.is_empty() {
147 for d in value.split(';') {
148 let d = d.trim();
149 if !d.is_empty() {
150 all.insert(d.to_string());
151 }
152 }
153 }
154 }
155 }
156 all.into_iter().collect()
157}