Last active
February 16, 2024 09:56
-
-
Save Kinggrass/ad42ab84e1a7561038b766408b14c9ff to your computer and use it in GitHub Desktop.
Powershell script for transfering GUIDs inside a Unity project to another by filename
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| param( | |
| [string]$sourceFolderPath, # The path to the folder containing the source .cs.meta files. | |
| [string]$targetProjectPath # The path to the target project where files will be updated. | |
| ) | |
| function Create-GUIDMap { | |
| param( | |
| [string]$sourcePath, | |
| [string]$targetPath | |
| ) | |
| $guidMap = @{} | |
| Write-Host "Creating GUID map..." | |
| $sourceScripts = Get-ChildItem -Path $sourcePath -Recurse -Filter "*.cs.meta" | |
| foreach ($sourceScript in $sourceScripts) { | |
| $fileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($sourceScript.Name) | |
| $sourceGuid = (Get-Content $sourceScript.FullName | Select-String -Pattern 'guid: (.*)').Matches.Groups[1].Value | |
| if (-not $sourceGuid) { | |
| Write-Host "No GUID found in $sourceScript." | |
| continue | |
| } | |
| Write-Host "Processing $fileNameWithoutExtension with source GUID: $sourceGuid" | |
| $targetMetaFiles = Get-ChildItem -Path $targetPath -Recurse -Filter "$fileNameWithoutExtension.meta" | |
| foreach ($targetMetaFile in $targetMetaFiles) { | |
| $targetGuid = (Get-Content $targetMetaFile.FullName | Select-String -Pattern 'guid: (.*)').Matches.Groups[1].Value | |
| if ($targetGuid -and $sourceGuid -ne $targetGuid) { | |
| $guidMap[$targetGuid] = $sourceGuid | |
| Write-Host "Mapping added: $targetGuid to $sourceGuid" | |
| } | |
| } | |
| } | |
| if ($guidMap.Count -eq 0) { | |
| Write-Host "No mappings found." | |
| } else { | |
| Write-Host "$($guidMap.Count) mappings created in the GUID map." | |
| } | |
| return $guidMap | |
| } | |
| function Replace-GUIDs { | |
| param( | |
| [string]$path, | |
| [hashtable]$guidMap | |
| ) | |
| Write-Host "Starting to replace GUIDs in all files..." | |
| $filesUpdated = 0 | |
| $allFiles = Get-ChildItem -Path $path -Recurse -File | |
| foreach ($file in $allFiles) { | |
| # Try to capture the contents of the file and check if it is not $null | |
| $content = Get-Content -Path $file.FullName -Raw -ErrorAction SilentlyContinue | |
| if ($content -eq $null) { | |
| Write-Host "No content of $($file.FullName), not readable or file is empty." | |
| continue | |
| } | |
| $changed = $false | |
| foreach ($oldGuid in $guidMap.Keys) { | |
| if ($content.Contains($oldGuid)) { | |
| $content = $content.Replace($oldGuid, $guidMap[$oldGuid]) | |
| $changed = $true | |
| } | |
| } | |
| if ($changed) { | |
| [System.IO.File]::WriteAllText($file.FullName, $content) | |
| Write-Host "GUID updated in: $($file.FullName)" | |
| $filesUpdated++ | |
| } | |
| } | |
| Write-Host "$filesUpdated files where updated." | |
| } | |
| $guidMap = Create-GUIDMap -sourcePath $sourceFolderPath -targetPath $targetProjectPath | |
| Replace-GUIDs -path $targetProjectPath -guidMap $guidMap | |
| Write-Host "Process completed." |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Make sure to do a backup before.
Usage example:
.\Transfer-Unity-GUIDs.ps1 -sourceFolderPath "C:\Users\UserA\Documents\Unity\ProjectA\Assets\Scripts" -targetProjectPath "C:\Users\UserA\Documents\Unity\ProjectB\Assets"This will also adjust all references in prefabs and scenes, if the serialization is the same the components will not lose any data.
I wrote this because in my carrer it happend often that myself or other developers copied scripts from one project to another without the meta files and sometimes during the project some prefabs should also be copied but Unity cannot find the references anymore because in the project the scripts do have other guids generated and therefor are incompatible then.
This is my solution for the case to make the scripts in the target project compatible again.
Be aware that it is currently checking against file names only to find corresponding scripts. Thats currently enough in my case and hopefully for yours.
Better would be also to check against namespaces inside the file.