When game creators want to have naked characters running around their virtual world without getting slapped with an M or AO rating, the tried and true technique (used by many games including The Sims and the Saints Row games) is the classic mosaic-style censor bar over the offending bits. It’s the way to make sure no app reviewer is ever subjected to virtual dangly bits that might get you rejected from the App Store!
Now, unlike me, you are probably far too much of an upstanding and virtuous person for such lechery. But… just in case it ever comes up in one of your games, here’s how you can go about implementing that effect.
First, you’ll need to create a new material. I called mine [FONT=Courier New]M_Pixelate. It needs to use a blend mode of Translucent, but otherwise, the default settings should work fine:
The node graph for this is pretty simple. We’re going to use the screen position to drive the UVs on a Scene Color node. We’ll multiply the screen position by a parameter value, floor the result, and then divide the floored value by the same parameter value. The end result is that the same color ends up being used for several pixels in a row in both X and Y directions. Increasing the value used for the multiply and divide will decrease the size of the mosaic blocks (and vice-versa). Here’s what that would look like in the material editor (click for full size):
http://8.t.imgbox.com/Eu9vVIxK.jpg
Here’s the graph node if you want to paste into your material:
Begin Object Class=MaterialGraphNode_Root Name="MaterialGraphNode_Root_0"
Begin Object Class=EdGraphPin Name="EdGraphPin_51079"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51078"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51077"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51076"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51075"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51074"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51073"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51072"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51071"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51070"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51069"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51068"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51067"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51066"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51065"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51064"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51063"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51062"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51061"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51060"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51059"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51058"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51057"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51056"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51055"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51054"
End Object
Begin Object Name="EdGraphPin_51079"
PinName="Pixel Depth Offset"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51078"
PinName="Material Attributes"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51077"
PinName="Customized UV7"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51076"
PinName="Customized UV6"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51075"
PinName="Customized UV5"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51074"
PinName="Customized UV4"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51073"
PinName="Customized UV3"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51072"
PinName="Customized UV2"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51071"
PinName="Customized UV1"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51070"
PinName="Customized UV0"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51069"
PinName="Refraction"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51068"
PinName="Ambient Occlusion"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51067"
PinName="Clear Coat Roughness"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51066"
PinName="Clear Coat"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51065"
PinName="Subsurface Color"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51064"
PinName="Tessellation Multiplier"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51063"
PinName="World Displacement"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51062"
PinName="World Position Offset"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51061"
PinName="Normal"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51060"
PinName="Opacity Mask"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51059"
PinName="Opacity"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51058"
PinName="Emissive Color"
PinType=(PinCategory="materialinput")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_0.EdGraphPin_51081'
End Object
Begin Object Name="EdGraphPin_51057"
PinName="Roughness"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51056"
PinName="Specular"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51055"
PinName="Metallic"
PinType=(PinCategory="materialinput")
End Object
Begin Object Name="EdGraphPin_51054"
PinName="Base Color"
PinType=(PinCategory="materialinput")
End Object
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
Pins(0)=EdGraphPin'EdGraphPin_51054'
Pins(1)=EdGraphPin'EdGraphPin_51055'
Pins(2)=EdGraphPin'EdGraphPin_51056'
Pins(3)=EdGraphPin'EdGraphPin_51057'
Pins(4)=EdGraphPin'EdGraphPin_51058'
Pins(5)=EdGraphPin'EdGraphPin_51059'
Pins(6)=EdGraphPin'EdGraphPin_51060'
Pins(7)=EdGraphPin'EdGraphPin_51061'
Pins(8)=EdGraphPin'EdGraphPin_51062'
Pins(9)=EdGraphPin'EdGraphPin_51063'
Pins(10)=EdGraphPin'EdGraphPin_51064'
Pins(11)=EdGraphPin'EdGraphPin_51065'
Pins(12)=EdGraphPin'EdGraphPin_51066'
Pins(13)=EdGraphPin'EdGraphPin_51067'
Pins(14)=EdGraphPin'EdGraphPin_51068'
Pins(15)=EdGraphPin'EdGraphPin_51069'
Pins(16)=EdGraphPin'EdGraphPin_51070'
Pins(17)=EdGraphPin'EdGraphPin_51071'
Pins(18)=EdGraphPin'EdGraphPin_51072'
Pins(19)=EdGraphPin'EdGraphPin_51073'
Pins(20)=EdGraphPin'EdGraphPin_51074'
Pins(21)=EdGraphPin'EdGraphPin_51075'
Pins(22)=EdGraphPin'EdGraphPin_51076'
Pins(23)=EdGraphPin'EdGraphPin_51077'
Pins(24)=EdGraphPin'EdGraphPin_51078'
Pins(25)=EdGraphPin'EdGraphPin_51079'
NodeGuid=504CAE4BD74EFEC3D339ACBBD6BE2AD6
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_0"
Begin Object Class=EdGraphPin Name="EdGraphPin_51081"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51080"
End Object
Begin Object Class=MaterialExpressionSceneColor Name="MaterialExpressionSceneColor_0"
End Object
Begin Object Name="EdGraphPin_51081"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_Root_0.EdGraphPin_51058'
End Object
Begin Object Name="EdGraphPin_51080"
PinName="UVs"
PinType=(PinCategory="optional")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_6.EdGraphPin_51093'
End Object
Begin Object Name="MaterialExpressionSceneColor_0"
Input=(Expression=MaterialExpressionDivide'MaterialGraphNode_6.MaterialExpressionDivide_0')
MaterialExpressionEditorX=-272
MaterialExpressionEditorY=128
MaterialExpressionGuid=EFEFC1CF96450374BC58F9B6C86CF6D5
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionSceneColor'MaterialExpressionSceneColor_0'
Pins(0)=EdGraphPin'EdGraphPin_51080'
Pins(1)=EdGraphPin'EdGraphPin_51081'
NodePosX=-272
NodePosY=128
NodeGuid=594011462C4FF9D96DE7ECAD972925EC
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_1"
Begin Object Class=EdGraphPin Name="EdGraphPin_51082"
End Object
Begin Object Class=MaterialExpressionScreenPosition Name="MaterialExpressionScreenPosition_0"
End Object
Begin Object Name="EdGraphPin_51082"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_2.EdGraphPin_51083'
End Object
Begin Object Name="MaterialExpressionScreenPosition_0"
MaterialExpressionEditorX=-1062
MaterialExpressionEditorY=-31
MaterialExpressionGuid=9AEE150CD24BB4EB8BACE0BE0558CE53
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionScreenPosition'MaterialExpressionScreenPosition_0'
Pins(0)=EdGraphPin'EdGraphPin_51082'
NodePosX=-1062
NodePosY=-31
NodeGuid=5831C89667486375C82079A8C33A1637
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_2"
Begin Object Class=EdGraphPin Name="EdGraphPin_51084"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51083"
End Object
Begin Object Class=MaterialExpressionComponentMask Name="MaterialExpressionComponentMask_0"
End Object
Begin Object Name="EdGraphPin_51084"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_4.EdGraphPin_51086'
End Object
Begin Object Name="EdGraphPin_51083"
PinName="Input"
PinFriendlyName=" "
PinType=(PinCategory="required")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_1.EdGraphPin_51082'
End Object
Begin Object Name="MaterialExpressionComponentMask_0"
Input=(Expression=MaterialExpressionScreenPosition'MaterialGraphNode_1.MaterialExpressionScreenPosition_0')
R=True
G=True
MaterialExpressionEditorX=-912
MaterialExpressionEditorY=-16
MaterialExpressionGuid=39D851DD864EA59AA9BDD89E77A45925
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionComponentMask'MaterialExpressionComponentMask_0'
Pins(0)=EdGraphPin'EdGraphPin_51083'
Pins(1)=EdGraphPin'EdGraphPin_51084'
NodePosX=-912
NodePosY=-16
NodeGuid=963715339A48EB1B93E2AAA200D6AA01
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_3"
Begin Object Class=EdGraphPin Name="EdGraphPin_51085"
End Object
Begin Object Class=MaterialExpressionScalarParameter Name="MaterialExpressionScalarParameter_0"
End Object
Begin Object Name="EdGraphPin_51085"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_4.EdGraphPin_51087'
LinkedTo(1)=EdGraphPin'MaterialGraphNode_6.EdGraphPin_51092'
End Object
Begin Object Name="MaterialExpressionScalarParameter_0"
DefaultValue=10.000000
ParameterName="MosaicSize"
ExpressionGUID=DC7BE420D042AA2731E237B7112C51DC
MaterialExpressionEditorX=-896
MaterialExpressionEditorY=160
MaterialExpressionGuid=F3C139132E40F3133226FFBF5CED1548
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionScalarParameter'MaterialExpressionScalarParameter_0'
Pins(0)=EdGraphPin'EdGraphPin_51085'
NodePosX=-896
NodePosY=160
bCanRenameNode=True
NodeGuid=978C2FC66845A2C6620AB19B73025B5F
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_4"
Begin Object Class=EdGraphPin Name="EdGraphPin_51088"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51087"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51086"
End Object
Begin Object Class=MaterialExpressionMultiply Name="MaterialExpressionMultiply_0"
End Object
Begin Object Name="EdGraphPin_51088"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_5.EdGraphPin_51089'
End Object
Begin Object Name="EdGraphPin_51087"
PinName="B"
PinType=(PinCategory="optional")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_3.EdGraphPin_51085'
End Object
Begin Object Name="EdGraphPin_51086"
PinName="A"
PinType=(PinCategory="optional")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_2.EdGraphPin_51084'
End Object
Begin Object Name="MaterialExpressionMultiply_0"
A=(Expression=MaterialExpressionComponentMask'MaterialGraphNode_2.MaterialExpressionComponentMask_0')
B=(Expression=MaterialExpressionScalarParameter'MaterialGraphNode_3.MaterialExpressionScalarParameter_0')
MaterialExpressionEditorX=-768
MaterialExpressionGuid=CEEADB684340CD6F3076A39AFA957117
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionMultiply'MaterialExpressionMultiply_0'
Pins(0)=EdGraphPin'EdGraphPin_51086'
Pins(1)=EdGraphPin'EdGraphPin_51087'
Pins(2)=EdGraphPin'EdGraphPin_51088'
NodePosX=-768
NodeGuid=21E80B9203417D784F64BBA54E0B647A
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_5"
Begin Object Class=EdGraphPin Name="EdGraphPin_51090"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51089"
End Object
Begin Object Class=MaterialExpressionFloor Name="MaterialExpressionFloor_0"
End Object
Begin Object Name="EdGraphPin_51090"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_6.EdGraphPin_51091'
End Object
Begin Object Name="EdGraphPin_51089"
PinName="Input"
PinFriendlyName=" "
PinType=(PinCategory="required")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_4.EdGraphPin_51088'
End Object
Begin Object Name="MaterialExpressionFloor_0"
Input=(Expression=MaterialExpressionMultiply'MaterialGraphNode_4.MaterialExpressionMultiply_0')
MaterialExpressionEditorX=-587
MaterialExpressionEditorY=46
MaterialExpressionGuid=AD9EEC0F884BB25E34FC3988BAF1EDAE
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionFloor'MaterialExpressionFloor_0'
Pins(0)=EdGraphPin'EdGraphPin_51089'
Pins(1)=EdGraphPin'EdGraphPin_51090'
NodePosX=-587
NodePosY=46
NodeGuid=3C4BFB394847E0ADD161249506F067B0
End Object
Begin Object Class=MaterialGraphNode Name="MaterialGraphNode_6"
Begin Object Class=EdGraphPin Name="EdGraphPin_51093"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51092"
End Object
Begin Object Class=EdGraphPin Name="EdGraphPin_51091"
End Object
Begin Object Class=MaterialExpressionDivide Name="MaterialExpressionDivide_0"
End Object
Begin Object Name="EdGraphPin_51093"
PinName="Output"
PinFriendlyName=" "
Direction=EGPD_Output
LinkedTo(0)=EdGraphPin'MaterialGraphNode_0.EdGraphPin_51080'
End Object
Begin Object Name="EdGraphPin_51092"
PinName="B"
PinType=(PinCategory="optional")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_3.EdGraphPin_51085'
End Object
Begin Object Name="EdGraphPin_51091"
PinName="A"
PinType=(PinCategory="optional")
LinkedTo(0)=EdGraphPin'MaterialGraphNode_5.EdGraphPin_51090'
End Object
Begin Object Name="MaterialExpressionDivide_0"
A=(Expression=MaterialExpressionFloor'MaterialGraphNode_5.MaterialExpressionFloor_0')
B=(Expression=MaterialExpressionScalarParameter'MaterialGraphNode_3.MaterialExpressionScalarParameter_0')
MaterialExpressionEditorX=-475
MaterialExpressionEditorY=110
MaterialExpressionGuid=49C526D94E4814AF96EA44B583AD4820
Material=PreviewMaterial'/Engine/Transient.M_Pixellate'
End Object
MaterialExpression=MaterialExpressionDivide'MaterialExpressionDivide_0'
Pins(0)=EdGraphPin'EdGraphPin_51091'
Pins(1)=EdGraphPin'EdGraphPin_51092'
Pins(2)=EdGraphPin'EdGraphPin_51093'
NodePosX=-475
NodePosY=110
NodeGuid=F5D73A529746F5E7CB21F0A50009AAAF
End Object
Next, we create a material instance based off of that material. The fastest way to do that is to simply right-click the material in the Content Browser and select Create Material Instance. In this material instance, you can set the size of the mosaic block parameter as needed for your purposes. Remember: bigger values make smaller block.
If we assign this material instance to any actor, the actor itself will basically disappear, but anything behind it (relative to the camera) will become pixelated. With this material, all you have to do is add a static mesh to our character class or blueprint, assign this material to that static mesh, then update the location and rotation of the static mesh each tick so that it keeps itself between the camera and the part of the character we don’t think our players are mature enough to see!
We need three properties to accomplish this - a mesh, a socket name, and a float. In C++, we’d add the following three properties to our header class:
UPROPERTY(EditDefaultsOnly, Category=Censor)
FName CensorBarTargetSocket;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Censor, meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent* CensorBar;
UPROPERTY(EditDefaultsOnly, Category=Censor)
float CensorBarDistanceFromSocket;
The first property is the name of a socket we’ll add later to our skeletal mesh. This socket is how we’ll identify the part of the model that needs to be obscured. You can leave this to be set later in Blueprint, or you can provide a default value in your constructor, like so:
CensorBarTargetSocket = FName(TEXT("censor"));
The second property is the static mesh that will serve as the actual mosaic. I just used the default cube mesh flattened to the shape I need, but you can use any static mesh. If you’re using C++, you’ll need to create the subobject in your constructor, like so:
CensorBar = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Censor Bar"));
CensorBar->AttachParent = GetCapsuleComponent();
The last property represents how far away from the socket to place the censor bar. If we were to place it right at the socket, the censor bar mesh would intersect with the character mesh, and only parts of the character mesh would get mosaic’ed. Instead, we need to offset it a bit in the direction of the camera. This variable lets us configure how far because the actual distance needed will depend on the size of the part of the model being obscured [insert your own dirty joke here]. I set a reasonable default value in my constructor of a half meter, knowing I can adjust it later in my blueprint to get the ideal distance.
CensorBarDistanceFromSocket = 50.f;
If you’re working only in Blueprint, you can accomplish the same thing by adding a static mesh component using the green button in the Blueprint Editor, selecting the cube or other mesh and sizing it appropriately in the Viewport. You then need two variables, a [FONT=Courier New]Name to hold the socket name and a [FONT=Courier New]float to hold the distance).
Make sure to size the censor bar a little bigger than it looks like you need to account for different camera angles. Don’t worry about placement or orientation of the mesh - we’ll take care of that in code.
[http://3.t.imgbox.com/PExOEVdQ.jpg
The mosaic effect works even in the Blueprint editor viewport.](http://i.imgbox.com/PExOEVdQ)
Next, you need to open up your character’s skeletal mesh and add a socket by right-clicking the bone you want to add the socket to and selecting Add Socket. Make sure the socket name matches exactly the value you gave to [FONT=Courier New]CensorBarTargetSocket.You may want to adjust the position of the socket if the bone you selected isn’t exactly lined up with the part of your model you want to obscure. We’ll only use the socket location in code, so there’s no need to bother adjusting the rotation or scale of the socket.
We’re not going to attach our mesh to the socket. We’re just going to use the socket’s location to calculate where to place the bar each frame. We’ll do that by overriding [FONT=Courier New]Tick(float DeltaSeconds):
To calculate the position of the censor bar, we take the socket’s world position and subtract the camera position from that and normalize the result. That will give us a vector pointing from the socket to the camera. Then, we’ll multiply that vector by the value in [FONT=Courier New]CensorBarDistanceFromSocket. Because we normalized the vector, it has a length of 1.0, so multiplying it by that value will give us a location that is that many units away long pointing in the direction of the camera. We then subtract that vector from the socket location to get the censor bar’s location. Inside of your [FONT=Courier New]Tick() function, that would look like this:
if (CensorBar && CensorBar->IsValidLowLevelFast())
{
FVector SocketWorldLocation = GetMesh()->GetSocketLocation(CensorBarTargetSocket);
APlayerController *PlayerController = Cast<APlayerController>(GetController());
if (PlayerController && PlayerController->IsValidLowLevelFast())
{
FVector CameraLocation = PlayerController->PlayerCameraManager->GetCameraLocation();
FVector DeltaVector = (SocketWorldLocation - CameraLocation).GetSafeNormal();
DeltaVector *= CensorBarDistanceFromSocket;
FVector Offset = ActorToWorld().TransformFVector4(CensorBarOffset);
CensorBar->SetWorldLocation((SocketWorldLocation - DeltaVector));
}
}
In Blueprint, it would look something like this (click for full-size):
http://7.t.imgbox.com/cPLME7y9.jpg
Once that logic is in place, you should have a nice mosaic between the camera and whatever naughty bits might be at the socket you created earlier. You could also use a shadeless black material for a more timeless (but more obtrusive) censoring effect.
Now you know how to do it, and knowing is half the battle. You should be able to very easily, for example, turn the innocent endless runner tutorial into a streaking game (not that you’d ever do that, of course):
http://2.t.imgbox.com/xLMw2bYC.jpg
Adding a cheat code to let your players remove the censor bar is left as an exercise for the student. :rolleyes:
I hope this was helpful for someone, and yes, I feel dirty, but that’s okay. I accept myself for who I am.
Also, I have a very funny, but very mildly NSFW video I took while testing this code. It’s the character repeatedly running into a wall and ragdolling. The results are really funny (in a rather sophomoric way). But, the bar did its job throughout! Let me know if I should post the video link.