Skip to content

Commit 2bc178f

Browse files
committed
extract finding unity into a script
1 parent e351381 commit 2bc178f

2 files changed

Lines changed: 130 additions & 120 deletions

File tree

Directory.Build.targets

Lines changed: 11 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -25,132 +25,23 @@
2525
<SentryWindowsArtifactsDestination>$(SentryArtifactsDestination)Windows/Sentry/</SentryWindowsArtifactsDestination>
2626
</PropertyGroup>
2727

28-
<PropertyGroup>
29-
<HubSecondaryInstallPathFile>$(AppData)\UnityHub\secondaryInstallPath.json</HubSecondaryInstallPathFile>
30-
<HubDefaultEditorFile>$(AppData)\UnityHub\defaultEditor.json</HubDefaultEditorFile>
31-
<HubDefaultEditor Condition="'$(HubDefaultEditor)' == ''"></HubDefaultEditor>
32-
<HubInstallDir Condition="'$(HubInstallDir)' == '' AND $([MSBuild]::IsOSPlatform('Windows'))">C:\Program Files\Unity\Hub\Editor</HubInstallDir>
33-
<HubInstallDir Condition="'$(HubInstallDir)' == '' AND $([MSBuild]::IsOSPlatform('OSX'))">\Applications\Unity\Hub\Editor</HubInstallDir>
34-
<HubInstallDir Condition="'$(HubInstallDir)' == '' AND $([MSBuild]::IsOSPlatform('Linux'))">$(Home)\Unity\Hub\Editor</HubInstallDir>
35-
<HubInstallDir Condition="!Exists('$(HubInstallDir)')"></HubInstallDir>
36-
</PropertyGroup>
37-
38-
<Target Name="FindHub"
39-
Condition="'$(HubInstallDir)' == '' AND Exists('$(HubSecondaryInstallPathFile)')"
40-
Returns="$(HubInstallDir);$(HubDefaultEditor)">
41-
42-
<ReadLinesFromFile File="$(HubSecondaryInstallPathFile)">
43-
<Output TaskParameter="Lines" ItemName="item1" />
44-
</ReadLinesFromFile>
45-
46-
<ReadLinesFromFile File="$(HubDefaultEditorFile)" Condition="Exists('$(HubDefaultEditorFile)')">
47-
<Output TaskParameter="Lines" ItemName="item2" />
48-
</ReadLinesFromFile>
49-
50-
<PropertyGroup>
51-
<HubInstallDir>@(item1->Replace('"', ''))</HubInstallDir>
52-
<HubInstallDir Condition=" !Exists('$(HubInstallDir)') "></HubInstallDir>
53-
54-
<HubDefaultEditor>@(item2->Replace('"', ''))</HubDefaultEditor>
55-
<HubDefaultEditor Condition=" !Exists('$(HubInstallDir)\$(HubDefaultEditor)') "></HubDefaultEditor>
56-
</PropertyGroup>
57-
</Target>
58-
59-
<!-- Use the Unity Editor version set in the sample project of the repo -->
60-
<Target Name="FindUnity" DependsOnTargets="FindHub" AfterTargets="FindHub">
28+
<Target Name="FindUnity">
6129
<Message Text="Unity Version: $(UnityVersion)" Importance="Normal" />
6230

