def rename_original_to_wwise(obj): if obj['type'] != 'Sound': return original_wave_path = WaapiTools.get_original_wave_path(obj) new_wave_name = obj['name'] + '.wav' language = WaapiTools.get_sound_language(obj) # 当前不包含源文件,直接根据名称导入 if language == '': if 'SFX' in original_wave_path: language = 'SFX' else: language = WaapiTools.get_default_language() if original_wave_path != '': original_wave_name = os.path.basename(original_wave_path) # 同名不用修改 if original_wave_name == new_wave_name: return new_wave_path = original_wave_path.replace(original_wave_name, new_wave_name) # 重命名源文件 if not os.path.exists(new_wave_path): os.rename(original_wave_path, new_wave_path) # 删除旧资源 delete_audio_sources(obj) # 找不到源文件,直接导入新的 else: if language != 'SFX': language = os.path.join('Voice', language) new_wave_path = os.path.join(ScriptingTools.get_originals_folder(), language, new_wave_name) # 导入新资源 WaapiTools.import_audio_file(new_wave_path, obj, obj['name'], language)
def auto_assign_switch_mappings(obj): if obj['type'] != 'SwitchContainer' and obj[ 'type'] != 'MusicSwitchContainer': return # 获取分配的Switch Group get_args = { 'from': { 'id': [obj['id']] }, 'options': { 'return': ['@SwitchGroupOrStateGroup'] } } switch_group_objects = WaapiTools.Client.call('ak.wwise.core.object.get', get_args)['return'] if len(switch_group_objects) == 0: return switch_group_obj = switch_group_objects[0]['@SwitchGroupOrStateGroup'] # 获取Switch Group中所有可能值 switch_objects = WaapiTools.get_children_objects(switch_group_obj, False) # 找到Switch Container里面的所有子对象 switch_container_children = WaapiTools.get_children_objects(obj, False) for child in switch_container_children: for switch_obj in switch_objects: # 两者名字任一包括即符合 switch_name = switch_obj['name'] child_name = child['name'] if switch_name in child_name or child_name in switch_name: assign_switch_mapping(child, switch_obj)
def populate_from_wwise(self, objects: list): for obj in objects: if obj['type'] == 'Sound': self.add_file(WaapiTools.get_original_wave_path(obj)) else: self.populate_from_wwise( WaapiTools.get_children_objects(obj, False))
def start_replacing(self): self.__oldName = self.iptFindName.text() self.__newName = self.iptReplaceName.text() WaapiTools.begin_undo_group() for obj in self.__mainWindow.activeObjects: self.iterate_child_objects(obj) WaapiTools.end_undo_group()
def create_banks_by_matrix(self): self.get_permutations() WaapiTools.begin_undo_group() for permutation in self.permutations: bank_name = self.get_bank_name(permutation) create_sound_bank_by_name(bank_name) WaapiTools.end_undo_group()
def copy_selection_to_active_objects(self): if WaapiTools.Client is None: return selection = WaapiTools.get_selected_objects() if len(selection) > 0: self.batchProcessor = BatchProcessor( self.activeObjects, lambda obj: WaapiTools.copy_object(selection[0], obj)) self.batchProcessor.start()
def move_active_objects_to_selection(self): if WaapiTools.Client is None: return selection = WaapiTools.get_selected_objects() if len(selection) > 0: self.batchProcessor = BatchProcessor( self.activeObjects, lambda obj: WaapiTools.move_object(obj, selection[0])) self.batchProcessor.start()
def get_children_from_selection(self): selected_objects = WaapiTools.get_selected_objects() if len(selected_objects) == 0: return children = WaapiTools.get_children_objects(selected_objects[0], False) row = 0 for child in children: if row >= self.tblMatrix.rowCount(): self.tblMatrix.setRowCount(row + 1) self.tblMatrix.setItem(row, 0, QTableWidgetItem(child['name'])) row += 1
def run(self): if WaapiTools.Client is None: return WaapiTools.begin_undo_group() index = 0 for obj in self.__objects: index += 1 self.progressBarCallback.emit( index, obj.name if hasattr(obj, 'name') else obj['name']) self.__processor(obj) self.finishedCallback.emit() WaapiTools.end_undo_group()
def export_to_file(self): if WaapiTools.Client is None: return saveDict = { "selectObject": WaapiTools.get_selected_objects(), "activeObjects": self.activeObjects, "cacheObjects": self.cacheObjects, "radioBtn_group_key_name": self.radioBtn_group_key_name.isChecked(), "radioBtn_group_ope_include": self.radioBtn_group_ope_include.isChecked(), "cbxUseRegularExpression": self.cbxUseRegularExpression.isChecked(), "cbxMatchWholeWord": self.cbxMatchWholeWord.isChecked(), "cbxCaseSensitive": self.cbxCaseSensitive.isChecked(), "cbbDescendantType": self.cbbDescendantType.currentIndex(), "iptSelectionFilter": self.iptSelectionFilter.text() } FileTools.export_to_file(saveDict)
def find_matching_bank(self, obj): # 在每一种排列组合中搜索 for permutation in self.permutations: match = True for item in permutation: if item not in obj['path']: match = False break # 找到符合名称的Bank if match: bank_name = self.get_bank_name(permutation) bank = WaapiTools.find_object_by_name(bank_name, 'SoundBank') # Wwise搜索会包含所有带有关键词的,需要精确搜索 if bank and bank['name'] == bank_name: set_args = { 'soundbank': bank['id'], 'operation': 'add', 'inclusions': [{ 'object': obj['id'], 'filter': ['media'] }] } WaapiTools.Client.call( 'ak.wwise.core.soundbank.setInclusions', set_args) return True # 每一个组合都不符合,在下级继续找 return False
def add_to_selected_bank(self): if WaapiTools.Client is None: return banks = WaapiTools.get_selected_objects() if len(banks) == 0 or banks[0]['type'] != 'SoundBank': return add_objects_to_bank(banks[0], self.activeObjects, ['media'])
def replace_source_wave(self, sound_obj): new_sound_name = sound_obj['name'].replace(self.__oldName, self.__newName) WaapiTools.rename_object(sound_obj, new_sound_name) sources = WaapiTools.get_children_objects(sound_obj, False) for source in sources: original_path = WaapiTools.get_original_wave_path(source) language = WaapiTools.get_sound_language(source) new_wave_path = original_path.replace(self.__oldName, self.__newName) WaapiTools.delete_object(source) WaapiTools.import_audio_file(new_wave_path, sound_obj, new_sound_name, language)
def Remove(self): if self.path == '': self.path = WaapiTools.get_project_directory() index = self.path.rfind('\\') self.path = self.path[:index + 1] self.auto_remove_wwise_silence( self.path + "Actor-Mixer Hierarchy\\Voice_InGame.wwu") self.auto_remove_wwise_silence( self.path + "Actor-Mixer Hierarchy\\Voice_FrontEnd.wwu")
def filter_objects_by_inclusion(objects: list, inclusion: bool): objects_filtered = [] for obj in objects: # 音频资源没有inclusion选项 if obj['type'] == 'AudioFileSource': continue if WaapiTools.get_object_property(obj, '@Inclusion') == inclusion: objects_filtered.append(obj) return objects_filtered
def replace_parent(obj): parent = WaapiTools.get_parent_objects(obj, False) grand_parent = WaapiTools.get_parent_objects(parent, False) WaapiTools.move_object(obj, grand_parent) if grand_parent['type'] == 'SwitchContainer': mappings = get_switch_mapping(grand_parent) for mapping in mappings: if mapping['child'] == parent['id']: assign_switch_mapping(obj, mapping['stateOrSwitch']) WaapiTools.delete_object(parent) WaapiTools.rename_object(obj, parent['name'])
def connect_to_wwise(self): url = 'ws://127.0.0.1:' + str(self.spbWaapiPort.value()) + '/waapi' try: WaapiTools.Client = WaapiClient(url=url) WaapiTools.Client.subscribe('ak.wwise.core.project.postClosed', self.on_wwise_closed) self.statusbar.showMessage('Wwise已连接到' + WaapiTools.get_project_directory()) self.btnWaapiConnect.setEnabled(False) except CannotConnectToWaapiException: self.statusbar.showMessage('无法连接到Wwise工程...')
def replace_event(self, event_obj): new_event_name = event_obj['name'].replace(self.__oldName, self.__newName).replace( '_01', '') WaapiTools.rename_object(event_obj, new_event_name) for action in WaapiTools.get_children_objects(event_obj, False): target = WaapiTools.get_object_property(action, '@Target') target_full = WaapiTools.get_full_info_from_obj_id(target['id']) new_target_path = target_full['path'].replace( self.__oldName, self.__newName) new_target = WaapiTools.get_object_from_path(new_target_path) if new_target is not None: WaapiTools.set_object_reference(action, 'Target', new_target)
def replace_bank(self, bank_obj): new_bank_name = bank_obj['name'].replace(self.__oldName, self.__newName).replace( '_01', '') WaapiTools.rename_object(bank_obj, new_bank_name) new_inclusion_objects = [] for old_inclusion_obj in SoundBankTools.get_bank_inclusions(bank_obj): target_full = WaapiTools.get_full_info_from_obj_id( old_inclusion_obj['object']) new_target_path = target_full['path'].replace( self.__oldName, self.__newName) new_target = WaapiTools.get_object_from_path(new_target_path) if new_target is not None: inclusion = { 'object': new_target['id'], 'filter': old_inclusion_obj['filter'] } new_inclusion_objects.append(inclusion) SoundBankTools.clear_bank_inclusions(bank_obj) SoundBankTools.add_objects_to_bank_with_individual_inclusion( bank_obj, new_inclusion_objects)
def iterate_child_objects(self, obj): if self.cbxObjectType.currentText( ) == 'AudioSource' and obj['type'] == 'Sound': if self.__oldName in obj['name']: self.replace_source_wave(obj) elif self.cbxObjectType.currentText( ) == 'Event' and obj['type'] == 'Event': if self.__oldName in obj['name']: self.replace_event(obj) elif self.cbxObjectType.currentText( ) == 'SoundBank' and obj['type'] == 'SoundBank': if self.__oldName in obj['name']: self.replace_bank(obj) else: if self.__oldName in obj['name']: new_object_name = obj['name'].replace(self.__oldName, self.__newName) # 音效不需要去除_01的后缀,事件和Bank需要 if self.cbxObjectType.currentText() != 'AudioSource': new_object_name = new_object_name.replace('_01', '') WaapiTools.rename_object(obj, new_object_name) for child in WaapiTools.get_children_objects(obj, False): self.iterate_child_objects(child)
def find_parent(self): if WaapiTools.Client is None: return if self.cbxKeepSelf.isChecked(): all_parents = self.activeObjects else: all_parents = [] for obj in self.activeObjects: for parent in WaapiTools.get_parent_objects( obj, self.cbxRecursiveFind.isChecked()): all_parents.append(parent) self.cacheObjects = all_parents self.reset_filter() self.filter_and_show_list()
def find_children(self): if WaapiTools.Client is None: return if self.cbxKeepSelf.isChecked(): all_children = self.activeObjects else: all_children = [] for obj in self.activeObjects: for child in WaapiTools.get_children_objects( obj, self.cbxRecursiveFind.isChecked()): all_children.append(child) self.cacheObjects = all_children self.reset_filter() self.filter_and_show_list()
def add_file(self, file, asset_type): row = self.tblFileList.rowCount() self.tblFileList.setRowCount(row + 1) file_guid = file.rstrip('.asset') obj = WaapiTools.get_full_info_from_obj_id('{' + file_guid + '}') if obj is not None: obj_name = obj['name'] status = '正常' else: full_path = os.path.join(self.__workDir, asset_type, file) with open(full_path) as text: obj_name = text.readlines()[13].lstrip( ' objectName: ').rstrip() status = '多余' self.tblFileList.setItem(row, 0, QTableWidgetItem(obj_name)) self.tblFileList.setItem(row, 1, QTableWidgetItem(asset_type)) self.tblFileList.setItem(row, 2, QTableWidgetItem(status)) self.tblFileList.setItem(row, 3, QTableWidgetItem(file_guid))
def create_or_add_to_bank(obj): # 寻找或创建同名bank bank = WaapiTools.find_object_by_name(obj['name'], 'SoundBank') if bank is None: bank = create_sound_bank_by_name(obj['name']) # 为bank添加内容 set_args = { 'soundbank': bank['id'], 'operation': 'add', 'inclusions': [{ 'object': obj['id'], 'filter': ['events', 'structures', 'media'] }] } WaapiTools.Client.call('ak.wwise.core.soundbank.setInclusions', set_args)
def localize_language(obj): language_list = WaapiTools.get_language_list() sources = WaapiTools.get_children_objects(obj, False) existing_language = '' existing_source = None for source in sources: existing_language = WaapiTools.get_sound_language(source) existing_source = source break for language_obj in language_list: language = language_obj['name'] if language != existing_language: original_file_path = WaapiTools.get_original_wave_path( existing_source) WaapiTools.import_audio_file( original_file_path.replace(existing_language, language), obj, obj['name'], language)
def get_switch_container_child_context(obj): get_args = { 'from': { 'id': [obj['id']] }, 'options': { 'return': ['switchContainerChild:context'] } } result = WaapiTools.Client.call('ak.wwise.core.object.get', get_args) context = result['return'][0]['switchContainerChild:context'] print(context) descendants = WaapiTools.get_children_objects(context, True) print(descendants) get_args = { 'from': { 'id': [context['id']] }, 'options': { 'return': ['@VoicePitch'] } } result = WaapiTools.Client.call('ak.wwise.core.object.get', get_args) print(result)
def get_originals_folder(): project_path = WaapiTools.get_project_directory() project_dir = trim_path_from_right(project_path) return project_dir + '\\Originals\\'
def iterate_child_sound_objects(obj, action): if obj['type'] == 'Sound': action(obj) else: for child in WaapiTools.get_children_objects(obj, False): iterate_child_sound_objects(child, action)
def temp_tool(objects: list): for obj in objects: parent = WaapiTools.get_parent_objects(obj, False) new_obj = WaapiTools.create_object('Tail', 'SwitchContainer', parent, 'rename') WaapiTools.move_object(obj, new_obj) indoor_switch_group = WaapiTools.find_object_by_name( 'Indoor_Outdoor', 'SwitchGroup') WaapiTools.set_object_reference(new_obj, 'SwitchGroupOrStateGroup', indoor_switch_group) outdoor_switch = WaapiTools.get_children_objects( indoor_switch_group, False)[1] LogicContainerTools.assign_switch_mapping(obj, outdoor_switch) WaapiTools.set_object_reference(new_obj, 'DefaultSwitchOrState', outdoor_switch) if parent['type'] == 'SwitchContainer': loop_switch_group = WaapiTools.find_object_by_name( 'Gun_Shot_Loop_Mode', 'SwitchGroup') end_switch = WaapiTools.get_children_objects( loop_switch_group, False)[0] LogicContainerTools.assign_switch_mapping(new_obj, end_switch)
def open_in_batch_rename(self): if WaapiTools.Client is None: return WaapiTools.execute_ui_command(self.activeObjects, 'ShowBatchRename')