Code viewer
Change Temperature
#Kismet
A custom Kismet node that can change the world temperature at runtime.
This node also has a Duration property, that allows smoothly interpolating the heat overlay effect.
NOTE: You may want to edit the value of ObjCategory to something unique, so you can tell it apart from other copies of this script.
class Drew_SeqAct_ChangeTemperature extends SequenceAction; /** * The new temperature the map should use. A MapInfo needs to exist for this to work. */ var() float NewTemperature; /** * If > 0, how long should it take to interpolate the heat overlay. */ var() float Duration; event Activated() { local WorldInfo WI; local Hat_MapInfo MI; local Engine E; local LocalPlayer LP; WI = GetWorldInfo(); MI = Hat_MapInfo(WI.GetMapInfo()); if (MI == None) return; MI.Temperature = NewTemperature; // Update any usage of temperature in materials. WI.UpdateGenericSceneProxyParameters(); // Also update the heat overlay(s). E = class'Engine'.static.GetEngine(); foreach E.GamePlayers(LP) { UpdateHeatOverlayEffect(LP); } } function UpdateHeatOverlayEffect(LocalPlayer LP) { local Hat_HUD H; local MaterialEffect m; local MaterialInstance MatInst; local InterpCurveFloat Curve; local float Temp, PrevTemp; H = Hat_HUD(LP.Actor.MyHUD); if (H == None) return; m = MaterialEffect(LP.PlayerPostProcess.FindPostProcessEffect('HeatOverlay')); if (m == None) return; MatInst = MaterialInstance(m.GetMaterial(true)); if (MatInst == None && Duration <= 0.f) // Wasn't initialized (overridden) yet? { // Let Hat_HUD initialize it and handle the temperature effect. H.InitPostProcessMaterialInstance(); return; } // We got here, so we need to update the parameter manually. Temp = H.GetSceneTemperature(); if (Duration > 0.f) { PrevTemp = 0.f; if (MatInst != None) MatInst.GetScalarParameterValue('Scale', PrevTemp); // We need to interpolate, so we need a time-varying material. if (MaterialInstanceTimeVarying(MatInst) == None) { // That won't do - recreate it as time-varying. MatInst = new(m) class'MaterialInstanceTimeVarying'; MatInst.SetParent(m.GetMaterial(false)); m.SetMaterial(MatInst); } Curve = H.GenerateCurveFloat(PrevTemp, Temp, Duration); MaterialInstanceTimeVarying(MatInst).SetScalarCurveParameterValue('Scale', Curve); MaterialInstanceTimeVarying(MatInst).SetScalarStartTime('Scale', 0.0); } else if (MaterialInstanceTimeVarying(MatInst) != None) { // For whatever reason, calling SetScalarParameterValue doesn't work anymore once we've done our time-varying conversion. // Create a dummy curve that just sets the value instantly, I guess. Curve = H.GenerateCurveFloat(Temp, Temp, 0.f); MaterialInstanceTimeVarying(MatInst).SetScalarCurveParameterValue('Scale', Curve); MaterialInstanceTimeVarying(MatInst).SetScalarStartTime('Scale', 0.0); } else { MatInst.SetScalarParameterValue('Scale', Temp); } if (Temp <= 0.f && Duration > 0.f && H.WorldInfo.TimeDilation > 0.f) { // We gotta wait for the interpolation to end before we can hide the effect completely. // Set the timer on the archetype so its correctly reset, even when using multiple nodes. H.SetTimer(Duration / H.WorldInfo.TimeDilation, false, NameOf(DelayedUpdateShowInGame), ObjectArchetype, LP); } else { m.bShowInGame = (Temp > 0.f); } } function DelayedUpdateShowInGame(LocalPlayer LP) { local Hat_HUD H; local MaterialEffect m; H = Hat_HUD(LP.Actor.MyHUD); if (H == None) return; m = MaterialEffect(LP.PlayerPostProcess.FindPostProcessEffect('HeatOverlay')); if (m == None) return; m.bShowInGame = (H.GetSceneTemperature() > 0.f); } defaultproperties { ObjName = "Change Temperature" ObjCategory = "Give me a custom category!" bCallHandler = false VariableLinks.Empty }