63-
<!-- Find all the installations of Unity done by the Unity Hub -->
64-
<ItemGroup Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' == ''">
65-
<_AllUnityInstallDirs Include="$([System.IO.Directory]::GetDirectories('$(HubInstallDir)'))" />
66-
<_UnityInstalls Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)', '^[\d]{4}.*$'))" Include="@(_AllUnityInstallDirs->'%(Filename)%(Extension)')" />
67-
</ItemGroup>
68-
69-
<!-- Pick the latest one if this version of the Hub doesn't record a default version -->
70-
<PropertyGroup Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' == ''">
71-
<HubDefaultEditor>%(_UnityInstalls.Identity)</HubDefaultEditor>
72-
</PropertyGroup>
73-
74-
<PropertyGroup>
75-
<_UnityInnerPath Condition="!$([MSBuild]::IsOSPlatform('OSX'))">Editor\Data</_UnityInnerPath>
76-
<_UnityInnerPath Condition="$([MSBuild]::IsOSPlatform('OSX'))">Unity.App\Contents</_UnityInnerPath>
77-
</PropertyGroup>
78-
79-
<ItemGroup>
80-
<!-- Unity 6000.3+ relocated managed assemblies under Resources\Scripting\Managed.
81-
Each candidate carries Root metadata so the post-selection block doesn't have
82-
to reverse-engineer the layout. New layout is probed first within each slot. -->
83-
<_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''"
84-
Include="$(UNITY_PATH)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll"
85-
Root="$(UNITY_PATH)\" />
86-
<_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''"
87-
Include="$(UNITY_PATH)\$(_UnityInnerPath)\Managed\UnityEngine.dll"
88-
Root="$(UNITY_PATH)\" />
89-
90-
<_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''"
91-
Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll"
92-
Root="$(HubInstallDir)\$(UnityVersion)\" />
93-
<_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''"
94-
Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Managed\UnityEngine.dll"
95-
Root="$(HubInstallDir)\$(UnityVersion)\" />
96-
97-
<_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'"
98-
Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll"
99-
Root="$(HubInstallDir)\$(HubDefaultEditor)\" />
100-
<_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'"
101-
Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Managed\UnityEngine.dll"
102-
Root="$(HubInstallDir)\$(HubDefaultEditor)\" />
103-
104-
<_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))"
105-
Include="C:\Program Files\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll"
106-
Root="C:\Program Files\Unity\" />
107-
<_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))"
108-
Include="C:\Program Files\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll"
109-
Root="C:\Program Files\Unity\" />
110-
111-
<_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))"
112-
Include="\Applications\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll"
113-
Root="\Applications\Unity\" />
114-
<_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))"
115-
Include="\Applications\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll"
116-
Root="\Applications\Unity\" />
117-
118-
<_UnityPathsFound Include="@(_PotentialUnityPaths->Exists())" />
119-
<_UnityPathsFoundReversed Include="@(_UnityPathsFound->Reverse())" />
120-
</ItemGroup>
31+
<Exec
32+
Command="pwsh -NoProfile -File &quot;$(RepoRoot)scripts/find-unity.ps1&quot; -UnityVersion &quot;$(UnityVersion)&quot; -HubInstallDir &quot;$(HubInstallDir)&quot; -HubDefaultEditor &quot;$(HubDefaultEditor)&quot;"
33+
ConsoleToMSBuild="true">
34+
<Output TaskParameter="ConsoleOutput" PropertyName="_FindUnityOutput" />
35+
</Exec>
12136

12237
<PropertyGroup>
123-
<!-- "Last one wins" trick — reversed list yields the first match. Metadata rides along. -->
124-
<_UnityPathProp>%(_UnityPathsFoundReversed.Identity)</_UnityPathProp>
125-
<_UnityRootProp>%(_UnityPathsFoundReversed.Root)</_UnityRootProp>
38+
<UnityRoot>$([System.Text.RegularExpressions.Regex]::Match($(_FindUnityOutput), 'UnityRoot=([^;\r\n]+)').Groups[1].Value)</UnityRoot>
39+
<UnityDataPath>$([System.Text.RegularExpressions.Regex]::Match($(_FindUnityOutput), 'UnityDataPath=([^;\r\n]+)').Groups[1].Value)</UnityDataPath>
40+
<UnityManagedPath>$([System.Text.RegularExpressions.Regex]::Match($(_FindUnityOutput), 'UnityManagedPath=([^;\r\n]+)').Groups[1].Value)</UnityManagedPath>
41+
<UnityLibcache>$(UnityDataPath)Resources/PackageManager/ProjectTemplates/libcache/</UnityLibcache>
12642
</PropertyGroup>
12743

