2class ResourceProcessorPlugin: WorkbenchPlugin
5 ref array<string> FileTypes;
7 [
Attribute(
"",
UIWidgets.FileNamePicker,
"Check only textures whose path starts with given filter string.",
params:
"folders")]
10 [
Attribute(
"",
UIWidgets.EditBox,
"Check only textures whose path contains given filter string.")]
13 [
Attribute(
"",
UIWidgets.EditBox,
"Check only textures whose path ends with given filter string.")]
19 [
Attribute(
"true",
UIWidgets.CheckBox,
"Resaves metafile even if it's without changes")]
20 bool ForceResaveMetaFile;
23 bool ReportMissingMetaFile;
26 bool ReportMissingConfigurations;
29 bool ReportCustomPropertyValues;
31 [
Attribute(
"false",
UIWidgets.CheckBox,
"Fix custom property values (sets all PC custom changes to all other platforms)")]
32 bool FixCustomPropertyValues;
34 ref array<string> m_Resources =
new array<string>;
37 void ResourceProcessorPlugin()
56 static const string MeshObjectCommon =
"Common";
60 bool TestAgainstFilter(
string resource)
62 int resourceLength = resource.Length();
64 int prefixLength = PathStartsWith.Length();
65 if (resourceLength < prefixLength)
68 int suffixLength = PathEndsWith.Length();
69 if (resourceLength < suffixLength)
72 int subLength = PathContains.Length();
73 if (resourceLength < subLength)
77 if (!resource.StartsWith(PathStartsWith))
80 if (!resource.EndsWith(PathEndsWith))
83 if (!resource.Contains(PathContains))
92 if (TestAgainstFilter(filePath))
93 m_Resources.Insert(filePath);
97 bool CheckContainersVar(
string resource, notnull array<string> platformPrefixes, notnull array<BaseContainer> containers,
string varName,
DataVarType type)
100 bool isSetOnPC = pc.IsVariableSetDirectly(varName);
105 array<BaseContainer> subContainers = {};
106 array<string> subPlatformPrefixes = {};
108 for (
int iPlatform = 0; iPlatform < containers.Count(); iPlatform++)
111 subContainers.Insert(platform.GetObject(varName));
112 subPlatformPrefixes.Insert(platformPrefixes[iPlatform] +
"." + varName);
118 int nVars = pcSubContainer.GetNumVars();
119 for (
int iVar = 0; iVar < nVars; iVar++)
121 string subVarName = pcSubContainer.GetVarName(iVar);
123 if (!CheckContainersVar(resource, subPlatformPrefixes, subContainers, subVarName, pcSubContainer.GetDataVarType(iVar)))
132 for (
int iPlatform = 1; iPlatform < containers.Count(); iPlatform++)
135 bool isSet = platform.IsVariableSetDirectly(varName);
136 bool isInherited =
false;
138 if (platformPrefixes[iPlatform].StartsWith(
"HEADLESS"))
141 if (platform.GetAncestor() && platform.GetAncestor().GetName() == pc.GetName())
159 pc.Get(varName, valPC);
160 pc.Get(varName, valPlatform);
163 if (valPC != valPlatform)
165 if (FixCustomPropertyValues)
167 FixIssue(resource, pc, platform, platformPrefixes[iPlatform], varName);
171 ReportIssue(resource,
"Property inherited from PC, but overridden on platform: " + platformPrefixes[iPlatform] +
"." + varName);
181 if (FixCustomPropertyValues)
183 FixIssue(resource, pc, platform, platformPrefixes[iPlatform], varName);
187 ReportIssue(resource,
"Property set on PC, but not set on platform: " + platformPrefixes[iPlatform] +
"." + varName);
197 if (FixCustomPropertyValues)
199 FixIssue(resource, pc, platform, platformPrefixes[iPlatform], varName);
203 ReportIssue(resource,
"Property not set on PC, but set on plarform: " + platformPrefixes[iPlatform] +
"." + varName);
216 PathStartsWith.ToLower();
217 PathContains.ToLower();
218 PathEndsWith.ToLower();
223 filter.fileExtensions = FileTypes;
229 ResourceManager rb = Workbench.GetModule(ResourceManager);
230 WBProgressDialog progress =
new WBProgressDialog(
"Processing...", rb);
232 Print(
"Batch resource processor - BEGIN");
234 float count = m_Resources.Count();
236 foreach (
int resourceIdx,
string resource : m_Resources)
238 progress.SetProgress(resourceIdx / count);
240 MetaFile meta = rb.GetMetaFile(resource);
243 if (ReportMissingMetaFile)
245 ReportIssue(resource,
"meta-file is missing");
254 if (ReportMissingConfigurations)
256 ReportIssue(resource,
"meta-file is missing 'Configurations' property");
263 bool anyChangeInMetaFile = ForceResaveMetaFile;
265 if (ReportCustomPropertyValues || FixCustomPropertyValues)
267 int nPlatforms = configurations.Count();
269 ResourceName pcConfigName = configurations[0].GetResourceName();
270 array<string> pcConfigVarsChanged = {};
274 array<BaseContainer> containers = {};
275 array<string> platformPrefixes = {};
277 for (
int iPlatform = 0; iPlatform < nPlatforms; iPlatform++)
280 containers.Insert(platformConf);
281 platformPrefixes.Insert(platformConf.GetName());
284 int nVars = pcPlatformConf.GetNumVars();
285 for (
int iVar = 0; iVar < nVars; iVar++)
287 string varName = pcPlatformConf.GetVarName(iVar);
289 if (!CheckContainersVar(resource, platformPrefixes, containers, varName, pcPlatformConf.GetDataVarType(iVar)))
292 if (FixCustomPropertyValues)
293 anyChangeInMetaFile =
true;
301 string className =
conf.GetClassName();
302 if( IsMeshObject(className) )
304 if( FixMeshObjectMetaFile(meta, resource) )
307 anyChangeInMetaFile =
true;
310 else if( IsSound(className) )
312 if( FixSoundMetaFile(meta, resource) )
313 anyChangeInMetaFile =
true;
315 else if( IsParticleEffect(className) )
317 if( FixParticleEffectMetaFile(meta, resource) )
318 anyChangeInMetaFile =
true;
322 if(anyChangeInMetaFile )
330 Print(
"Batch resource processor - END");
338 if (!Workbench.ScriptDialog(
"Batch resource processor",
"",
this))
348 FixCustomPropertyValues =
false;
350 ForceResaveMetaFile =
false;
352 ReportMissingMetaFile =
true;
353 ReportMissingConfigurations =
true;
354 ReportCustomPropertyValues =
true;
357 PathStartsWith =
string.Empty;
358 PathContains =
string.Empty;
359 PathEndsWith =
string.Empty;
361 ResourceManager rm = Workbench.GetModule(ResourceManager);
364 rm.GetCmdLine(
"-FileTypes", cli);
365 cli.Split(
",", FileTypes,
true);
367 rm.GetCmdLine(
"-PathStartsWith", PathStartsWith);
368 rm.GetCmdLine(
"-PathContains", PathContains);
369 rm.GetCmdLine(
"-PathEndsWith", PathEndsWith);
371 Print(
"BatchMeshObjectProcessorPlugin commandline:");
372 Print(PathStartsWith);
384 static void ReportIssue(
string resource,
string issue)
386 string msg =
string.Format(
"@\"%1\" : %2", resource, issue);
394 pc.Get(varName, val);
395 platform.Set(varName, val);
396 ReportIssue(resource,
"Property fixed: " + prefix +
"." + varName);
400 static bool FixMeshObjectMetaFile(MetaFile meta,
string absFileName)
406 bool metaModified =
false;
408 for(
int c = 0; c < configurations.Count(); c++)
412 string cfgName = cfg.GetName();
417 bool IsSet = cfg.IsVariableSetDirectly(MeshObjectCommon);
423 cfg.SetObject(MeshObjectCommon, cont);
430 ReportIssue(absFileName,
"Cannot set configuration ancestor (" + cfgName +
")" );
439 ancestor =
"{0877E7C4BB2B2C9A}configs/ResourceTypes/PC/MeshObjectCommon.conf";
442 ancestor =
"{9D5B6207F7628CE2}configs/ResourceTypes/XBOX_ONE/MeshObjectCommon.conf";
445 ancestor =
"{DD9F02115C764647}configs/ResourceTypes/XBOX_SERIES/MeshObjectCommon.conf";
448 ancestor =
"{53EC476BC921D99A}configs/ResourceTypes/PS4/MeshObjectCommon.conf";
451 ancestor =
"{F62AA8E7B8EA9D26}configs/ResourceTypes/PS5/MeshObjectCommon.conf";
454 ancestor =
"{3A5B3356978039E8}configs/ResourceTypes/HEADLESS/MeshObjectCommon.conf";
460 commonObj.SetAncestor(ancestor);
468 BaseContainer commonPc = confPc_.GetObject(MeshObjectCommon);
469 for (
int iConf = 0, countConf = configurations.Count(); iConf < countConf; iConf++)
475 BaseContainer commonDerived = confDerived_.GetObject(MeshObjectCommon);
479 for (
int iVar = 0, countVar = commonPc.GetNumVars(); iVar < countVar; iVar++)
481 string namePc = commonPc.GetVarName(iVar);
482 string nameDerived = commonDerived.GetVarName(iVar);
483 if (namePc != nameDerived)
486 DataVarType varType = commonPc.GetDataVarType(iVar);
487 bool isSetDirectlyPc = commonPc.IsVariableSetDirectly(namePc);
488 bool isSetDirectlyDerived = commonDerived.IsVariableSetDirectly(nameDerived);
493 float propValPc, propValDerived;
494 if (!commonPc.Get(namePc, propValPc))
497 if (!commonDerived.Get(nameDerived, propValDerived))
500 if (propValPc != propValDerived)
503 commonDerived.Set(nameDerived, propValPc);
508 int propValPc, propValDerived;
509 if (!commonPc.Get(namePc, propValPc))
512 if (!commonDerived.Get(nameDerived, propValDerived))
515 if (propValPc != propValDerived)
518 commonDerived.Set(nameDerived, propValPc);
522 else if (isSetDirectlyDerived)
525 commonDerived.ClearVariable(nameDerived);
535 static bool FixSoundMetaFile(MetaFile meta,
string absFileName)
541 bool anyChangeInMetaFile =
false;
543 for(
int c = 0; c < configurations.Count(); c++)
547 string cfgName = cfg.GetName();
553 ancestor =
"{F72B05D02F3F135E}configs/ResourceTypes/PC/Sound.conf";
556 ancestor =
"{A0776163143143AC}configs/ResourceTypes/XBOX_ONE/Sound.conf";
559 ancestor =
"{382981CA1FC1C8DB}configs/ResourceTypes/XBOX_SERIES/Sound.conf";
562 ancestor =
"{89EB939911B4C093}configs/ResourceTypes/PS4/Sound.conf";
565 ancestor =
"{A584A3B556D4A981}configs/ResourceTypes/PS5/Sound.conf";
568 ancestor =
"{D63592CA950AF3A8}configs/ResourceTypes/HEADLESS/Sound.conf";
574 cfg.SetAncestor(ancestor);
575 anyChangeInMetaFile =
true;
579 return anyChangeInMetaFile;
583 static bool FixParticleEffectMetaFile(MetaFile meta,
string absFileName)
589 bool anyChangeInMetaFile =
false;
591 for(
int c = 0; c < configurations.Count(); c++)
595 string cfgName = cfg.GetName();
601 ancestor =
"{4B4500E061CCD624}configs/ResourceTypes/PC/ParticleEffect.conf";
604 ancestor =
"{73FE8562A95EBA36}configs/ResourceTypes/XBOX_ONE/ParticleEffect.conf";
607 ancestor =
"{DC1673718B31CF7E}configs/ResourceTypes/XBOX_SERIES/ParticleEffect.conf";
610 ancestor =
"{B94602D6C3160C98}configs/ResourceTypes/PS4/ParticleEffect.conf";
613 ancestor =
"{E8F9F77ECEB75947}configs/ResourceTypes/PS5/ParticleEffect.conf";
616 ancestor =
"{EED8908A9A55ED1C}configs/ResourceTypes/HEADLESS/ParticleEffect.conf";
622 cfg.SetAncestor(ancestor);
623 anyChangeInMetaFile =
true;
627 return anyChangeInMetaFile;
631 static bool IsMeshObject(
string className)
633 return className ==
"FBXResourceClass" || className ==
"TXOResourceClass";
637 static bool IsSound(
string className)
639 return className ==
"WAVResourceClass";
643 static bool IsParticleEffect(
string className)
645 return className ==
"PTCResourceClass";