June 18, 2011
Hello ! I want to share with you some code that I have founded/coded by myself. It’s the best way for me to share and keep alive my different tests.
So with unrealscript in the UDK I have managed how to change the material of an object dynamically ! The UDK provide a specific type of material inherited from the basic materials : the material instances. With this material you can change specific value and change the rendering of the material.
KgravityActor :
class KgravityActor extends KActor
placeable
ClassGroup(Physics)
showcategories(Navigation);
//--material var
var float matLoading;
var MaterialInstanceConstant matInst;
var bool bCrystal; //are we crystalizing the mesh ?
simulated event PostBeginPlay()
{
enable('Tick');
initMaterial();
}
simulated event Tick(float DT)
{
super.Tick(DT);
//Change material
//transform object ?
if(bCrystal) //yes
{
matLoading += 0.25*DT;//Lerp(0.25, matLoading, 1.0); //update
}
else
{
matLoading -= 0.25*DT;//Lerp(-0.25, matLoading, 1.0); //update
}
toggleMaterial();
}
function initMaterial()
{
matInst = new(None) Class'MaterialInstanceConstant';
matInst.SetParent(StaticMeshComponent.GetMaterial(0));
StaticMeshComponent.SetMaterial(0, matInst);
`Log("__________Material Instance = " @ matInst);
toggleMaterial();
}
//enable/disable de crystal effect on an object
function toggleMaterial()
{
//Limit maximum value of
if(matLoading >= 1)
{
matLoading = 1;
}
else if(matLoading <= 0)
{
matLoading = 0;
}
MatInst.SetScalarParameterValue('matLoading',matLoading);
}
defaultproperties
{
//default mesh :
//PhysTest_Resources.RemadePhysBarrel
bCrystal = false;
matLoading = 0.0f;
Begin Object Name=StaticMeshComponent0
StaticMesh=StaticMesh'Layout.Mesh.instPhysbarrel'
WireframeColor=(R=0,G=255,B=128,A=255)
BlockRigidBody=true
RBChannel=RBCC_GameplayPhysics
RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE)
End Object
//physics enabled by default on level start
bWakeOnLevelStart = true;
bPawnCanBaseOn = true; //true for disabling bounce and bug with wall walking
}
Weapon :
local vector start, end, hitloc, hitnorm;
local actor hitactor;
local KgravityActor kgrav;
local TraceHitInfo hitinfo;
start = P.Location;
end = P.Location + 10000 * vector(P.Rotation);
hitactor = Trace(hitloc, hitnorm, end, start, true, , hitinfo);
DrawDebugLine(start, end, 0, 128, 0, true);
if(hitActor.isA('KgravityActor'))
{
`Log("KgravityActor !");
kgrav = KGravityActor(hitactor);
kgrav.bCrystal = !kgrav.bCrystal;
}
else if( hitActor == WorldInfo || hitActor.isA('StaticMeshActor') )
{
//Do something else
}
Here is the code that I use in my weapon, it’s very simple. I just check my Trace, if I have touched a KgravityActor, I change its bool, if not, I do something else.
Well : we need of course some variables for working. MatLoading is used to stored the current value of our parameter. With this parameter we change the color of the material (using the lerp in the material with the parameter as the alpha). So here, initMaterial is used to make the reference between my instanced material and the mesh when level start (in the postbeginplay). After in every tick I update the value of the parameter.
So when I change the value of my bool (bCrystal) I change the color of the material. In this case when bCrystal = true the material change to white.
As you can see with my weapon when I shot my KgravityActor I change their materials by simply set their bool bCrystal to true of false (just a simple toggle). This code is great because you can change the material of any object because the code don’t reference the name of the object/material. The only thing that matter is the name of the parameter. So as long as you put the good parameter in your material, everything works.