param( [string]$Target ) $ErrorActionPreference = "Stop" Write-Host "====================================" Write-Host " Unity CI Build (Windows Agent)" Write-Host " Target: $Target" Write-Host "====================================" try { # ----------------------------- # Load toolchain config # ----------------------------- $config = Get-Content ".\ci\toolchain.json" | ConvertFrom-Json $unityVersion = $config.unityVersion $unityRoot = $config.windows.unityRoot $hubExe = "${env:ProgramFiles}\Unity Hub\Unity Hub.exe" if (!(Test-Path $hubExe)) { throw "Unity Hub not found at: $hubExe" } # ----------------------------- # Ensure Unity is installed # ----------------------------- $unityEditorPath = Join-Path $unityRoot "$unityVersion\Editor\Unity.exe" if (!(Test-Path $unityEditorPath)) { Write-Host "Unity $unityVersion not found. Installing via Unity Hub..." # Install Unity Editor & $hubExe -- --headless install ` --version $unityVersion if ($LASTEXITCODE -ne 0) { throw "Failed to install Unity $unityVersion" } } Write-Host "Unity found: $unityEditorPath" # ----------------------------- # Ensure required modules # ----------------------------- # NOTE: # Unity Hub CLI installs modules per version. # These are cached per editor version, not reinstalled each build. $modules = $config.windows.modules Write-Host "Ensuring Unity modules: $($modules -join ', ')" foreach ($module in $modules) { Write-Host "Checking module: $module" # Check installed modules via Unity Hub $installed = & $hubExe -- --headless editors --installed if ($installed -notmatch "$unityVersion.*$module") { Write-Host "Installing module: $module" & $hubExe -- --headless install-modules ` --version $unityVersion ` --module $module if ($LASTEXITCODE -ne 0) { throw "Failed to install module: $module" } } else { Write-Host "Module already installed: $module" } } # ----------------------------- # Resolve Unity build method # ----------------------------- if (!$Target) { Write-Host "No Target Provided" exit } else { $method = switch ($Target) { "Windows" { "BuildScript.Windows" } "Android" { "BuildScript.Android" } } Write-Host "Using Unity method: $method" Write-Host "====================================================================" Write-Host "===================== Starting Unity Build =========================" Write-Host "====================================================================" # 1. Define arguments cleanly using an array $logFile = "$PWD/unity_build.log" $unityArgs = @( "-batchmode", "-nographics", "-quit", "-projectPath", "$PWD", "-executeMethod", "$method", "-logFile", "$logFile" ) # 2. Start the Unity process in the background $process = Start-Process -FilePath $unityEditorPath -ArgumentList $unityArgs -PassThru -NoNewWindow # 3. Wait for the log file to be created by Unity while (!(Test-Path $logFile) -and !$process.HasExited) { Start-Sleep -Milliseconds 100 } # 4. Stream the log live into the TeamCity console if (Test-Path $logFile) { # Get-Content -Wait streams the file until the process kills it $logJob = Start-Job -ScriptBlock { Get-Content $using:logFile -Wait } # Wait for Unity to completely finish building $process.WaitForExit() # Stop streaming and clean up Stop-Job $logJob Receive-Job $logJob Remove-Job $logJob Remove-Item $logFile -Force } # 5. Bubble up the exit code so TeamCity catches errors if ($process.ExitCode -ne 0) { Write-Error "Unity build failed with exit code $($process.ExitCode)" exit $process.ExitCode } Write-Host "====================================" Write-Host " BUILD SUCCESS: $Target" Write-Host "====================================" } } catch { throw } finally { Write-Host "Cleaning Up" # Stop-Process -Name "Unity", "Unity Hub" -Force }