Announcement

Collapse
No announcement yet.

[Video][Code] Dynamically Show Whole Screen Effects (Post Process Material Effects)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [Video][Code] Dynamically Show Whole Screen Effects (Post Process Material Effects)

    Create Whole Screen Effects and cycle through them while in-game with press of a button!

    In this tutorial I show you the unrealscript code to dynamically set the Post Process Material Effects for your Post Process Chain for Your Level.

    This enables you to do things like:

    1. show indicator of damage taken as the edges of the player screen glowing red in a spherical shape
    2. make the whole screen turn blurry for a short time to show sudden velocity increase
    3. Fade the screen to a desaturation (more black and white) as the player unit dies
    4. Create a visual overlay of a Lightning Effect across entire player screen to show player is being hit by a lightning weapon.


    Here's a video I made showing you what this tutorial will help you do!

    Be sure to get to the part of video where I demo my Rainbow Effect !

    I find it exceedingly entertaining (starts at 5:20 in video)


    ~~~

    Three Material Effects For You

    At the end of this tutorial I give you the whole code for 3 of the material effects in this video, including my absolute favorite!

    1. Intense Motion Blur
    2. Sine Wavy Effect
    3. Rainbow Effect

    ~~~

    Creating Whole Screen Effects For Your Game

    Effects that alter your entire screen while in game, known as the Scene, are controlled via something called the Post Process Chain.

    Every level has only 1 Post Process Chain as its default chain.

    After you've created your Post Process Chain, go to view-> world properties in the UDK to Set your PPC.



    ~~~

    Creating and Naming Post Process Chain Nodes

    If your level doesn't have one that you feel like modifying, you need to make a new one by right-clicking-> new post process chain while in your preferred package.


    Add an UberPostProcessNode and a Material Effect Node.

    Then you can tweak the settings till you are happy with how your game looks.


    Make sure the little G in top button row of UDK is pressed, so you are seeing the game view of your PPC in action.


    Note you should add a Material Effect node but you dont have to set it to anything, just give it a name that you will then use in your code.

    ~~~

    Using The Code Below With Many Levels

    The PPC for each level must have the same kinds of nodes with the same exact names.

    So the materialeffect node must have same name in every level's Post Process Chain.

    ~~~

    Code to Change Material Effects While In-Game

    Code:
    //Put this code in an ACTOR subclass
    //because of the attempt to access
    //WorldInfo as used in the code
    
    //PPC data that is set in defaultproperties
    //testing only
    var PostProcessChain PPC;  
    
    var int curMaterialEffectIndex;
    
    //global temp data
    //for speed efficiency
    var array<PostProcessEffect> curEffects;
    //======================================
    
    //list all the nodes in the
    //Post Process Chain assigned
    //via defaultproperties
    //just for testing really
    function listPPEs() {
    	local int v;
    	for (v = 0; v < PPC.Effects.length; v++ ) {
    		`log("ppe"$v@PPC.Effects[v].EffectName);
    	}	
    }
    
    //I modified loadCurEffects code from the UDN tutorial
    
    function loadCurEffects(Name effectName, 
    optional class<PostProcessEffect> MatchingPostProcessEffectClass = class'PostProcessEffect') 
    {
      local PostProcessEffect PostProcessEffect;
      local PlayerController PlayerController;
      local LocalPlayer LocalPlayer;
    
    	//----- clear the old global array data -----
    	curEffects.length = 0;
    	//-----------------------------------------------
    	
      // Affect the world post process chain
      if (WorldInfo != None)
      {
        ForEach WorldInfo.AllControllers(class'PlayerController', PlayerController)
        {
          LocalPlayer = LocalPlayer(PlayerController.Player);
    
          if (LocalPlayer != None && LocalPlayer.PlayerPostProcess != None)
          {
            PostProcessEffect = LocalPlayer.PlayerPostProcess.FindPostProcessEffect(effectName);
    
            if (PostProcessEffect != None && 
          (PostProcessEffect.Class == MatchingPostProcessEffectClass ||    
          ClassIsChildOf(PostProcessEffect.Class, MatchingPostProcessEffectClass))
        ) {
              curEffects.AddItem(PostProcessEffect);
            }
          }
        }
      }
    }
    
    //repeated calls to this function
    //cycle the material effect among 3 choices
    
    //you must create/choose which
    //effects are displayed.
    //I provide you with the code
    //for 3 of the effects below
    function cycleScreenEffects() {
    
    	local MaterialEffect ppe;
    	local int v;  
    
    	//get all nodes from the current PPC
    	//that are named 'VictoryScreenEffects'
    	
    	//you must name your PPC nodes
    	//via UDK editor
    
    	//you can create new PPC
    	//and add a uberpostprocess node
    	//and a materialeffect node
    	//and name both to have most
    	//PostProcess effects available to you
    	//via code (the other big one is a Blur node)
    
    	//load the material effect node by name
    	loadCurEffects('VictoryScreenEffects');
    	
    	if (curEffects.Length <= 0) return;
    	for (v = 0; v < curEffects.length; v++) {
    		
    	  //get the next node that is named 
    	  //'VictoryScreenEffects'
    	  ppe = MaterialEffect(curEffects[v]);
    			
    	  if (ppe != None) { 
    				
    	  curMaterialEffectIndex++;
    				
    	  //reset cycle
    	  if (curMaterialEffectIndex > 3) curMaterialEffectIndex = 0;
    				
    	  if (curMaterialEffectIndex == 0) {
    	    ppe.Material = none;
    	  }
    	  else if (curMaterialEffectIndex == 1) {
    	    ppe.Material = Material'YourPackage.blurEffect';
    	  }
    	  else if (curMaterialEffectIndex == 2) {
    	    ppe.Material = Material'YourPackage.sineWavyEffect';
    	  }
    	  else if (curMaterialEffectIndex == 3) {
    	    ppe.Material = Material'YourPackage.RainbowEffect';
    	  }
    		
    	  } // end ppe != none
    } //for loop
    }
    
    DefaultProperties
    {
    	//PPC
    	//get path of your PPC in UDK
    	//by right clicking on it
    	//"copy full path"
    	
    	//if you have many levels with different PPCs
    	//dont worry, this is just for testing really
    	//and is not used in the main code.
    	PPC = PostProcessChain'YourPackage.YourPostProcessChain'
    }
    ~~~

    Calling cycleScreenEffects()

    See this tutorial of mine for info on how you can capture user input to run the cycleScreenEffects() function any time you want while in game:

    Capturing User Keyboard/Mouse Input


    ~~~

    Creating Your Material Effects

    Look up info on Material Instances if you want to be able to change the actual properties of your material effect during gameplay.


    For this tutorial I am showing simple materials.

    Here's the whole code I used for 3 of the Materials you see in my video (the 4th one used a custom texture I made):

    Extreme Blur Material Effect




    Sine Wavy Material Effect



    Rainbow Material Effect



    ~~~

    Multiple Material Effects at Same Time?

    Simply create additional Material Effect Nodes in your PPC and give them unique names!

    So you could have your EnvironmentalMaterialNode, and your DamageIndicatorNode, etc etc.

    Turn any of them off by setting the material to none or setting bshowinGame to false;

    ~~~

    Summary

    Using the code I've provided you with and your own creativity with making material effects, you can create all sorts of new themes, special effect, environment effects, damage indicators, speed of motion indicators and much more!

    And you can show these material effects and specify their duration with simple function calls!

    Enjoy!

    Rama

    PS: Advanced:

    Use Material Instances to set parameters for your materials that you can edit via unrealscript, to for example, have a slowly increasing desaturation of the scene that is controlled by unrealscript code as the desaturation value in the material is a parameter.

    Material Instance Tutorial

    #2
    Awesome

    I was going to impliment a time dilation while the players health was though but i might give your blur effect a try, looks great

    Comment


      #3
      Im about to give this a try, ive set up my ppc with names nodes all sorted with that bit, about to start with the code now lol

      I want to put this in my pawn class and call it from my pawn class when my player reaches XX amount of health, i know how to do that and how to make it stops when it goes back over xx amount of health. Would it be a similar process for this for calling it and ending it? Any tips?

      Im using a blur effect when the players health gets low, I am already using sound for it so it should just be a matter of calling this as well inside that function. Here is my code for that part -

      Code:
      event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
      {
          super.TakeDamage(DamageAmount, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
          if (Health <= 36)
          {
              HealthSound.Play();
          }
      }
      
      
      function Tick(float DeltaTime)
      {
          Super.Tick(DeltaTime);
      
          if (Health > 48)
               HealthSound.Stop();
      }
      
      
      
      
      simulated event Destroyed()
      {
          HealthSound = None;
          super.Destroyed();
      }

      Comment


        #4
        Here's the code you'll want then, if you want to vary the amount of blur through code, well I am releasing a new tutorial on that subject soon!

        but for just blur on and blur off, using a material effect (for other readers, this is not about regular blur node, you could use this code I am posting for any kind of whole screen effect)

        Code:
        //global temp data
        //for speed efficiency
        var array<PostProcessEffect> curEffects;
        
        //I modified loadCurEffects code from the UDN tutorial
        
        function loadCurEffects(Name effectName, 
        optional class<PostProcessEffect> MatchingPostProcessEffectClass = class'PostProcessEffect') 
        {
          local PostProcessEffect PostProcessEffect;
          local PlayerController PlayerController;
          local LocalPlayer LocalPlayer;
        
        	//----- clear the old global array data -----
        	curEffects.length = 0;
        	//-----------------------------------------------
        	
          // Affect the world post process chain
          if (WorldInfo != None)
          {
            ForEach WorldInfo.AllControllers(class'PlayerController', PlayerController)
            {
              LocalPlayer = LocalPlayer(PlayerController.Player);
        
              if (LocalPlayer != None && LocalPlayer.PlayerPostProcess != None)
              {
                PostProcessEffect = LocalPlayer.PlayerPostProcess.FindPostProcessEffect(effectName);
        
                if (PostProcessEffect != None && 
              (PostProcessEffect.Class == MatchingPostProcessEffectClass ||    
              ClassIsChildOf(PostProcessEffect.Class, MatchingPostProcessEffectClass))
            ) {
                  curEffects.AddItem(PostProcessEffect);
                }
              }
            }
          }
        }
        
        function toggleScreenEffect(bool b) {
        
        	local MaterialEffect ppe;
        	local int v;  
        
        	//load the material effect node by name
        	loadCurEffects('NameOfNodeYouWantToToggle');
        	
        	if (curEffects.Length <= 0) return;
        	for (v = 0; v < curEffects.length; v++) {
        		
        	  ppe = MaterialEffect(curEffects[v]);
        			
        	  if (ppe != None) { 
        				
        		if (b) {
        			ppe.Material = Material'YourPackage.blurEffect';
        		else{
        			ppe.Material = none;
        			
        	  } // end ppe != none
        } //for loop
        }

        Comment


          #5
          Thanks, Ill give it a whirl now

          Comment


            #6
            One day something will work first time but not today.. Get a compile error unexpected end of class, any ideas here is my code -

            Code:
            //I modified loadCurEffects code from the UDN tutorial
            
            function loadCurEffects(Name effectName, 
            optional class<PostProcessEffect> MatchingPostProcessEffectClass = class'PostProcessEffect') 
            {
              local PostProcessEffect PostProcessEffect;
              local PlayerController PlayerController;
              local LocalPlayer LocalPlayer;
            
            	//----- clear the old global array data -----
            	curEffects.length = 0;
            	//-----------------------------------------------
            	
              // Affect the world post process chain
              if (WorldInfo != None)
              {
                ForEach WorldInfo.AllControllers(class'PlayerController', PlayerController)
                {
                  LocalPlayer = LocalPlayer(PlayerController.Player);
            
                  if (LocalPlayer != None && LocalPlayer.PlayerPostProcess != None)
                  {
                    PostProcessEffect = LocalPlayer.PlayerPostProcess.FindPostProcessEffect(effectName);
            
                    if (PostProcessEffect != None && 
                  (PostProcessEffect.Class == MatchingPostProcessEffectClass ||    
                  ClassIsChildOf(PostProcessEffect.Class, MatchingPostProcessEffectClass))
                ) {
                      curEffects.AddItem(PostProcessEffect);
                    }
                  }
                }
              }
            }
            
            
            
            
            function toggleScreenEffect(bool b) {
            
            	local MaterialEffect ppe;
            	local int v;  
            
            	//load the material effect node by name
            	loadCurEffects('PlayerBluryM2');
            	
            	if (curEffects.Length <= 0) return;
            	for (v = 0; v < curEffects.length; v++) {
            		
            	  ppe = MaterialEffect(curEffects[v]);
            			
            	  if (ppe != None) { 
            				
            		if (b) {
            			ppe.Material = Material'gshipV3.Dblur';
            		else{
            			ppe.Material = none;
            			
            	  } // end ppe != none
            } //for loop
            }
            
            
            
            event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
            {
                super.TakeDamage(DamageAmount, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
                if (Health <= 36)
                {
                    HealthSound.Play();
            toggleScreenEffect.();
             
                }
            }
            
            
            simulated function SetCharacterClassFromInfo(class<UTFamilyInfo> Info); 
            
            
            
            function Tick(float DeltaTime)
            {
                Super.Tick(DeltaTime);
            
                if (Health > 48)
                     HealthSound.Stop();
            toggleScreenEffect.();
            }
            
            
            
            
            simulated event Destroyed()
            {
                HealthSound = None;
                super.Destroyed();
            toggleScreenEffect.();
            }
            I have assigned var, and default properties as in your tut.

            Thanks in advance

            Comment


              #7
              That error means your missing a closing bracket somewhere.

              Comment


                #8
                Originally posted by bwhit View Post
                That error means your missing a closing bracket somewhere.
                Thats wht i thought but it wasnt obvious. Ill have another check. Cheers

                Comment


                  #9
                  Found it now, now im getting some errors, i used -

                  Code:
                  toggleScreenEffect.();
                  What do i need to togle the effect?

                  I Also get Error on Line 88 (error `esle` bad command or expression)

                  Comment


                    #10
                    Originally posted by madaboutagmes View Post
                    Found it now, now im getting some errors, i used -

                    Code:
                    toggleScreenEffect.();
                    What do i need to togle the effect?

                    I Also get Error on Line 88 (error `esle` bad command or expression)
                    so put true in lol, still get the other error. else bad command etc.. any ideas?

                    Comment


                      #11
                      sorted it now, just get a warning - unknown properties in defaults .. .. ppc my bag i think so ill gert it sorted and give it a test

                      Comment


                        #12
                        Compiles fine but can not get it to work. I have got it compile ok and have the pp effects sorted and named correctly. Is it because I am using this on my pawn class? Should i be using it on my player controller class?

                        Comment


                          #13
                          please post your code and explain your whole set up

                          Till you do that make sure:

                          1. your map has your custom ppc set as its default ppc, udk->view->world properties
                          2. your ppc nodes have bshowingame = true
                          3. verify the function you are checking is actually being called at all

                          `log("this function DID run! ============ ! ===========");

                          Comment


                            #14
                            I didnt set my default pp for world, lol ill give it another try

                            Comment


                              #15
                              I'm off to bed now, good luck!

                              make sure to use `log("this function did run") as often as you can when things dont work as you want

                              helps narrow things down real fast

                              just include -log in your udk.exe run command



                              Rama

                              Comment

                              Working...
                              X