Mostly Harmless

Legacy:Dynamicly Accessing Original Static Mesh Textures

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

There is a handy workaround I discovered which allows you to access the Materials array which is natively defined for Static mesh's, normally you can only access this via UnrealEd but by using the GetPropertyText function declared in Core.Object I have managed to parse the original Materials array.

You might think why is this usefull?, well...If a mesh has had it's textures applied during the modelling process then those textures are normally inaccessible in code during runtime. (i.e. you can't find out what texture's the mesh uses)

In a lot of cases this is not a problem since you can manually define the textures in the Skins array but if you want to do DYNAMICALLY access the skins on a mesh (i.e. if you want to find what textures a Static mesh uses while ONLY having access to the StaticMesh object itself) then this code is neccessary.

Being able to dynamically access the skins in this way allows you to do tricks such as Making a Static mesh translucent by creating shaders that use modifiers to make an alpha channel. (which is how this code originated, I created it just for that)

Below is the code I have created which allows you to access the original materials.

NOTE:This is modified from my original code and I have not fully optimised it.

var class sClassPlaceholder;
 
// This function can be used to directly transfer to the Skins array in Engine.Actor
simulated function Array<Material> FindStaticMeshSkins(staticmesh SubjectMesh)
{
	local int iPointer, i;
	local string sParseString, sTextureClass, sMaterialsPropText;
	local array<Material> SkinArray< SEMI >
 
	// First of all obtain the string containing the list of the Materials on the Static mesh
	sMaterialsPropText = SubjectMesh.GetPropertyText("Materials");
 
 
	// This part of the function parses the string returned by GetPropertyText and returns the appropriate textures
	iPointer = InStr(sMaterialsPropText, ",Material=");
 
	while (iPointer != -1 && i < 256)
	{
		sParseString = Mid(sMaterialsPropText, iPointer + 10);
 
		// Check for a null-texture and if one is found then skip the current loop
		// NOTE: This includes the null value in the returned array, this is so it exactly mirror's the Materials array. (very important)
		if (Left(sParseString, 5) ~= "None)")
		{
			sMaterialsPropText = sParseString;
			Goto 'Skip';
		}
 
		iPointer = InStr(sParseString, "'");
 
		sTextureClass = Left(sParseString, iPointer);
 
 
		// I am not certain if this is needed since my original code was used for a slightly different purpose
		SetPropertyText("sClassPlaceholder", sTextureClass);
 
 
		sParseString = Mid(sMaterialsPropText, iPointer + 1);
 
		iPointer = InStr(sParseString, "'");
 
		sParseString = Mid(sParseString, iPointer + 1);
 
		iPointer = InStr(sParseString, "'");
 
 
		// Cut off the parsed section of sMaterialsPropText so that it will go onto the next section during the next iteration. (otherwise infinite recursion)
		sMaterialsPropText = Mid(sParseString, iPointer + 1);
 
		sParseString = Left(sParseString, iPointer);
 
 
		// Create a reference to the Material used on the mesh
		SkinArray[i] = Material(DynamicLoadObject(sParseString, sClassPlaceholder));
 
		Skip:
 
		iPointer = InStr(sMaterialsPropText, ",Material=");
 
		i++;
	}
 
	// Return the completed list of skins
	Return SkinArray< SEMI >
}

Related Topics[edit]

Comments[edit]

Shambler: My explanations of some things here could be better, maybe someone could have a shot at making things a bit more clear..