128-
<Message
129-
Condition="'$(UnityVersion)' != '' AND '$(HubInstallDir)' != ''
130-
AND !Exists('$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Managed\UnityEngine.dll')
131-
AND !Exists('$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll')
132-
AND '$(_UnityPathProp)' != ''"
133-
Text="Unity version $(UnityVersion) is not installed. Falling back to default Unity installation."
134-
Importance="High" />
135-
136-
<ItemGroup>
137-
<!-- Turn the property back into an item so we can use DirectoryName() below. -->
138-
<_UnityPath Include="$(_UnityPathProp)" />
139-
</ItemGroup>
140-
141-
<PropertyGroup Condition="'$(_UnityPathProp)' != ''">
142-
<UnityRoot>$(_UnityRootProp)</UnityRoot>
143-
<UnityDataPath>$(UnityRoot)$(_UnityInnerPath)\</UnityDataPath>
144-
<UnityManagedPath>@(_UnityPath->DirectoryName())\</UnityManagedPath>
145-
<UnityLibcache>$(UnityDataPath)Resources\PackageManager\ProjectTemplates\libcache\</UnityLibcache>
146-
</PropertyGroup>
147-
148-
<Error Condition="'$(UnityRoot)' == ''" Text="UnityRoot not found. Ensure Unity is installed.
149-
See the CONTRIBUTING.md.
150-
UnityVersion: '$(UnityVersion)'
151-
Expected to exist:
152-
* @(_PotentialUnityPaths, '%0a or %0a * ')" />
153-
44+
<Error Condition="'$(UnityRoot)' == ''" Text="UnityRoot not resolved — see scripts/find-unity.ps1 output above." />
15445

15546
<!-- Unity paths on Windows -->
15647
<PropertyGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">

scripts/find-unity.ps1

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env pwsh
2+
# Locate a Unity installation and emit the paths the build needs.
3+
#
4+
# Output (stdout, one per line):
5+
# UnityRoot=<dir containing the Unity executable, trailing slash>
6+
# UnityDataPath=<dir containing the Editor data, trailing slash>
7+
# UnityManagedPath=<dir containing UnityEngine.dll, trailing slash>
8+
#
9+
# Warnings + the "candidates tried" error go to stderr. Exits non-zero on failure.
10+
11+
[CmdletBinding()]
12+
param (
13+
[string] $UnityVersion = '',
14+
[string] $HubInstallDir = '',
15+
[string] $HubDefaultEditor = ''
16+
)
17+
18+
$ErrorActionPreference = 'Stop'
19+
20+
function Read-HubFile([string] $path) {
21+
if (-not (Test-Path $path)) { return '' }
22+
# Unity Hub writes a single quoted string per file (not strict JSON).
23+
return (Get-Content -Raw $path).Trim().Trim('"')
24+
}
25+
26+
# --- Resolve Hub install dir + default editor -------------------------------
27+
28+
# AppData is Windows-only; on macOS/Linux we just rely on the platform default below.
29+
$hubConfigDir = if ($env:APPDATA) { Join-Path $env:APPDATA 'UnityHub' } else { '' }
30+
31+
if (-not $HubInstallDir -and $hubConfigDir) {
32+
$HubInstallDir = Read-HubFile (Join-Path $hubConfigDir 'secondaryInstallPath.json')
33+
}
34+
if (-not $HubInstallDir) {
35+
$HubInstallDir = if ($IsWindows) { 'C:/Program Files/Unity/Hub/Editor' }
36+
elseif ($IsMacOS) { '/Applications/Unity/Hub/Editor' }
37+
elseif ($IsLinux) { Join-Path $env:HOME 'Unity/Hub/Editor' }
38+
}
39+
if (-not (Test-Path $HubInstallDir)) { $HubInstallDir = '' }
40+
41+
if (-not $HubDefaultEditor -and $hubConfigDir) {
42+
$HubDefaultEditor = Read-HubFile (Join-Path $hubConfigDir 'defaultEditor.json')
43+
if ($HubDefaultEditor -and -not (Test-Path (Join-Path $HubInstallDir $HubDefaultEditor))) {
44+
$HubDefaultEditor = ''
45+
}
46+
}
47+
# Fallback: pick the highest version-named dir under the hub install root.
48+
if (-not $HubDefaultEditor -and $HubInstallDir) {
49+
$HubDefaultEditor = Get-ChildItem -Path $HubInstallDir -Directory -ErrorAction SilentlyContinue |
50+
Where-Object Name -Match '^\d{4}' |
51+
Sort-Object Name -Descending |
52+
Select-Object -First 1 -ExpandProperty Name
53+
}
54+
55+
# --- Build the probe list ---------------------------------------------------
56+
57+
# Layout pieces. macOS Unity ships as a .app bundle so the inner path differs.
58+
$inner = if ($IsMacOS) { 'Unity.App/Contents' } else { 'Editor/Data' }
59+
$rootName = if ($IsMacOS) { 'Unity.App' } else { 'Editor' }
60+
61+
# Each "install" candidate is a directory like <hub>/<version>/ that contains
62+
# either Editor/ (win/linux) or Unity.App/ (mac).
63+
$installs = [System.Collections.Generic.List[string]]::new()
64+
if ($IsLinux -and $env:UNITY_PATH) { $installs.Add($env:UNITY_PATH) }
65+
if ($HubInstallDir -and $UnityVersion) { $installs.Add((Join-Path $HubInstallDir $UnityVersion)) }
66+
if ($HubInstallDir -and $HubDefaultEditor -and $UnityVersion -ne $HubDefaultEditor) {
67+
$installs.Add((Join-Path $HubInstallDir $HubDefaultEditor))
68+
}
69+
if ($IsWindows) { $installs.Add('C:/Program Files/Unity') }
70+
if ($IsMacOS) { $installs.Add('/Applications/Unity') }
71+
72+
# Unity 6000.3+ moved managed assemblies under Resources/Scripting/Managed.
73+
# Probe the new layout first within each install.
74+
$dllRelatives = @('Resources/Scripting/Managed/UnityEngine.dll', 'Managed/UnityEngine.dll')
75+
76+
function Find-UnityDll([string] $install) {
77+
foreach ($rel in $dllRelatives) {
78+
$dll = Join-Path $install (Join-Path $inner $rel)
79+
if (Test-Path $dll) { return $dll }
80+
}
81+
return $null
82+
}
83+
84+
# Did the requested-version install yield a DLL? Drives the fallback warning below.
85+
$expected = if ($UnityVersion -and $HubInstallDir) { Join-Path $HubInstallDir $UnityVersion } else { '' }
86+
$shouldWarnFallback = $expected -and -not (Find-UnityDll $expected)
87+
88+
$tried = [System.Collections.Generic.List[string]]::new()
89+
90+
foreach ($install in $installs) {
91+
$dll = Find-UnityDll $install
92+
if (-not $dll) {
93+
$dllRelatives | ForEach-Object { $tried.Add((Join-Path $install (Join-Path $inner $_))) }
94+
continue
95+
}
96+
97+
if ($shouldWarnFallback) {
98+
Write-Warning "Unity version $UnityVersion is not installed. Falling back to default Unity installation."
99+
}
100+
101+
$unityRoot = (Join-Path $install $rootName) + '/'
102+
$unityDataPath = (Join-Path $install $inner) + '/'
103+
$unityManagedPath = (Split-Path $dll -Parent) + '/'
104+
105+
# Normalize to forward slashes — MSBuild accepts both, and it keeps the output diff-clean across platforms.
106+
Write-Output ("UnityRoot=" + ($unityRoot -replace '\\', '/'))
107+
Write-Output ("UnityDataPath=" + ($unityDataPath -replace '\\', '/'))
108+
Write-Output ("UnityManagedPath=" + ($unityManagedPath -replace '\\', '/'))
109+
exit 0
110+
}
111+
112+
$msg = @"
113+
Unity installation not found. See CONTRIBUTING.md.
114+
UnityVersion: '$UnityVersion'
115+
Expected one of:
116+
* $($tried -join "`n * ")
117+
"@
118+
Write-Error $msg
119+
exit 1

0 commit comments

Comments
 (0)