Announcement

Collapse

The Infinity Blade Forums Have Moved

We've launched brand new Infinity Blade forums with improved features and revamped layout. We've also included a complete archive of the previous posts. Come check out the new Infinity Blade forums.
See more
See less

How to setup Hitmasks

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

    How to setup Hitmasks

    Hi All,

    I have seen a number of questions and concerns about the lacking documentation on Hitmasks, so I thought I would quickly chuck something together in the hopes that it will help new comers. At the end of this post you will find a test map attached that shows examples of what I have outlined in this post. The screenshot below shows what you will see in the map (The rectangles are actually Skeletal Meshes)


    (Sorry the last rectangle did not come out so well, it is supposed to show a modular mesh with individual hitmasks being updated)

    Firstly in the code side, create yourself a new class in your game folder (For the time being I am extending from UTPawn, so I dont have to reimplemented any functionality) and paste in the following code.

    Code:
    class HitMaskActor extends UTPawn
    	placeable;
    
    var() SceneCapture2DHitMaskComponent HitMaskComponent;
    var TextureRenderTarget2D MaskTexture;
    
    simulated function PostBeginPlay( )
    {
    	local MaterialInstanceConstant MIC;
    
    	Super.PostBeginPlay( );
    
    	MaskTexture = class'TextureRenderTarget2D'.static.Create( 2048, 2048, PF_G8, MakeLinearColor( 0, 0, 0, 1 ) );
    
    	if( MaskTexture != None )
    	{
    		HitMaskComponent.SetCaptureTargetTexture( MaskTexture );
    
    		MIC = Mesh.CreateAndSetMaterialInstanceConstant( 0 );
    		if( MIC != None )
    		{
    			MIC.SetTextureParameterValue( 'FilterMask', MaskTexture );
    		}
    	}
    }
    
    simulated function Destroyed( )
    {
    	Super.Destroyed( );
    
    	MaskTexture = None;
    }
    
    function PlayHit( float Damage, Controller InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, TraceHitInfo HitInfo )
    {
    	Super.PlayHit( Damage, InstigatedBy, HitLocation, damageType, Momentum, HitInfo );
    
    	HitMaskComponent.SetCaptureParameters( HitLocation, 10.0f, HitLocation, False );
    }
    
    simulated function SetCharacterClassFromInfo(class<UTFamilyInfo> Info)
    {
    }
    
    DefaultProperties
    {
    	Begin Object Class=SceneCapture2DHitMaskComponent Name=HitMaskComp
    	End Object
    	HitMaskComponent=HitMaskComp
    	Components.Add(HitMaskComp)
    }
    The code is basically just creating a Render Target with only a single channel. (I have used 2048x2048 for testing, you can reduce this if you wish) Then assigning that render target to the SceneCapture2DHitMaskComponent, then setting up a Material Instance Constant and replacing 'FilterMask' texture sampler with our new Render Target.

    PlayHit is called when the Pawn is hit by a gun, so in there is where I have placed the code to mark the Hitmask with a hit.

    This will allow you to place your newly created actor into a level, it will have no mesh associated with it, so you will need to fix that up in the editor or add the necessary code in the DefaultProperties to load the SkeletalMesh.

    In the editor you will want to create a new material and set it up like the following to start off with, and assign it to your skeletal mesh (The hitmask texture I used is just a sample one so I could see the effect I wanted to achieve in the material editor, it will be replaced by our render target)



    The important parts are the Texture Parameter is called 'FilterMask' and the Texture Coordinate UnMirrorU checkbox is ticked
    When you run the level (Make sure to set the GameTypeForPIE as UTGame) and shoot the actor, you will see white circles appearing in the locations you hit. This represents the areas that have been hit, where you will reveal your hit/blood texture.

    Next you can change your material to look like the following



    The noisy Texture Sample is just a quick texture I threw together in Photoshop, using the noise filter, followed by the sponge filter, added a layer clouds and set the layer style to "soft light" then adjusted the color levels to darken it a bit, it makes the blood slightly darker in some areas so its not just a straight one color red.

    What you will see when you run the level is that the actor will now display perfectly circular red marks where you hit it.

    The third material will break up the circular hits, so change the material to look like the following



    The warp texture I used was Texture2D'CH_TwinSouls_Cine.Mesh.T_FX_VehicleSpawn Pattern2_G_Dup' and this just warps the incoming UV's so that you no longer get direct circles when you hit. So when you run the level with this material, you will see something that looks a bit more bloody. From here you can play around to see what sort of effects you can come up with.

    Modular Meshes

    To apply this same effect on modular pawns (Ones with multiple SkeletalMeshComponents) I have see some people say that they have been breaking up the Components into individual Actors to get around the issue with hitmasks using the Owners SkeletalMeshComponent only. The other alternative is represented in the level file I have attached.

    Basically in SceneCapture2DHitMaskComponent.uc I removed const from the line 'var transient const SkeletalMeshComponent SkeletalMeshComp' to allow other classes to change that variable. And then just before I write to that SceneCapture2DHitMaskComponent I change the skeletal mesh component to the one I want to update. As it will always default back to the owners one.

    Otherwise the basic principles are to ensure you have one render target, one SceneCapture2DHitMaskComponent, and one MaterialInstanceConstant for each modular part of your pawn. So if your module is made up of 7 Skeletal meshes, you will have 7 Render Targets, 7 SceneCapture2DHitMaskComponent's and 7 MIC's.

    Well hopefully that has made things a little clearer. I'm not the best at tutorials. If not then let me know and I will try to help.

    Link to Sample Map: http://www.mediafire.com/?jud2dn53pgwl8nu

    1. Unzip to the root of your UDK directory (Will extract files to correct places)
    2. This will replace SceneCapture2DHitMaskComponent with my modified version (To remove the const)
    3. Add 'HitMaskGame' to your Packages in DefaultEngine.ini
    4. Recompile the source and then you can load HitMask.udk

    EDIT: New link provided for sample map

    #2
    Nice tutorial

    Though the link it's broken

    Comment


      #3
      AWESOME AWESOME AWESOME!!! I was looking for this exact tutorial. Thank You Ehamloptiran!!!

      Comment


        #4
        hehhe mediafire for the win !
        Thanks you alot gona test it out now : D

        Comment


          #5
          Huge thanks for the tutorial but im having some dificulties

          i setted up the material and code exactly like the example you posted, the render target gets created succesfully in my pawn model (since it goes completly black) in the material i just have an texture sample parameter 2D pointing to the mask texture and the Texture Coordinates with UTiling set to on.. but yet when i shot my pawn it does nothing the texture never comes up

          Comment


            #6
            alvaro: that has little to do with the HitMask, and more with the collision detection. this also goes for Neongho who will probably come up with the same problem.

            you're probably passing the shot's HitLocation as the coordinates to paint the HitMask, right? this works well for BSP and static meshes with proper collision volumes, but not quite with Pawns.
            the problem is that your shot is colliding with the Pawn's collision cylinder, which most of the time is so far offset from the mesh that the painted coordinates totally miss the mesh.
            To make sure this really is your problem, try setting the HitMask paint radius much much bigger (2 to 5+ times bigger). you should at least see something.

            if this really is the problem, you need to make your HitLocation much more accurate in relation to the mesh. on my end I went for full-blown mesh accuracy: after the shot gets the hit Pawn with a regular trace, I do a TraceComponent against the hit Pawn's mesh which ignores the collision cylinder and gets a proper HitLocation against the mesh. yes it's slower but it's super accurate (ie. you can even trace the mesh outside of the collision cylinder like wide-open arms)
            this will paint the hitmask right where the shot hit and visually will be perfectly accurate[see proof]

            Comment


              #7
              Chosker is absolutely right, and I should have called that out at the top, the HitLocation code is in no way sufficient, just a quick example to get it up and going

              Comment


                #8
                Ah i see now HUGE thanks!, but im kinda confused im doing exactly the same for my melee weapon class (you know the tread where you helped me : p) But yet the hitmask doesnt show up I did made sure i was hitting the Phys asset and not the collision Cylinder of the pawn i.e im able to hit the body outside of the collision cylinder etc

                But then increasing the radius does Make it show but as you sayd in the wrong location ...

                Comment


                  #9
                  alvarofer , i suggest you use , the location given from the takedamage of the player that you give damage

                  you could catch it, by mutiple ways

                  obiusly you could use the CustomPawn(HitActor)

                  Comment


                    #10
                    Tried that but its exactly the same

                    Comment


                      #11
                      Neongho: isn't the location given from TakeDamage traced against the cylinder component?

                      as I already stated previously try tracing against the Mesh using TraceComponent for the best results
                      even though my screenshot only shows arrows, it works just the same with my melee weapon code

                      in any case for debugging you can try doing a DrawDebugSphere every time your function paints into the HitMask. use the same HitLocation and the HitMask paint radius as your Sphere parameters, this way what you'll be seeing as a sphere will be pretty much the same area that should be painted into the HitMask

                      Comment


                        #12
                        Thanks chosker is just tried that and while the sphere was getting in the right positions the hit mask did not, again it doesnt even come up i used the same values from the hit mask and the debug sphere looks fine..

                        Just for testing when my weapon hits the pawn i made another function in the pawn where i use the vector from the TraceComponent into the mesh

                        the function in the pawn

                        Code:
                        exec function HitMaskTest(vector TestV)
                        {
                        HitMaskComponent.SetCaptureParameters( TestV, 20.0f, TestV, FALSE ); // alredy tried with both false and true
                        DrawDebugSphere(TestV,16,20,255,0,0,true);
                        }
                        and the trace component in the weapon class

                        Code:
                        	
                        	if(TraceComponent(HitLocation, HitNormal,TmpComp, Interval1Start, Interval1End) == true)
                        	{
                        	//`Log("ON TRACE COMPONENT"$TmpComp);
                        		// Skip the pawn using the sword
                        		if(HitActor == Instigator || !HitActor.bCanBeDamaged)
                        			continue;
                        		if(HitActor != Owner && CheckHurtList(HitActor) == true)		    //If the Pawn isn't in the SwingHurt List, deal the damage.
                               {
                        
                        		// Apply damage with a momentum direction from Instigator location to HitActor location
                        		CheckActor.TakeDamage( SwordAttackHitDamage[ComboIndex], Instigator.Controller,
                        						HitActor.Location, Normal(HitActor.Location - Instigator.Location) * 50,
                        						InstantHitDamageTypes[CurrentFireMode],, self);
                        						 WorldInfo.MyEmitterPool.SpawnEmitter(EffectToPlay,HitLocation);
                        						 TakeDurability(1);
                        						 tfpPawn(HitActor).HitMaskTest(HitLocation); // Just calling the function here....
                        						
                        					
                        	   }
                        	}

                        Comment


                          #13
                          Thanks chosker that information it's pretty valuable i want exact location depending on the body, nd thanks alvarofer for posting the code , i haven't even tried yet lol so busy implementign stuff and stuff , coding never ends!

                          Comment


                            #14
                            Originally posted by Chosker View Post
                            you're probably passing the shot's HitLocation as the coordinates to paint the HitMask, right? this works well for BSP and static meshes with proper collision volumes, but not quite with Pawns.
                            Is there way to implant HitMask Component into any other type of mesh(such as StaticMesh)?
                            I've tried to do on static meshes, but couldn't find any solutions.

                            Comment


                              #15
                              alvaro: are you sure you did the unmirror thing? (http://udn.epicgames.com/Three/HitMa...ture Parameter)
                              if you say your debug sphere pops up in the right place then everything else should be fine. you did name the material parameter just like the tutorial, right?
                              can you also put a `log inside your HitMaskTest function to make sure the code is getting that far?


                              slavelegend: it should work all the same on a static mesh.
                              notice that in this tutorial the HitMask gets painted on when the PlayHit function is executed. PlayHit happens on a Pawn when it's hit, and a StaticMeshActor doesn't have it. this is because the tutorial is an example of how one would implement HitMasks, and the author did it for Pawns only. but even if you created a custom class extending StaticMeshActor, it still would never do PlayHit.
                              The ideal here would be to implement it in the weapon code at the time it hits something, and so you would get rid of needing PlayHit altogether

                              Comment

                              Working...
                              X