Created
August 11, 2021 18:16
-
-
Save nickludlam/795a7f147e97f90455885c51fd184f23 to your computer and use it in GitHub Desktop.
How to change Unity meta script references from a DLL to individual files
This file contains 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
require 'tempfile' | |
require 'fileutils' | |
puts ARGV.inspect | |
base_path = "unity-project" | |
file_suffixes = ["*.unity", "*.prefab", "*.controller", "*.mat"] | |
$unity_loose_file_id = "11500000" # unity hardcoded value | |
source_data = """ | |
Asset: AbstractMemberBinding,InstanceID: 11912,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -186702827 | |
Asset: AbstractTemplateSelector,InstanceID: 11914,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1283446872 | |
Asset: AdapterOptions,InstanceID: 11916,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -855988391 | |
Asset: AnimatorParameterBinding,InstanceID: 11918,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -945915645 | |
Asset: BoolToColorAdapterOptions,InstanceID: 11920,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -343842708 | |
Asset: BoolToColorBlockAdapterOptions,InstanceID: 11922,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -150226926 | |
Asset: BoolToStringAdapterOptions,InstanceID: 11924,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: 2072353759 | |
Asset: CollectionBinding,InstanceID: 11926,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: 1223786303,ReplacementGUID: fc8f6e4a5f0376443b6e8516f9aa1cc1 | |
Asset: ColorToColorBlockAdapterOptions,InstanceID: 11928,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -970752098 | |
Asset: DateTimeToStringAdapterOptions,InstanceID: 11930,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1789889822 | |
Asset: DropdownBinding,InstanceID: 11932,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: 822021643, ReplacementGUID: 0c001c91b7bb4ad4cbcd38435b06117e | |
Asset: EventBinding,InstanceID: 11934,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1360956885,ReplacementGUID: 890ec8e82e868b34a8fce21566d83944 | |
Asset: FloatToStringAdapterOptions,InstanceID: 11936,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: 846165451 | |
Asset: OneWayPropertyBinding,InstanceID: 11938,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1670825535, ReplacementGUID: fc2d9c62932c0394ba2174cf22af8c74 | |
Asset: StringCultureToDateTimeAdapterOptions,InstanceID: 11940,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: 637168853 | |
Asset: SubViewModelBinding,InstanceID: 11942,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1830646146 | |
Asset: Template,InstanceID: 11944,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: 526415227 | |
Asset: TemplateBinding,InstanceID: 11946,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -456091253 | |
Asset: ToggleActiveBinding,InstanceID: 11948,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1613660816, ReplacementGUID: a5affc014ccc9214f91fe6a375b020f9 | |
Asset: TwoWayPropertyBinding,InstanceID: 11950,GUID: 33bb0041ebdea4bb8bad0be557ea70a1,FileID: -1957390036, ReplacementGUID: ff0db41e5d06b3e458e4e720862fa166 | |
""" | |
class UnityScriptReference | |
attr_accessor :name, :instance_id, :guid, :file_id, :replacement_guid | |
def initialize(name, instance_id, guid, file_id, replacement_guid) | |
@name = name | |
@instance_id = instance_id | |
@guid = guid | |
@file_id = file_id | |
@replacement_guid = replacement_guid | |
end | |
def to_s | |
return "USR: name=#{name} / instance_id=#{instance_id} / guid=#{guid} / file_id=#{file_id} / replacement_guid=#{replacement_guid}" | |
end | |
end | |
$script_references_dict = {} | |
source_data.split(/\n/).each do |data_line| | |
dict = {} | |
data_line.split(",").each do |element| | |
key, value = element.split(":") | |
key.strip! | |
value.strip! | |
#puts "'#{key}' -> '#{value}'" | |
dict[key] = value | |
end | |
if dict["Asset"] | |
usr = UnityScriptReference.new(dict["Asset"], dict["InstanceID"], dict["GUID"], dict["FileID"], dict["ReplacementGUID"]) | |
#puts "Created #{usr}" | |
if $script_references_dict.has_key?(usr.guid) | |
#puts "Extending #{usr.guid}" | |
script_references = $script_references_dict[usr.guid] | |
script_references << usr | |
$script_references_dict[usr.guid] = script_references | |
else | |
#puts "Seeding #{usr.guid}" | |
$script_references_dict[usr.guid] = [usr] | |
end | |
end | |
end | |
puts "$script_references_dict" | |
$script_references_dict.keys.each do |key| | |
usrs = $script_references_dict[key] | |
usrs.each do |usr| | |
puts "#{key} -> #{usr}" | |
end | |
end | |
def file_edit(source_file_path, line_replacements) | |
file_basename = File.basename(source_file_path) | |
puts "Rewriting #{source_file_path}" | |
tmpfile = Tempfile.new(file_basename) | |
begin | |
input_line_number = 0 | |
File.readlines(source_file_path).each do |line| | |
replacement_usr = line_replacements[input_line_number] | |
if replacement_usr | |
#puts "RAW_LINE: #{line}" | |
matches = line.match(/fileID: (-?[\d]+), guid: ([a-z0-9]+), type: ([\d]+)/) | |
file_ref_fileid = matches[1].strip | |
file_ref_guid = matches[2].strip | |
file_ref_type = matches[3].strip | |
#puts("Replacing guid #{file_ref_guid} with #{replacement_usr.replacement_guid}") | |
line = line.gsub(file_ref_guid, replacement_usr.replacement_guid) | |
line = line.gsub(file_ref_fileid, $unity_loose_file_id) | |
#puts "EDITED_LINE: #{line}" | |
end | |
tmpfile << line | |
input_line_number += 1 | |
end | |
ensure | |
tmpfile.close | |
FileUtils.copy(tmpfile.path, source_file_path) | |
tmpfile.unlink # deletes the temp file | |
end | |
end | |
file_suffixes.each do |suffix| | |
glob_path = File.join(base_path, "**", suffix) | |
Dir.glob(glob_path).each do |f| | |
#puts "File: #{f}" | |
line_number = 0 | |
line_replacements = {} | |
if !File.file?(f) | |
puts "Skipping non-file #{f}" | |
continue | |
end | |
File.readlines(f).each do |line| | |
line.strip! | |
if line =~ /m\_Script/ | |
#puts "found m_Script in #{f}" | |
#puts line | |
# Match e.g. " m_Script: {fileID: 11500000, guid: 10801da39a3e6457b83c39f229dd5114, type: 3}" | |
matches = line.match(/fileID: (-?[\d]+), guid: ([a-z0-9]+), type: ([\d]+)/) | |
if matches && matches.length == 4 | |
file_ref_fileid = matches[1].strip | |
file_ref_guid = matches[2].strip | |
file_ref_type = matches[3].strip | |
#puts "#{f} contains guid: #{file_ref_guid}" | |
script_refs = $script_references_dict[file_ref_guid] | |
if script_refs | |
script_refs.each do |usr| | |
if file_ref_fileid == usr.file_id && file_ref_guid == usr.guid | |
puts "#{f}[#{line_number}] MATCHES #{usr.name}" | |
puts line | |
line_replacements[line_number] = usr | |
end | |
end | |
end | |
else | |
puts "Problem with regexp!" | |
exit(1) | |
end | |
end | |
line_number += 1 | |
end | |
if line_replacements.keys.count > 0 | |
file_edit(f, line_replacements) | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment