From 6564d6fda0c9d31f1b6e286051f9f249bff3a2d7 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 6 May 2026 17:08:01 +0200 Subject: [PATCH 1/4] added lookup for new structure --- Directory.Build.targets | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index 620b8f644..a48696ad4 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -77,10 +77,17 @@ + + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" Include="$(UNITY_PATH)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" Include="$(UNITY_PATH)\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> + <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> + <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" Include="C:\Program Files\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" Include="C:\Program Files\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" Include="\Applications\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" Include="\Applications\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> <_UnityPathsFound Include="@(_PotentialUnityPaths->Exists())" /> <_UnityPathsFoundReversed Include="@(_UnityPathsFound->Reverse())" /> @@ -92,7 +99,10 @@ @@ -105,6 +115,9 @@ @(_UnityPath->DirectoryName())\ @(_UnityPath->DirectoryName()->DirectoryName())\ @(_UnityPath->DirectoryName()->DirectoryName()->DirectoryName())\ + + @(_UnityPath->DirectoryName()->DirectoryName()->DirectoryName()->DirectoryName())\ + @(_UnityPath->DirectoryName()->DirectoryName()->DirectoryName()->DirectoryName()->DirectoryName())\ $(UnityDataPath)Resources\PackageManager\ProjectTemplates\libcache\ From e351381259533cb6ffe44beb85a5e3089b3757b9 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 7 May 2026 12:14:21 +0200 Subject: [PATCH 2/4] cleanup --- Directory.Build.targets | 60 ++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index a48696ad4..64b2766ad 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -77,25 +77,52 @@ - - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" Include="$(UNITY_PATH)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" Include="$(UNITY_PATH)\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" Include="C:\Program Files\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" Include="C:\Program Files\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" Include="\Applications\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" Include="\Applications\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" /> + + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" + Include="$(UNITY_PATH)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" + Root="$(UNITY_PATH)\" /> + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" + Include="$(UNITY_PATH)\$(_UnityInnerPath)\Managed\UnityEngine.dll" + Root="$(UNITY_PATH)\" /> + + <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" + Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" + Root="$(HubInstallDir)\$(UnityVersion)\" /> + <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" + Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Managed\UnityEngine.dll" + Root="$(HubInstallDir)\$(UnityVersion)\" /> + + <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" + Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" + Root="$(HubInstallDir)\$(HubDefaultEditor)\" /> + <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" + Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Managed\UnityEngine.dll" + Root="$(HubInstallDir)\$(HubDefaultEditor)\" /> + + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" + Include="C:\Program Files\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" + Root="C:\Program Files\Unity\" /> + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" + Include="C:\Program Files\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" + Root="C:\Program Files\Unity\" /> + + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" + Include="\Applications\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" + Root="\Applications\Unity\" /> + <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" + Include="\Applications\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" + Root="\Applications\Unity\" /> + <_UnityPathsFound Include="@(_PotentialUnityPaths->Exists())" /> <_UnityPathsFoundReversed Include="@(_UnityPathsFound->Reverse())" /> - + <_UnityPathProp>%(_UnityPathsFoundReversed.Identity) + <_UnityRootProp>%(_UnityPathsFoundReversed.Root) + $(_UnityRootProp) + $(UnityRoot)$(_UnityInnerPath)\ @(_UnityPath->DirectoryName())\ - @(_UnityPath->DirectoryName()->DirectoryName())\ - @(_UnityPath->DirectoryName()->DirectoryName()->DirectoryName())\ - - @(_UnityPath->DirectoryName()->DirectoryName()->DirectoryName()->DirectoryName())\ - @(_UnityPath->DirectoryName()->DirectoryName()->DirectoryName()->DirectoryName()->DirectoryName())\ $(UnityDataPath)Resources\PackageManager\ProjectTemplates\libcache\ From 2bc178fcf2cf1b61ca5efe4fc0bde13df14a96bf Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 7 May 2026 13:15:24 +0200 Subject: [PATCH 3/4] extract finding unity into a script --- Directory.Build.targets | 131 ++++------------------------------------ scripts/find-unity.ps1 | 119 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 120 deletions(-) create mode 100644 scripts/find-unity.ps1 diff --git a/Directory.Build.targets b/Directory.Build.targets index 64b2766ad..8f6613858 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -25,132 +25,23 @@ $(SentryArtifactsDestination)Windows/Sentry/ - - $(AppData)\UnityHub\secondaryInstallPath.json - $(AppData)\UnityHub\defaultEditor.json - - C:\Program Files\Unity\Hub\Editor - \Applications\Unity\Hub\Editor - $(Home)\Unity\Hub\Editor - - - - - - - - - - - - - - - @(item1->Replace('"', '')) - - - @(item2->Replace('"', '')) - - - - - - + - - - <_AllUnityInstallDirs Include="$([System.IO.Directory]::GetDirectories('$(HubInstallDir)'))" /> - <_UnityInstalls Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Filename)', '^[\d]{4}.*$'))" Include="@(_AllUnityInstallDirs->'%(Filename)%(Extension)')" /> - - - - - %(_UnityInstalls.Identity) - - - - <_UnityInnerPath Condition="!$([MSBuild]::IsOSPlatform('OSX'))">Editor\Data - <_UnityInnerPath Condition="$([MSBuild]::IsOSPlatform('OSX'))">Unity.App\Contents - - - - - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" - Include="$(UNITY_PATH)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" - Root="$(UNITY_PATH)\" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Linux')) AND '$(UNITY_PATH)' != ''" - Include="$(UNITY_PATH)\$(_UnityInnerPath)\Managed\UnityEngine.dll" - Root="$(UNITY_PATH)\" /> - - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" - Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" - Root="$(HubInstallDir)\$(UnityVersion)\" /> - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != ''" - Include="$(HubInstallDir)\$(UnityVersion)\$(_UnityInnerPath)\Managed\UnityEngine.dll" - Root="$(HubInstallDir)\$(UnityVersion)\" /> - - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" - Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" - Root="$(HubInstallDir)\$(HubDefaultEditor)\" /> - <_PotentialUnityPaths Condition="'$(HubInstallDir)' != '' AND '$(HubDefaultEditor)' != '' AND '$(UnityVersion)' != '$(HubDefaultEditor)'" - Include="$(HubInstallDir)\$(HubDefaultEditor)\$(_UnityInnerPath)\Managed\UnityEngine.dll" - Root="$(HubInstallDir)\$(HubDefaultEditor)\" /> - - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" - Include="C:\Program Files\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" - Root="C:\Program Files\Unity\" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('Windows'))" - Include="C:\Program Files\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" - Root="C:\Program Files\Unity\" /> - - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" - Include="\Applications\Unity\$(_UnityInnerPath)\Resources\Scripting\Managed\UnityEngine.dll" - Root="\Applications\Unity\" /> - <_PotentialUnityPaths Condition="$([MSBuild]::IsOSPlatform('OSX'))" - Include="\Applications\Unity\$(_UnityInnerPath)\Managed\UnityEngine.dll" - Root="\Applications\Unity\" /> - - <_UnityPathsFound Include="@(_PotentialUnityPaths->Exists())" /> - <_UnityPathsFoundReversed Include="@(_UnityPathsFound->Reverse())" /> - + + + - - <_UnityPathProp>%(_UnityPathsFoundReversed.Identity) - <_UnityRootProp>%(_UnityPathsFoundReversed.Root) + $([System.Text.RegularExpressions.Regex]::Match($(_FindUnityOutput), 'UnityRoot=([^;\r\n]+)').Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_FindUnityOutput), 'UnityDataPath=([^;\r\n]+)').Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_FindUnityOutput), 'UnityManagedPath=([^;\r\n]+)').Groups[1].Value) + $(UnityDataPath)Resources/PackageManager/ProjectTemplates/libcache/ - - - - - <_UnityPath Include="$(_UnityPathProp)" /> - - - - $(_UnityRootProp) - $(UnityRoot)$(_UnityInnerPath)\ - @(_UnityPath->DirectoryName())\ - $(UnityDataPath)Resources\PackageManager\ProjectTemplates\libcache\ - - - - + diff --git a/scripts/find-unity.ps1 b/scripts/find-unity.ps1 new file mode 100644 index 000000000..4c414f2ad --- /dev/null +++ b/scripts/find-unity.ps1 @@ -0,0 +1,119 @@ +#!/usr/bin/env pwsh +# Locate a Unity installation and emit the paths the build needs. +# +# Output (stdout, one per line): +# UnityRoot= +# UnityDataPath= +# UnityManagedPath= +# +# Warnings + the "candidates tried" error go to stderr. Exits non-zero on failure. + +[CmdletBinding()] +param ( + [string] $UnityVersion = '', + [string] $HubInstallDir = '', + [string] $HubDefaultEditor = '' +) + +$ErrorActionPreference = 'Stop' + +function Read-HubFile([string] $path) { + if (-not (Test-Path $path)) { return '' } + # Unity Hub writes a single quoted string per file (not strict JSON). + return (Get-Content -Raw $path).Trim().Trim('"') +} + +# --- Resolve Hub install dir + default editor ------------------------------- + +# AppData is Windows-only; on macOS/Linux we just rely on the platform default below. +$hubConfigDir = if ($env:APPDATA) { Join-Path $env:APPDATA 'UnityHub' } else { '' } + +if (-not $HubInstallDir -and $hubConfigDir) { + $HubInstallDir = Read-HubFile (Join-Path $hubConfigDir 'secondaryInstallPath.json') +} +if (-not $HubInstallDir) { + $HubInstallDir = if ($IsWindows) { 'C:/Program Files/Unity/Hub/Editor' } + elseif ($IsMacOS) { '/Applications/Unity/Hub/Editor' } + elseif ($IsLinux) { Join-Path $env:HOME 'Unity/Hub/Editor' } +} +if (-not (Test-Path $HubInstallDir)) { $HubInstallDir = '' } + +if (-not $HubDefaultEditor -and $hubConfigDir) { + $HubDefaultEditor = Read-HubFile (Join-Path $hubConfigDir 'defaultEditor.json') + if ($HubDefaultEditor -and -not (Test-Path (Join-Path $HubInstallDir $HubDefaultEditor))) { + $HubDefaultEditor = '' + } +} +# Fallback: pick the highest version-named dir under the hub install root. +if (-not $HubDefaultEditor -and $HubInstallDir) { + $HubDefaultEditor = Get-ChildItem -Path $HubInstallDir -Directory -ErrorAction SilentlyContinue | + Where-Object Name -Match '^\d{4}' | + Sort-Object Name -Descending | + Select-Object -First 1 -ExpandProperty Name +} + +# --- Build the probe list --------------------------------------------------- + +# Layout pieces. macOS Unity ships as a .app bundle so the inner path differs. +$inner = if ($IsMacOS) { 'Unity.App/Contents' } else { 'Editor/Data' } +$rootName = if ($IsMacOS) { 'Unity.App' } else { 'Editor' } + +# Each "install" candidate is a directory like // that contains +# either Editor/ (win/linux) or Unity.App/ (mac). +$installs = [System.Collections.Generic.List[string]]::new() +if ($IsLinux -and $env:UNITY_PATH) { $installs.Add($env:UNITY_PATH) } +if ($HubInstallDir -and $UnityVersion) { $installs.Add((Join-Path $HubInstallDir $UnityVersion)) } +if ($HubInstallDir -and $HubDefaultEditor -and $UnityVersion -ne $HubDefaultEditor) { + $installs.Add((Join-Path $HubInstallDir $HubDefaultEditor)) +} +if ($IsWindows) { $installs.Add('C:/Program Files/Unity') } +if ($IsMacOS) { $installs.Add('/Applications/Unity') } + +# Unity 6000.3+ moved managed assemblies under Resources/Scripting/Managed. +# Probe the new layout first within each install. +$dllRelatives = @('Resources/Scripting/Managed/UnityEngine.dll', 'Managed/UnityEngine.dll') + +function Find-UnityDll([string] $install) { + foreach ($rel in $dllRelatives) { + $dll = Join-Path $install (Join-Path $inner $rel) + if (Test-Path $dll) { return $dll } + } + return $null +} + +# Did the requested-version install yield a DLL? Drives the fallback warning below. +$expected = if ($UnityVersion -and $HubInstallDir) { Join-Path $HubInstallDir $UnityVersion } else { '' } +$shouldWarnFallback = $expected -and -not (Find-UnityDll $expected) + +$tried = [System.Collections.Generic.List[string]]::new() + +foreach ($install in $installs) { + $dll = Find-UnityDll $install + if (-not $dll) { + $dllRelatives | ForEach-Object { $tried.Add((Join-Path $install (Join-Path $inner $_))) } + continue + } + + if ($shouldWarnFallback) { + Write-Warning "Unity version $UnityVersion is not installed. Falling back to default Unity installation." + } + + $unityRoot = (Join-Path $install $rootName) + '/' + $unityDataPath = (Join-Path $install $inner) + '/' + $unityManagedPath = (Split-Path $dll -Parent) + '/' + + # Normalize to forward slashes — MSBuild accepts both, and it keeps the output diff-clean across platforms. + Write-Output ("UnityRoot=" + ($unityRoot -replace '\\', '/')) + Write-Output ("UnityDataPath=" + ($unityDataPath -replace '\\', '/')) + Write-Output ("UnityManagedPath=" + ($unityManagedPath -replace '\\', '/')) + exit 0 +} + +$msg = @" +Unity installation not found. See CONTRIBUTING.md. +UnityVersion: '$UnityVersion' +Expected one of: + * $($tried -join "`n * ") +"@ +Write-Error $msg +exit 1 From 17334bc4e62fe5ec6b146b6e1296c5d52f924b28 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 8 May 2026 10:55:22 +0200 Subject: [PATCH 4/4] lowercasing --- scripts/find-unity.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/find-unity.ps1 b/scripts/find-unity.ps1 index 4c414f2ad..51409619f 100644 --- a/scripts/find-unity.ps1 +++ b/scripts/find-unity.ps1 @@ -55,11 +55,11 @@ if (-not $HubDefaultEditor -and $HubInstallDir) { # --- Build the probe list --------------------------------------------------- # Layout pieces. macOS Unity ships as a .app bundle so the inner path differs. -$inner = if ($IsMacOS) { 'Unity.App/Contents' } else { 'Editor/Data' } -$rootName = if ($IsMacOS) { 'Unity.App' } else { 'Editor' } +$inner = if ($IsMacOS) { 'Unity.app/Contents' } else { 'Editor/Data' } +$rootName = if ($IsMacOS) { 'Unity.app' } else { 'Editor' } # Each "install" candidate is a directory like // that contains -# either Editor/ (win/linux) or Unity.App/ (mac). +# either Editor/ (win/linux) or Unity.app/ (mac). $installs = [System.Collections.Generic.List[string]]::new() if ($IsLinux -and $env:UNITY_PATH) { $installs.Add($env:UNITY_PATH) } if ($HubInstallDir -and $UnityVersion) { $installs.Add((Join-Path $HubInstallDir $UnityVersion)) }