Skip to content

Instantly share code, notes, and snippets.

@Kinggrass
Last active February 16, 2024 09:56
Show Gist options
  • Select an option

  • Save Kinggrass/ad42ab84e1a7561038b766408b14c9ff to your computer and use it in GitHub Desktop.

Select an option

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
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."
@Kinggrass
Copy link
Author

Kinggrass commented Feb 16, 2024

Donate

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment